فصل اول آموزش gnu c

ویکی‎کتاب، کتابخانهٔ آزاد
پرش به ناوبری پرش به جستجو

فصل اول: دیباچه‌ای بر C[ویرایش]

ltr article

زبان برنامه نویسی چیست؟[ویرایش]

یک زبان برنامه نویسی قالبی است که از طریق آن می‌توانیم خواسته‌های خود را برای رایانه مطرح کنیم تا رایانه آنها را اجرا کند. زبان‌های برنامه نویسی به سه دسته تقسیم می‌شوند.

  • زبان‌های ترجمه‌ای
  • زبان‌های کامپایل شده
  • و زبان ماشین.

از این میان تنها زبان ماشین به طور مستقیم توسط کامپیوتر قابل فهم است. یک زبان ماشین مجموعه‌ای از راهنماییها(instructions) ست که CPU کامپیوتر (واحد پردازشگر مرکزی) آن‌ها را درک می‌کند. تمام راهنمایی‌ها و اطلاعات توسط اعداد نمایش داده می‌شوند. در حالیکه درک و اجرای زبان ماشین برای کامپیوتر بسار سریع و آسان صورت می‌گیرد، خواندن و نوشتن این کدها برای انسان بسیار دشوار است. برای آسان تر ساختن وظیفه برنامه نویسی کامپیوتر مردم زبان آسانتری را ساختند که Assembly نامیده می‌شد. یک زبان Assembly نامهای متنی برای دستورات در دسترس زبان ماشین فراهم می‌کند. این مطلب در کنار این واقعیت که زبان اسمبلی به برنامه نویسان اجازه اضافه کرن فاصله‌ها و تب‌ها را در کدها می‌دهد زبان Assembly را برای برنامه نویسی بسیار راحت می‌سازد. برنامه‌های Assembly می‌توانند برای ترجمه به زبان ماشین به منظور فهم CPU به یک Assembler سپرده شوند.

استفاده از زبان‌های Assembly خیلی سریع گسترش یافت. آنها به عنوان زبانهای نسل دوم شناخته می‌شدند. اما هنوز هم دو مشکل وجود داشت. اولا هر دستور Assembly تنها یک وظیفه خیلی ابتدایی نظیر جمع دو عدد و یا بارگذاری یک مقدار از حافظه را انجام می‌داد. استفاده از این دستورات کوچک واقعا ملالت آور بود. مشکل دوم خیلی بزرگتر بود. هر کدام از برنامه‌های نوشته شده به Assembly به نوع خاصی از CPUوابسته بود. هر نوع از CPU زبان ماشین مخصوص به خودو بنابر این زبان Assembly مخصوص به خود را داشت. کار مهم بعدی طراحی زبانی بود که به زبان ماشین انواع گوناگون CPU ها قابل ترجمه باشد.

این زبانهای جدید وابسته به ماشین زبانهای نسل سوم یا زبانهای سطح بالا نامیده می‌شوند. این زبانها که برای آسان خوانده شدن طراحی شده بودند از کلمات انگلیسی - سمبل‌های پایه‌ای ریاضی و علایم نقطه گذاری تشکیل می‌شدند. این زبانها به عبارات ساده اجازه می‌دهند تا به طور مختصر بیان شوند به عنوان مثال جمع دو عدد و ذخیره‌سازی حاصل در حافظه می‌تواند به صورت زیر بیان شود:

data = 10 + 200 ;

که بر عبارت زیر ارجحیت دارد:

Load R1, 10

Load R2, 200

Addi R1, R2

Store R2, L1

پس از نوشتن کدها ابزاری که کامپایلر نامیده می‌شود برای تبدیل کدهای سطح بالا به زبان ماشین استفاده می‌شود.

C چیست ؟[ویرایش]

C یک زبان سطح بالاست. یک برنامه می تواند به زبان C نوشته شده و سپس برای هر کامپیوتری کامپایل شود. درگیری با جزییات سخت‌افزاری بر عهده کامپایلر است. برای مقایسه برتری زبان C بر Assembly به یک برنامه کوچک که در هر دو زبان نوشته شده نگاه کنید:

مثال 1.1 C در مقایسه با Assembly:

 .section  .rodata

.LC0:

         .string   "Tax Due: %d "
         .text
         .align 2

.globl main

         .type     main,@function

main:

         pushl     %ebp
         movl      %esp, %ebp
         subl      $24, %esp
         andl      $-16, %esp
         movl      $0, %eax
         subl      %eax, %esp
         movl      $1000, %eax
         movl      $400, %edx
         movl      $0x3e6147ae, -12(%ebp)
         subl      %edx, %eax
         pushl     %eax
         fildl     (%esp)
         leal      4(%esp), %esp
         fmuls     -12(%ebp)
         fnstcw    -18(%ebp)
         movw      -18(%ebp), %ax
         movb      $12, %ah
         movw      %ax, -20(%ebp)
         fldcw     -20(%ebp)
         fistpl    -16(%ebp)
         fldcw     -18(%ebp)
         subl      $8, %esp
         pushl     -16(%ebp)
         pushl     $.LC0
         call      printf
         addl      $16, %esp
         movl      $1, %eax
         leave
         ret

.Lfe1:

         .size     main,.Lfe1-mainn

بدون شناخت از C شما کدام برنامه را برای خواندن آسانتر می‌دانید؟ خروجی هر دو برنامه مشابه است: "Tax Due: 131 euro" کد Assembly نشان داده شده که در مجموعه راهنمایی 80386 نوشته شده در ماشینی که از مجموعه راهنمایی دیگری استفاده می‌کند کار نخواهد کرد. اما کد C می‌تواند عملا برای هر کامپیوتری کامپایل شود.

ابزارهای برنامه نویسی[ویرایش]

Gnu به همراه کامپایلری به نام gcc ارایه می‌شود. gcc از ابتدا مخفف Gnu C Compiler بود ولی از زمانی که توانست زبانهای دیگری غیر از C از قبیل C++,Ada,Java,Objective C و Fortran را کامپایل کند بهGnu Compiler Colection تغییر نام داد. پدید آورنده اصلی GCC ریچارد استالمن است کسی که بنیانگذار پروژه Gnu محسوب می‌شود. نخستین نسخه GCC در سال 1987 انتشار یافت که یک پیشرفت مهم محسوب می‌شد زیرا محصول جدید اولین کامپایلر بهینه‌سازی شده قابل حمل ANSI C به عنوان یک نرم‌افزار آزاد محسوب می‌شد.

در سال 1992 نسخه 2.0 کامپایلر GCC عرضه شد. نسخه جدید قابلیت کامپایل کدهای ++C را نیز داشت. در سال 1997 یک انشعاب آزمایشی در GCC به نام EGCC به منظور بهینه‌سازی کامپیایلر و پشتیبانی کامل تر از ++C ایجاد شد. در ادامه EGCC به عنوان نسل بعدی کامپایلر GCC پذیرفته شد و تکامل آن باعث انتشار نسخه سوم GCC در سال 2004 گردید.

چهارمین نسخه از کامپایلر GCC در سال 2005 عرضه شد.

برای اطمینان از اینکه gccرا نصب کرده‌اید یا خیر دستورات زیر را وارد کنید: مشاهده نسخه gcc Mahdix@domain:~/book$ gcc --version 4.1.1 Mahdix@domain:~/book$

نسخه‌ای از gcc که شما استفاده می‌کنید ممکن است متفاوت باشد. هر چیزی شبیه این از قبیل 3.4.6 یا 4.1.1 خوب است. در صودتی که یک پیام خطا به صورت: command not found دریافت می‌کنید شما gcc را نصب نکرده‌اید. اگر Gnu را از روی cd نصب کرده‌اید می‌توانید gcc را در آن پیدا کنید. اگر شما نمی‌دانید چگونه یک برنامه را از روی cd نصب کنید آنگاه از یک دوست یا فردی کهGnu را بر روی سیستم شما نصب کرده بخواهید این کار را برای شما انجام دهد.

معرفی gcc[ویرایش]

حالا ما می‌خواهیم یک تکه کوچک کد c و طرز کامپایل آنرا به شما نشان بدهیم. دراینجاهدف آموزش نحوه استفاده از gcc است بنابر این هنوز به تشریح کد c نمی‌پردازیم. در زیر کوچکترین قطعه کد c که gcc قادر به کامپایل آن است را می‌بینید. این کد هیچ کاری انجام نمی‌دهد. مثال 1.3 tiny.c main() { } این قطعه کد را در ویرایشگر متن خود تایپ و با نامtiny.c ذخیره کنید. شما می‌توانید هر نام دیگری را نیز که به پسوند c. ختم می‌شود انتخاب کنید. این پسوندی است که توسط برنامه‌های c استفاده می‌شود. gcc برای کامپایل یک برنامه صحت این پسوند را چک می‌کند. با در اختیار داشتن یک فایل ذخیره شده حالا می‌توانید به وسیله دستور زیر آنرا کامپایل کنید:

کامپایل برنامه Mahdix@domain:~/book$ gcc tiny.c Mahdix@domain:~/book$

در صورتیکه که این فرمان با موفقیت انجام شود بدون پیغام خروجی خواهد بود. در صورتیکه هر گونه پیغام خطایی را دریافت کردید باید صحت برنامه خود را چک کنید. در صورتیکه فرض کنیم شما این برنامه ۸ کاراکتری را درست نوشته باشید باید فایلی به نامa.outدر دایرکتوری شما ایجاد شود. این برنامه زبان ماشینی است که از کدهای بالا ساخته شده است. در صورتیکه آنرا اجرا کنید خواهید دید که در واقع هیچ کار خاصی را انجام نمی‌دهد. نامگذاریa.out دلایل تاریخی دارد. آن مخفف output Assembler می‌باشد. اگر چه gcc این کدها را کامپایل کرد اما این کدها کامل نیستند اگر شما اخطارهای جی سی سی را فعال کنید به شما گفته خواهد شد چه کمبودهایی وجود دارد. با اضافه کردن سوئیچ Wall- به فرمان کامپایل اخطارهای gcc را فعال می‌کنیم:

فعال کردن نمایش اخطارها Mahdix@domain:~/book$ gcc -Wall tiny.c tiny.c:2: warning: return-type defaults to `int' tiny.c: In function `main': tiny.c:3: warning: control reaches end of non-void function Mahdix@domain:~/book$

دلیل ظهور این پیغام‌ها اینست که برنامه ما به طور دقیق کامل نیست. برای رهایی از این پیغام‌ها باید دو سطر جدید به برنامه خود اضافه کنیم. بنابر این کوتاهترین برنامه معتبر C به صورت زیر است: مثال 2.3 tiny2.c int main() {

 return 0;

} حالا برنامه را با گزینه Wall – کامپایل می‌کنیم ولی هیچ پیام خطایی دریافت نمی‌کنیم. گزینه دیگر o filename - است که نام فایل خروجی را (به جای a.out) مشخص می‌کند. کامپایل برنامه در حال فعال بودن اخطارها Mahdix@domain:~/book$ gcc -Wall -o tiny-program tiny2.c Mahdix@domain:~/book$ ls tiny2.c tiny-program Mahdix@domain:~/book$. /tiny-program Mahdix@domain:~/book$

نام فایل ها[ویرایش]

Gcc به صورت قرار دادی از نام و پسوندهای زیر برای فایل‌ها استفاده می‌کند:

نوع فایل نام و پسوند Source code program_name.c Object file program_name.o Executable file program_name (بدون پسوند) Header file name.h Library file libname.a یا

libname.so

خطاهای برنامه[ویرایش]

خطا یا Er ror اشتباهی است که برنامه نویس در خلال نوشتن کدهای برنامه مرتکب آنها می‌شود. این اشتباهات بر دو نوع اند: ۱) خطاهای زمان کامپایل: این خطاها توسط کامپایلر کشف می‌شوند و شامل خطاهای نحوی از قبیل اشتباه در تایپ کلمات و نیز اشکالات ساختاری برنامه مانند انتساب یک مقدار اعشاری به یک متغییر از نوع صحیح می‌باشد. فرض کنید در هشتمین سطر از فایلی به نام eg.c دستور Y = Sin (x); را اشتباها به صورت زیر تایپ کرده‌ایم: Y = Sin (x]; در صورتیکه قصد کامپایل کردن فایل eg.c را داشته باشیم با صدور پیام خطای زیر از طرف gcc روبرو خواهیم شد:

گزارش خطای زمان کامپایل توسط gcc error--> eg.c: In function `main': eg.c:8: parse error before `]'

۲) خطاهای زمان اجرا: خطاهایی که بعد از کامپایل برنامه و در زمان اجرای آن رخ می‌دهد. برخی خطاهای زمان اجرا مواردی را شامل می‌شود که برنامه کاری غیر از خواسته شما را انجام می‌دهد. در فصل هشتم کتاب تحت عنوان «جنبه‌های احتیاطی در مورد آرایه‌ها» به یکی از این نوع خطاها پرداخته‌ایم. نوع دیگر خطاهای زمان اجرا خطاهایی هستند که منجر به بسته شدن و خروج ناگهانی برنامه (crash) می‌شوند. تصور کنید برنامه‌ای نوشته‌اید که دو عدد را از کاربر دریافت و آن‌ها را برهم تقسیم می‌کند. اگر در زمان اجرای برنامه کاربر عدد دوم را صفر وارد کند به دلیل نامفهوم بودن تقسیم بر صفر برنامه با خطای زمان اجرا روبرو و بسته خواهد شد.

خوشبختانه در محیط Gnu در اکثر مواردیکه یک برنامه با چنین اشکالاتی مواجه و مجبور به بسته شده می‌شود یک پیغام خطا کاربر را از علت مطلع می‌گرداند.

چه کسی c معتبر را تعریف می‌کند؟[ویرایش]

برای شما به عنوان یک برنامه نویس C معتبر توسط کامپایلر تعریف می‌شود. لهجه‌های مختلف زیادی از C وجود دارد. خوشبختانه آنها خیلی به هم شبیه هستند. همچنین زبانهای دیگری نیز وجود دارند که بر پایه C ساخته شده‌اند مثل Objective C و++ C. این زبانها در ظاهر بسیار شبیه C هستند اما کاربردی متمایز دارند. gcc علاوه بر اینکه از زبان‌های گوناگون پشتیبانی می‌کند از لهجه‌های گوناگون زبان C نیز پشتیبانی می‌نماید.

سی کرنیگان و ریچی[ویرایش]

C توسط Dennis Ritchie بین سالهای ۱۹۶۹ تا ۱۹۷۳ ساخته شد. در سال ۱۹۷۸دنیس ریچی به همراه Brian Kernighan یک کتاب آموزشی بسیار خوب برای C با نام "The C programming language"منتشر کرد. این کتاب در واقع اولین تعریف رسمی از این زبان بود و از آنجا که لهجه اصلی C محسوب می‌شود گاهی اوقات به آن C سنتی می‌گویند. متاسفانه این کتاب بسیاری از جنبه‌های این زبان را تعریف نشده باقی گذاشت. بنابر این افرادی که کامپایلرها را می‌نوشتند مجبور بودند خود در مورد چگونگی رفتار با این جنبه‌ها تصمیم گیری کنند. نتیجه این شد که اجرای یک قطعه کد بسته به نوع کامپایلر مورد استفاده نتایج متفاوتی را در برداشت. استفاده از این لهجه مدت زیادی به طول نینجامید. gcc تنها برای کامپایل برنامه‌های خیلی قدیمی از آن پشتیبانی می کندو ما تنها به خاطر مقاصد تاریخی به آن اشاره کردیم.

ISO C[ویرایش]

در سال ۱۹۸۳ موسسه استاندارد ملی آمریکا “ANSI” کمیته‌ای را به منظور تدوین یک استاندارد صحیح و رفع برخی کاستی‌ها ی زبان C تشکیل داد. کار تدوین این استاندارد در سال ۱۹۸۹ به پایان رسید و مورد پذیرش سازمان بین‌المللی استاندارد نیز قرار گرفت. این لهجه جدید با نام C89 شناخته شد. همچنین از آن به عنوان ISO C و ANSI C نیز یاد می‌شود. gcc یکی از سازگارترین کامپایلرهای موجود با این لهجه است.

C99[ویرایش]

کمیته ANSI C جلسات بسیار کمی را برای ارتقای این زبان تشکیل می‌دهد. آخرین استاندارد ارتقا یافته در سال ۱۹۹۹ عرضه شد که با نام سی ۹۹ شناخته می‌شود. تاکنون کامپایلرهای بسیار کمی به طور کامل از سی ۹۹ پشتیبانی می‌کنند زیرا ایجاد تغییرات در یکی از مهمترین نرم‌افزارهای سیستم عامل کار زمان گیری است. تا زمان نگارش این کتاب پشتیبانی GCC از سی ۹۹ تا حد زیادی کامل شده است اما توسعه دهندگان هنوز مشغول کار بر روی آن هستند.

گنو سی[ویرایش]

Gnu C بسیار شبیه C89 است اما دارای برخی خصیصه‌های جدیدتر از C99 و برخی امکانات فرعی اضافه(extension) دیگر است. امکانات فرعی به صورت محتاطانه برای رفع برخی اشکالاتی که C99 راه حل مناسبی برای آنها ارایه نکرده توسط توسعه دهندگان ارایه شده‌اند.Gnu C لهجه پیش فرض gcc و نیز لهجه ایست که ما در این کتاب به کار خواهیم برد. ما نهایت تلاش خود را خواهیم کرد تا در مواقعی که از امکانات فرعی Gnu C استفاده می‌کنیم آنها را مشخص کنیم هر چند به طور کلی استفاده کامل از Gnu C بهتر است زیرا استفاده از ISO C باعث محدود شدن برنامه‌های شما به استفاده از جنبه‌های مشترک می گرددو کابرد آنها را محدود به موارد معینی می‌سازد.

انتخاب یک لهجه[ویرایش]

در صورتیکه می‌خواهید لهجه‌ای غیر از لهجه پیش فرض انتخاب کنید می‌توانید با سوییچ = std - انتخاب خود را مشخص کنید. به دنبال این سوییچ می‌توانید یکی از گزینه‌های c89، c99، gnu89 و gnu99 را وارد کنید. gnu89 در حال حاضر گزینه پیش فرض است تا زمانی که پشتیبانی از c99 تکمیل شود. در آن صورت gnu99 گزینه پیش فرض خواهد شد. در هر صورت تغییرات چندان قابل توجه نخواهد بود.

آینده استانداردها[ویرایش]

امکانات فرعی اضافه از قبیل آنهایی که توسط gcc اضافه می‌شوند منابع الهام اصلی ISO برای استانداردهای جدید C هستند. زمانی که گروه ANSI C مشاهده می‌کنند تعداد زیادی از کامپایلرها یکی از امکانات فرعی اضافه را به کار می‌گیرند آنها لزوم وجود آن امکان را بررسی می‌نمایند و در صورتیکه آنرا مفید تشخیص دهند یک را استاندارد برای به کار گیری آن ارایه می‌دهند. برخی از امکانات فرعی اضافه شده توسط gcc ممکن است در آینده به صورت استاندارد در آیند و برخی دیگر ممکن است اینگونه نباشند.

خاتمه[ویرایش]

در این جا معرفی ما خاتمه می‌یابد. با امید به اینکه دید صحیحی در باره برنامه نویسی بدست آورده‌اید در فصل بعدی به نوشتن برنامه‌های پایه‌ای که عملا کارهایی را انجام می‌دهند و تشریح اینکه چگونه این کارها را انجام می‌دهند خواهیم پرداخت.