صفحه اصلی

آرشیو مقاله ها

آرشیو اخبار

همکاری با ما

تماس با ما
 
عنوان خبر
 
  
 
سامانه جمع آوری خودکار تجهیزات IT
افرنگ نیوز مجله زندگی
ماشین ایرانی
elham_fitnees_cool
فروشگاه رایکا
فروشگاه رایکا
هر روز صبح جدیدترین اخبار در افرنگ نیوز کلیک کنید ...
برنامه نويسي به زبان C در سيستم عامل GNU - قسمت اول
تعداد بازدید : 631
 
 مقدمه
1- هدف

به آموزش GNU C خوش آمديد. هدف از نوشتن اين مقاله آموزش نوشتن نرم افزار به کمک زبان برنامه نويسي C به کاربران سيستم‌هاي GNU است. اصولا اين مقاله به عنوان خود آموز براي افراد مبتدي نوشته شده امابراي استفاده به عنوان مرجع توسط کاربران با تجربه نيز قابل استفاده است.
مطالب پايه‌اي در چند فصل اول شرح داده شده اند. کاربران مبتدي بايد به دقت آنها را مطالعه کنند اما افراد با تجربه مي توانند به صورت سطحي از کنار آنها بگذرند.تمام اطلاعات در اينجا وجود دارد و به هيچ گونه اطلاعات قبلي در مورد برنامه نويسي نياز نيست.
فرض بر اين است که خواننده به يک سيستم عامل GNUاي دسترسي دارد. اگر چه هدف اصلي کاربران GNU هستند اما مطالب اين کتاب تا ?? درصد براي کاربران - Open BSD Free BSD يا Net BSD نيز قابل استفاده است. تمام فرمان‌ها در کنار نمونه‌هاي برنامه نويسي ذکر شده اند با اين حال آشنايي مختصر با پوسته (خط فرمان يا ترمينال) مفيد خواهد بود. شما تنها به مهارت در استفاده از يک ويرايشگر متن احتياج داريد. هر ويرايشگري قابل استفاده خواهد بود. GNU Emacs يک نمونه بسيار خوب براي برنامه نويسان است. اين برنامه به مدت بيش از 20 سال است که توسعه مي يابد و داراي صدها خصيصه مفيد مي باشد. GNU Nano يکي ديگر از ويرايشگرهاي متن مفيد و ساده است که شما مي توانيد از آن استفاده کنيد. برخي برنامه نويسان مايل به استفاده از vi هستند. اگر شما از قبل يک ويرايشگر محبوب داريد مي توانيد از آن استفاده کنيد. همچنين ويرايشگر‌هاي گرافيکي نظير Anjuta يا KDevelop براي برنامه نويسان وجود دارند اما اکثر برنامه نويسان ويرايشگر‌هاي محيط‌هاي متني را ترجيح مي دهند. (Anjuta و KDevelope و نيز GNU Emacs بيش از يک ويرايشگر متن هستند و آن‌ها را IDE نيز مي‌نامند که مخفف Integrated Development Environment است. به معني محيط توسعه‌ي مجتمع.)

2- مفاد اين متن

مطالب اين مقاله مي توانند به دو بخش تقسيم شوند : الف. هسته زبان سي و ب. توابع استاندارد ارايه شده براي برنامه نويسان. اين توابع توسط کتابخانه توابع سي يا GNU libc فراهم شده اند که بخشي از هر سيستتم GNU/Linux مي باشد. هيچ کدام از اين دو بخش بدون ديگري استفاده نمي‌شود اما در اين مقاله در شروع تمر کز بر روي هسته زبان C و در بخش‌هاي آخر بحث‌هاي بيشتري در مورد libc خواهد بود. سازماندهي مطالب به گونه‌اي است تا آموزش برنامه نويسي C در يک حالت صعودي انجام شود به گونه‌اي که مطالب هر فصل بر روي فصل قبلي بنا مي شود. برخي جنبه‌هاي هسته زبان براي کاربران با تجربه کاربرد دارند بنابراين در فصل‌هاي پاياني ذکر خواهند شد. زبان C به خودي خود مي تواند ساختار‌هاي تصميم گيري و تکرار دستورات را ايجاد کند و ذخيره سازي داده‌ها و محاسبات رياضي را انجام دهد. با همين اهميت يک روش براي استفاده از توابع خارجي نظير libc را فراهم ميکند. libc توابعي براي کارهاي نظير خواندن و نوشتن فايل‌ها - دسته بندي و جست و جوي داده - دريافت ورودي براي کاربر و نمايش داده براي او - ارتياط از طريق شبکه - ساخت برنامه‌هاي قابل ترجمه و غيره فراهم مي‌کند.

3-چرا زبان برنامه نويسيC براي آموزش؟

زبان برنامه نويسي ‏C استاندارد است. C زبان استاندارد برنامه نويسي سيستم‌هاي بر پايه GNU و BSD است. اغلب اين سيستم عامل‌ها به همراه برنامه‌هاي کاربردي که بر روي آنها اجرا مي شوند به زبان C نوشته شده اند. C بيش از سي سال پيش براي نوشتن سيستم‌هاي عامل و برنامه‌هاي کاربردي شروع به توسعه يافت. C کوچک است. طراحي قابل بسط به آن اين امکان را داد تا به همراه صنعت کامپيوتر توسعه پيدا کند. به دليل قدمت و محبوبيت C زباني داراي پشتيباني بسيار خوب است. ابزارهاي زيادي به وجود آمده اند تا برنامه نويسي C را آسان تر کنند . و اين ابزار‌ها غالبا بسيار کامل و استاندارد هستند. غريب به اتفاق نرم افزارهايي که ما در اين مقاله از آنها استفاده خواهيم کرد با C نوشته شده‌اند.

4- چرا استفاده از سيستم عامل GNU ؟

سيستم عامل GNU/Linux يک سيستم عامل شبه Unix است که بيش از بيست سال پيش شروع به توسعه کرد. شروع توسعه‌ي اين سيستم عامل پرژه‌ي GNU است که ريچارد استالمن آن را براي فراهم آوردن آزادي نرم‌افزارها ايجاد کرد. پس از مدتي با فراهم شدن هسته‌اي به نام Linux از سوي لينوس ترووالدز سيستم عامل GNU/Linux شروع به کار نمود. نرم‌افزارهاي مورد استفاده در سيستم GNU و سيستم عامل GNU/Linux به دليل آزاد بودن (و متعاقبا اوپن سورس بودن) نرم افزار‌هايي با پايداري و قابليت اطمينان و منطبق بر استانداردها هستند. اغلب سيستم‌هاي GNU از Linux به عنوان هسته استفاده مي کنند. اين سيستم‌ها غالبا به عنوان سيستم‌هاي GNU/Linux شناخته مي شوند. (براي دريافت اطلاعات بيشتر مي‌تونيد مقاله‌ي لينوکس چيست را در همين سايت مطالعه کنيد.)

5- چرا نرم افزار آزاد؟

مهم‌ترين مطلب درباره‌ي GNU فراهم آوردن نرم‌افزارهايي آزاد است؛ يک نرم افزار زماني يک نرم افزار آزاد است که چهار شرط را براي کاربران فراهم کند :
?- آزادي براي اجراي برنامه براي هر هدفي و استفاده از آن در هر زمينه‌اي.
?-آزادي درمطالعه درباره‌ي نحوه‌ي کار يک برنامه.(در دسترس بودن سورس کد پيش شرط اين موضوع است)
?-آزادي در توزيع مجدد برنامه و يا کپي آن براي همسايگان.
?-آزادي براي توسعه و بهبود و تغيير برنامه و منتشر کردن دوباره‌ي برنامه. (در دسترس بودن سورس کد پيش شرط اين موضوع است)

نرم افزار‌هايي که آزاد نيستند نرم افزار داراي حق مالکيت (يا انحصاري) ناميده مي شوند، چرا که يک نفر ادعاي مالکيت آنها را مي کند و ديگران را از به اشتراگ گذاري و ايجاد تغيير در آن منع مي نمايد. از ديدگاه اخلاقي نوشتن نرم افزار آزاد راهي اجتماعي تر است. نرم افزار آزاد با اجازه دادن به کاربرانش براي کمک به خود از طريق ايجاد تغييرات دلخواه در نرم افزار (يا استفاده از فردي ديگر براي ايجاد تغييرات ) آنها را قدرتمند مي سازند. آن به افراد اجازه مي دهد تا از طريق به اشتراک گذاردن نرم افزار با همسايگانشان به آنها کمک کنند. نرم افرار انحصاري بر عکس عمل مي کند : آن با گفتن اين نکته به افراد که پاسخ مثبت دادن به تقاضاي کمک مردم جرم است به اشتراک گذاري نرم افزار را غير قانوني مي سازد. در حاليکه نرم افزار آزاد به افراد اجازه مي دهد تا با پخش نسخه‌هاي بهبود يافته نرم افزار به اجتماع خود کمک کنند.
نرم افزار آزاد همچنين بر ضد افراد فقير يا افراد کشور‌هاي در حال توسعه موضع نمي گيرد.با اعطاي تمام آزاديهاي بالا به آنها اجازه مي دهدتا بدون اجبار براي پرداخت مبالغ غير ممکن پول براي حق امتياز نرم افزار از کامپيوتر استفاده کنند. در نهايت برتري‌هاي فني نيز وجود دارد. نرم افزار آزاد فارغ از دسيسه‌هاي بازاريابي است.آن خود را براي مجبور کردن کاربران به خريد قطعه‌هاي اضافي برنامه محدود نمي‌کند. هر قطعه از GNU طوري طراحي شده که تا حد ممکن مفيد باشد. به عنوان يک برنامه نويس شما از همان نرم افزار برنامه نويسي C استفاده مي کنيد که در پروژه‌هاي بزرگ استفاده مي شود.
نر افزار‌هاي انحصاري تنها در يک شکل قابل خواندن براي ماشين توزيع مي شوند. اين يعني کاربر نمي تواند از آنچه درون نرم افزار اتفاق مي افتد اطلاع يابد.در مقابل نرم افزار آزاد بايد به همراه کد منبع خود در يک فرمت قابل خواندن براي انسان منتشر شود. به عنوان يک برنامه نويس شما مي توانيد کدهاي هر قطعه از نرم افزار ازاد را که مايل باشيد مطالعه کنيد. اگر خطايي در برنامه وجود داشته باشد شما مي توانيد خودتان آنرا رفع کنيد.
اين آزادي در رفع خطاها و اضافه ساختن امکانات چيزي است که نرم افزار GNU را عالي مي سازد. همه کدها براي بازبيني در دسترس اند.
نرم افزار آزاد قصد تغيير جهان براي بهتر شدن را دارد.


بخش اول : ديباچه‌اي بر C
1.1 زبان برنامه نويسي چيست؟

يک زبان برنامه نويسي قالبي براي طرح ريزي براي اجراي موارد سفارش داده شده توسط کامپيوتر تعريف مي‌کند. زبان‌هاي برنامه نويسي به سه دسته تقسيم مي شوند. ?.زبان‌هاي ترجمه‌اي ?. زبان‌هاي کامپايل شده و ?.زبان ماشين. از اين ميان تنها زبان ماشين به طور مستقيم توسط کامپيوتر قابل فهم است.
يک زبان ماشين مجموعه‌اي از راهنمايي‌ها(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
‏1.2 زبان 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-main

همان برنامه اين‌بار که اينبار به زبان C نوشته شده است :

#include 
 
int
main()
{
  int wages = 1000;
  int tax_allowance = 400;
  float tax_rate = 0.22;
  int tax_due;
 
  tax_due = (wages - tax_allowance) * tax_rate;
 
  printf("Tax Due: %d euro
"، tax_due);
 
  return 0;
}
 

بدون شناخت از زبان C شما کدام برنامه را براي خواندن آسانتر مي دانيد؟ خروجي هر دو برنامه مشابه است :

 "Tax Due: 131 euro"

کد Assembly نشان داده شده که در مجموعه راهنمايي 80386 نوشته شده در ماشيني که از مجموعه راهنمايي ديگري استفاده مي کند کار نخواهد کرد . اما کد C مي تواند عملا براي هر کامپيوتر با هر معماري پردازشگري کامپايل شود.

1.3 ابزارهاي برنامه نويسي

‏سيستم‌هاي GNU به همراه کامپايلري به نام gcc ارايه مي شود. gcc از ابتدا مخفف GNU C Compiler بود ولي پس از مدتي که قابليت کامپايل زبان‌هاي ديگري غير از C به آن افزوده شد نام آن را GNU Compiler Colection خطاب مي‌کنند. پديد آورنده‌ي اصلي GCC ريچارد استالمن، بناينگذار پروژه GNU است. نخستين نسخه GCC در سال ???? انتشار يافت که يک پيشرفت مهم و اساسي در پيشبرد اهداف GNU Project محسوب مي‌شد زيرا محصول جديد اولين کامپايلر بهينه سازي شده قابل حمل ANSI C به عنوان يک نرم افزار آزاد محسوب مي شد. در سال ???? نسخه 2.0 کامپايلر GCC عرضه شد. نسخه جديد قابليت کامپايل کدهاي ++C را نيز داشت.
در سال ???? يک انشعاب آزمايشي در GCC به نام EGCC به منظور بهينه سازي کامپيايلر و پشتيباني کامل تر از ++C ايجاد شد. در ادامه EGCC به عنوان نسل بعدي کامپايلر GCC پذيرفته شد و تکامل آن باعث انتشار نسخه سوم GCC در سال ???? گرديد. چهارمين نسخه از کامپايلر GCC در سال ???? عرضه شد. براي اطمينان از اينکه gccرا نصب کرده‌ايد يا خير دستورات زير را وارد کنيد :

ciaran@pooh:~/$ gcc --version 4.1.1 $ciaran@pooh:~/

نسخه‌اي از gcc که شما استفاده مي کنيد ممکن است متفاوت باشد. هر چيزي شبيه اين از قبيل 3.4.6 يا 4.1.1 مناسب است. اگر پيغام خطاي " command not found" را دريافت مي کنيد، شما gcc را نصب نکرده‌ايد. اگر لينوکستان را از روي cd نصب کرده‌ايد مي توانيد gcc را در آن پيدا کنيد. اگر شما نمي‌دانيد چگونه بايد gcc را در سيستم خود نصب کنيد مي‌توانيد از طريق انجمن‌هاي مختلف موجود در اينترنت اقدام نماييد. کافيست در اين انجمن‌ها پرسش خود را بپرسيد تا کساني اطلاعاتي در اين زمينه دارند به شما کمک کنند. (براي نمونه مي‌توانيد به انجمن‌هاي سايت گنوايران. ارگ مراجعه کنيد.)

1.4 معرفي کامپايلر gcc

بسيار خوب، مي خواهيم کامپايل کردن يک تکه کوچک کد C را از طريق gcc به شما نشان دهيم. اينجا هدف آموزش نحوه استفاده از gcc است بنابر اين در اين بخش به شرح سازوکار کد C نمي‌پردازيم. در نمونه ?.? کوچکترين قطعه کد C که gcc قادر به کامپايل آن است را مي بينيد. اين کد هيچ کاري انجام نمي دهد.
نمونه 1.3 tiny.c

main()
{
}

اين قطعه کد را در ويرايشگر متن خود تايپ و با نام tiny.c ذخيره کنيد. شما مي توانيد هر نام ديگري را نيز که به پسوند c. ختم مي شود انتخاب کنيد. اين پسوندي است که براي سورس کدهاي نوشته شده با C استفاده مي شود. gcc براي کامپايل يک برنامه صحت اين پسوند را چک مي‌کند. با در اختيار داشتن يک فايل ذخيره شده حالا مي توانيد به وسيله دستور زير آنرا کامپايل کنيد:
کامپايل برنامه

ciaran@pooh:~/$ gcc tiny.c $ciaran@pooh:~/

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

فعال کردن نمايش اخطارها

ciaran@pooh:~/$ 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 ciaran@pooh:~/$

دليل نمايش داده شدن اين پيغام‌ها کامل نبودن برنامه‌ي نوشته شده توسز ماست. براي رهايي از اين پيغام‌ها بايد با افزودن سازوکارهاي جديد برنامه‌اي کامل‌تر ايجاد کنيم. در اينجا با افزودن دو سطر جديد به برنامه، آن را به کوتاهترين برنامه معتبر C تبديل مي‌کنيم:
نمونه 2.3 tiny2.c

int main() { return 0; }

حالا برنامه را با گزينهWall- کامپايل مي کنيم و شاهد اين خواهيد بود که پيام خطايي نمايش داده نمي‌شود. گزينه‌ي مفيد ديگر o filename- است که نام فايل خروجي را ( به جاي a.out) مشخص مي‌کند.

ciaran@pooh:~/$ gcc -Wall -o tiny-program tiny2.c ciaran@pooh:~/$ ls tiny2.c tiny-program ciaran@pooh:~/$ ./tiny-program ciaran@pooh:~/$

1.5 چه کسي c معتبر را تعريف مي کند؟

براي شما به عنوان يک برنامه نويس C معتبر توسط کامپايلر تعريف مي شود. لهجه‌هاي مختلف زيادي از C وجود دارد. (يا بهتر است بگوييم انواع مختلفي از زبان C موجود هستند.) خوشبختانه اغلب اين انواع بسيار به يکديگر شباهت دارند. همچنين زبانهاي ديگري نيز وجود دارند که بر پايه C ساخته شده اند مانند Objective C و ++C. اين زبان‌ها در ظاهر بسيار شبيه C هستند اما کاربردي متمايز دارند. gcc خيلي از لهجه‌هاي زبان C را به خوبي خيلي از زبان‌هاي ديگر از قبيل ++C و Obcetive C مي فهمد. ( انواع C در IBM)

1.5.1 Keringhan و Ritchie

زبان ‏C توسط Dennis Ritchie بين سالهاي ???? تا ???? ابداع شد؛ در سال ???? دنيس ريچي به همراه Brian Kernighan يک کتاب آموزشي بسيار خوب براي C با نام "The C programming language"منتشر کرد. اين کتاب در واقع اولين تعريف رسمي از اين زبان بود و از آنجا که نوع اصلي C محسوب مي شود گاهي اوقات به آن C سنتي مي گويند. متاسفانه‌اين کتاب بسياري از جنبه‌هاي اين زبان را تعريف نشده باقي گذاشت. بنابر اين افرادي که کامپايلر‌ها را مي نوشتند مجبور بودند خود در مورد چگونگي رفتار با اين جنبه‌ها تصميم گيري کنند. نتيجه‌ي ‌اين رفتار وابستگي شديد C و واکنش آن به کدها به نوع کامپايلر مورد استفاده بود. ممکن بود کدي که در يک کامپايلر نتيجه‌اي مطلوب مي‌دهد در کامپايلر ديگري نتايج متفاوتي را در بر داشته باشد. استفاده از اين لهجه مدت زيادي طول نکشيد. gcc تنها براي کامپايل برنامه‌هاي خيلي قديمي از آن پشتيباني مي کند و ما تنها به خاطر مقاصد تاريخي به آن اشاره کرديم.

‏1.5.2نسخه‌ي ISO C

در سال ???? موسسه استاندارد ملي آمريکا (ANSI) کميته‌اي را به منظور تدوين يک استاندارد صحيح و رفع برخي کاستي‌ها ي زبان C تشکيل داد. کار تدوين اين استاندارد در سال ???? به پايان رسيد و مورد پذيرش سازمان بين المللي استاندارد يا (ISO) نيز قرار گرفت. اين لهجه جديد با نام C89 شناخته شد. همچنين از آن به عنوان ISO C و ANSI C نيز ياد مي شود. gcc يکي از سازگارترين کامپايلر‌هاي موجود با اين لهجه است.

1.5.3 C99

کميته ANSI C جلسات بسيار کمي را براي ارتقاي اين زبان تشکيل مي دهد. آخرين استاندارد ارتقا يافته در سال ???? عر ضه شد که با نام C99 شناخته مي شود. تاکنون کامپايلر‌هاي بسيار کمي به طور کامل از C99 پشتيباني مي کنند زيرا ايجاد تغييرات در يکي از مهمترين نرم افزار‌هاي سيستم عامل کار زمان گيري است. تا زمان نگارش اين مقاله پشتيباني gcc از C99 تا حد قابل توجهي کامل شده است اما توسعه دهندگان هنوز مشغول کار بر روي آن هستند.

1.5.4 GNU C

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

1.5.5 انتخاب يک نوع C

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

1.5.6 آينده استانداردها

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

1.6 خاتمه

در اين جا معرفي ما خاتمه مي يابد. با اميد به‌اينکه ديد صحيحي درباره زبان برنامه نويسي C بدست آورده باشيد، دربخش بعدي به نوشتن برنامه‌هاي پايه‌اي تشريح نحوه‌ عمل کرد اين برنامه‌ها خواهيم پرداخت.


بخش دوم : توابع در زبان C
2.1 توابع چه هستند؟

توابع بلوک‌هاي ساختاري برنامه‌هاي C هستند. اکثريت برنامه‌هاي C از بلوک‌هايي از کد که تابع(function) ناميده مي شوند ساخته مي شوند. وقتي يک برنامه را مي نويسيد شما توابع زيادي را براي انجام وظايفي که احتياج داريد ايجاد خواهيد کرد. علاوه بر اين تعداد زيادي از وظايف عمومي از قبيل نمايش يک متن بر روي صفحه نمايش وجود دارند که مورد نياز اکثر برنامه نويسان هستند. به جاي اينکه هر برنامه نويس مجبور باشد در اين زمينه سرمايه گذاري مجددي صورت دهد سيستم‌هاي GNU به همراه کتابخانه(library)‌هايي از توابع پيش ساخته براي انجام بسياري از اين وظايف عرضه مي شوند. در طول سالها هزاران مورد از چنين توابعي بر روي هم جمع شده اند. در غير اين صورت اگر شما قصد نوشتن برنامه‌اي براي بازي BINGO داشتيد مجبور بوديد شخصا توابع مخصوص برنامه را بنويسيد امااکنون در مي يابيد که افراد ديگر توابعي براي توليد اعداد تصادفي – نمايش اعداد بر روي صفحه نمايش – دريافت اعداد ورودي از بازيکن و موارد ديگر نوشته اند.
هر برنامه C ملزم به داشتن تابعي به نام ()main است. اجراي برنامه از اين تابع شروع مي شود. مي توان تمامي کدهاي برنامه را در تابع ()main قرار داد اما روش مرسوم تر تقسيم برنامه به چندين تابع کوچک است. به عنوان اولين قطعه کد مفيد در اين مقاله به يک نمونه کلاسيک نگاه مي اندازيم. سپس از کامپايل و اجرا برنامه يک پيام ساده روي صفحه نمايش شما چاپ مي‌کند. برنامه تابعي به نام ()main را تعريف (define) و تابعي به نام ()printf را فراخواني (call) مي‌کند. ()prinf تابعي است که توسط کتابخانه ابزار ورودي/خروجي استاندارد (Standard Device Input/Output library) فراهم مي شود که‌اين کتابخانه به همراه هر سيستم GNU وجود دارد. متن برنامه کوچک ما به صورت زير است:

نمونه 2.1 hello.c

#include 
 
int
main()
{
  printf("hello، world");
 
  return 0;
}

حالا برنامه را کامپايل و اجرا کنيد. اگر همه چيز درست باشد عبارت “hello، world” بر روي ترمينال شما (ابزار خروجي استاندارد ) نمايش داده خواهد شد. در صورتيکه فرامين مربوط به کامپايل و اجراي برنامه را فراموش کرده‌ايد آنها به صورت زير هستند :
فرامين کامپايل و اجراي برنامه

ciaran@pooh:~/$ gcc -Wall -o hello hello.c ciaran@pooh:~/$ ./hello hello، world ciaran@pooh:~/$

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

2.2 يک تشريح سطر به سطر

حالا به طور سريع کاري را که هر سطر انجام مي دهد تشريح مي کنيم.در صورتيکه برخي از سطر‌ها براي شما مبهم است نگران نباشيد. در آينده نمونه‌هاي بسيار زيادي را انجام خواهيم داد. سطر <include></include>
اين سطر به gcc مي گويد از کتابخانه ابزار ورودي/خروجي استاندارد اطلاعاتي را در مورد چگونگي استفاده از توابع برداشت کند. به طور معمول ابزار ورودي استاندارد صفحه کليد و ابزار خروجي استاندارد صفحه نمايش است. اين کتابخانه به طور گسترده مورد استفاده قرار مي گيرد و ما در اين مقاله با توابع بسيار زيادي از آن سروکار خواهيم داشت.

int main()

اين دو سطر تعريف تابع ()main را آغاز مي کنند. در مورد سطر اول از اين دو سطر بعدا توضيحات بيشتري خواهيم داد.

{
آکولاد باز نشانه شروع يک بلوک کد است. تمام کدهاي بين آکولاد باز و بسته جزيي از تابع ()main هستند.
printf("hello، world ");
اين سطر در واقع يک فراخواني تابع (function call) است. تابع از قبل براي شما تعريف شده است. وقتي شما تابع ()printf را فرا مي خوانيد بايد يک نشانوند(Argument)براي آن ذکر کنيد تا به آن بگوييد چه چيزي را نمايش دهد.
return 0;
دستور return به اجراي تابع ()main خاتمه مي دهد. هيچ دستور ديگري بعد از اين سطر اجرا نخواهد شد. با پايان يافتن تابع ()main برنامه شما خاتمه مي يابد. زماني که يک تابع به پايان مي رسد مي تواند مقداري را به محلي که از آنجا فراخواني شده بازگرداند. اين کار با قراردادن يک مقدار پس از return حاصل مي شود.تابع ()main همواره يک مقدار صحيح (يک عدد مثبت يا منفي بدون اعشار) را باز مي گرداند.ما با مقدم ساختن تعريف ()main با int به کامپايلر مي فهمانيم که منتظر چنين چيزي باشد. قرار بر اين است که درصورت اجراي بدون اشکال تابع ()main مقدار بازگشتي برابر صفر باشد.
{
آکولاد بسته نشانه پايان بلوک کدي است که تابع ()main را مي سازد. دو سطري که بدنه تابع ()main را مي سازند با نام تقرير (statement) شناخته مي شوند. به صورت دقيقتر اين‌ها تقريرات ساده (simple statements) هستند (در مقابل تقريرات مرکب (compound statements) که در بخش چهار به آنها مي رسيم). (لينک به بخش چهار-- يادداشت ?) تقريرات در زبان C به منزله جملات براي زبانهاي گفتاري هستند. در انتهاي هر تقرير ساده يک نقطه-ويرگول (semi-colon) قرار مي گيرد. اضافه نمودن خطوط خالي در برنامه اختياري است.C هيچگونه نيازي به آنها ندارد اما استفاده از آنها باعث خوانايي برنامه مي شود. متذکر شديم که تابع ()main ما مقدار صفر را باز مي گرداند. اغلب توابع مقدار بازگشتي خود را به برنامه بازمي گردانند در حاليکه تابع ()main مقدار بازگشتي خود را که نشانه پايان برنامه است براي پوسته ارسال مي‌کند. مقدار بازگشتي برنامه توسط پوسته ذخيره مي شود. درصورتيکه مايل به مشاهده آن هستيد از دستورات زير استفاده کنيد:

ciaran@pooh:~/$ gcc -Wall -o hello hello.c ciaran@pooh:~/$ ./hello hello، world ciaran@pooh:~/$ echo $? 0 ciaran@pooh:~/$

2.3 توضيحات

توضيحات يا Comment‌ها راهي براي اضافه نمودن متون توضيحي در برنامه هستند. آنها توسط کامپايلر ناديده گرفته مي شوند بنابراين هيچ تاثيري بر روي برنامه شما ندارند. هر چنداين کار حجم برنامه شما را افزايش مي دهد اما شما پي خواهيد برد که استفاده از Comment‌ها وسيله مفيدي است تا به شما يادآوري کند مشغول انجام چه کاري هستيد.در نمونه‌هاي اين کتاب ما Comment‌ها را براي توضيح آنچه در حال انجام است به کار مي بريم.با دو روش ميتوانيد يک Comment را وارد برنامه خود سازيد:عادي ترين روش اينست که در شروع و انتهاي متن توضيحي خود به ترتيب از /* و */ استفاده کنيد. توضيحات در اين روش مي توانند از چندين سطر تشکيل شوند. روش دوم استفاده از // درابتداي سطر است که محتويات بعد از خود تا پايان سطر جاري را به متن توضيحي مبدل مي سازد.
در اين جا برنامه hello، world ما به همراه متون توضيحي آورده شده است:
نمونه 2.2 hello2.c

/* The purpose of this program is to
 * display some text to the screen
 * and then exit.
 */
 
#include 
 
int
main()
{
  /* printf() displays a text string */
  printf("hello، world");
 
  return 0;  //zero indicates there were no errors
}

پس از کامپايل از لحاظ اجرايي اين کدها مشابه کدهاي نمونه قبل هستند. خطوط 2 و 3 توضيحات بالا با يک ستاره آغاز مي شوند . اين کار اگر چه لازم نيست اما اين نکته که توضيحات در چهار سطر ادامه دارد را روشن مي سازد.

2.1 ساختن توابع شخصي

در نمونه قبلي ما تنها بک تابع معرفي کرديم. براي اضافه کردن توابع ديگر به طور کلي شما بايد دو کار انجام دهيد: ابتدا بايد به همان صورت که براي تابع ()main انجام داديم آنها را تعريف کنيم. کار ديگري که بايد انجام دهيم اعلان (declare) توابع است. اعلان يک تابع به منزله‌اين است که به gcc بگوييم تا منتظر آن تابع باشد. ما مجبور به اعلان تابع ()main نيستسم زيرا آن يک تابع مخصوص است و gcc مي داند که بايد منتظر آن باشد. نامي که به تابع مي‌دهيم بايد در هر دو جنبه اعلان و تعريف ظاهر شود.
نام تابع مي تواند از حروف الفبا يعني کاراکترهاي A تا Z و a تا z و نيز ارقام 0 تا 9 و کاراکتر خط زير(underscore) يعني "_" تشکيل شود. اين کاراکتر‌ها به هر ترتيبي مي توانند کنار هم قرار بگيرند اما حرف نخست نام تابع نمي تواند عدد باشد. زبان C حساس به بزرگي و کوچکي متن (case-sensitive) است بنابرين My_Function کاملا با my_function متمايز است. نام هر تابع بايد متمايز بوده و طول آن از يک تا 36 کاراکتر مجاز است. به همراه نام بايد به هرتابع يک نوع و يک بلوک کد اختصاص دهيد. نوع تابع براي کامپايلر مشخص مي سازد که مقدار بازگشتي تابع چگونه است. تابع مي تواند بدون مقدار بازگشتي باشد. مقدار بازگشتي تابع ()printf يک عدد صحيح و برابر تعداد کاراکترهاي است که بر روي ترمينال نمايش داده است. اين اطلاعات براي ما مهم نيستند بنابرين آنها را در برنامه خود ناديده مي گيريم. در بخش بعدي در مورد جزييات انواع داده‌اي صحبت خواهيم کرد و سپس به تفصيل مقادير بازگشتي توابع خواهيم پرداخت.
در اينجا برنامه‌اي را داريم که ? تابع را تعريف مي کند:
نمونه 2.3 three_functions.c

#include 
/* function declarations */
int first_function(void);
int goodbye(void);
int
main()            // function definition
{
  printf("the program begins... ");
  first_function();
  goodbye();
 
  return 0;
}
int
first_function()  // function definition
{
  /* this function does nothing */
  return 0;
}
int
goodbye()         // function definition
{
  printf("...and the program ends. ");
  return 0;
}    

در نمونه بالا ما تابع ()first_function را نوشتيم که هيچ کاري انجام نمي دهد و نيز تابع ()goodbye که يک پيغام را در صفحه نمايش چاپ مي‌کند. اعلان توابع بايد قبل ار فراخواني آنها صورت بگيرد يعني در نمونه ما بايد توابع قبل از تابع ()main اعلان مي شدند. به طور کلي مرسوم است که اعلان توابع بعد از سطر‌هاي شامل عبارت include# و قبل ار آغاز تعريف توابع صورت مي گيرد.

2.5 فايل‌هاي چندگانه

اجباري براي اينکه برنامه‌ها تنها در يک فايل معين نوشته شوند وجود ندارد. کدهاي شما ميتوانند در هر تعداد فايل که بخواهيد پخش شوند. به عنوان نمونه اگر برنامه‌اي از ?? تابع تشکيل شده باشد شما مي توانيد هر تابع را در يک فايل جداگانه قرار دهيد؛ اگر چه اين کار يک افراط در تکه تکه کردن برنامه است. غالبا توابع بر حسب موضوع در گروه‌هايي دسته بندي شده و در فايل‌هاي جداگانه قرار مي گيرند. براي نمونه در صورتيکه وظيفه يک برنامه محاسبه قيمت يک پيتزا و نمايش نتيجه است شما مي توانيد توابع مربوط به محاسبه قيمت را در يک فايل و توابع نمايش نتايج را در فايل ديگري قرار داده و از فايل سوم براي نگهداري تابع ()main استفاده کنيد. حال مي توانيد از فرمان زير براي کامپايل برنامه استفاده کنيد:
کامپايل برنامه تشکيل شده از سه فايل

ciaran@pooh:~/$ gcc -o pizza_program main.c prices.c display.c

ياد آوري مي کنيم در صورتيکه تابعي را در prices.c تعريف و قصد فراخواني آن را در main.c داريد بايد آنرا در main.c اعلان کنيد.

2.6 فايل‌هاي سرآيند

ادامه پيگيري اعلان توابع مي تواند موجب شلوغ کاري شود. به همين دليل فايل‌هاي سرآيند براي جا دادن کدهاي C که شما قصد به کارگيري آنها در فايل‌هاي چندگانه را داريد استفاده مي شوند. قبل از اين شما به طور عملي از يک فايل سرآيند به نام stdio.h استفاده کرديد، اين فايل سرآيند شامل اعلان توابع بسيار زيادي است. از جمله شامل تابع ()printf و نيز اعلان آن است. شما نيز مي توانيد يک فايل سرآيند شامل اعلان توابعي که قصد به اشتراک گذاري آنها را داريد ايجاد کنيد و سپس با استفاده از include# آن را در اختيار هر فايل C که به اطلاعات آن احتياج دارد قرار دهيد. تنها تفاوت موجود در اين است که شما بايد به جاي علائم < و > نام فايل خود را بين دو "،" يا کوتيشن مارک قرار دهيد. يعني از "my_header.h" به جاي استفاده کنيد. براي توضيح اين نکته برنامه پيتزا که قبلا به آن اشاره کرديم را خواهيم نوشت.

2.7 يک (غير) برنامه بزرگتر

نکات کوچک برنامه نويسي که تا کنون بررسي کرديم براي نوشتن يک برنامه آراسته و تاثير گذار کافي نيستند. براي حفظ سادگي برنامه ما تنها يک اسکلت کلي از برنامه را مي نويسيم تا بدينوسيله ساختار و روش استفاده از فايل‌هاي سرآيند را تشريح کنيم بدون اينکه شما در باتلاق مفاهيم جديد فرو رويد. در بخش سوم مقاله يک نسخه کامل از اين برنامه را خواهيم نوشت. کدهاي زير مي توانند کامپايل و اجرا شود اما عملياتي براي محاسبه قيمت و يا سوال از کاربر براي وارد کردن اطلاعات انجام نخواهد داد.
نخست با فايل main.c سرو کار داريم که تنها شامل تابع ()main مي شود.()main برخي از توابعي که در فايل‌هاي ديگر تعريف شده اند را فراخواني خواهد نمود. متذکر مي شويم که فايل main.c فاقد سطر #include مي باشد زيرا از هيچ يک از توابع عضو کتابخانه ابزار ورودي/خروجي استاندارد استفاده نمي‌کند.
نمونه 2.4 main.c

#include "display.h"
#include "prices.h"
 
int
main()
{
  display_options();
  calculate_price();
  display_price();
 
  return 0;
}

در مرحله بعد به بررسي display.c مي‌پردازيم. اين فايل شامل دو تابع است که هر دو از طريق تابع ()main فراخواني مي شوند و ما اعلان آنها را در يک فايل سرآيند با نام display.h قرار داده‌ايم. نمونه 2.5 display.c

#include 
 
int
display_options()
{
  printf("Welcome to the pizza parlor
");
  printf("What size pizza would you like? (in inches)");
 
  return 0;
}
 
int
display_price()
{
  printf("Your pizza will cost 0.00
");
 
  return 0;
}
نمونه 2.6 display.h
/* header file just contains function declarations، an file that wants
 * to use either of these functions just has to #include this file */
int display_options(void);
int display_price(void);

و در نهايت prices.c را داريم که شامل توابعي براي دريافت داده از کاربر و محاسبه قيمت مجموع هزينه‌هاي پيتزا است. تنها يکي از اين توابع از طريق ()main فراخواني مي شود بنابر اين اعلان دو تابع ديگر در بالاي همين فايل صورت مي گيرد. کدهاي کامل اين توابع را در فصل سوم خواهيم نوشت.
نمونه 2.7 prices.c

int get_size(void);
int get_toppings(void);
 
int
calculate_price()
{
  /* insert code here.  Will call get_size() and get_toppings(). */
  return 0;
}
 
int
get_size()
{
  /* insert code here */
  return 0;
}
 
int get_toppings()
{
  /* insert code here */
  return 0;
}
نمونه 2.8 prices.h
int calculate_price(void);

حالا مي توانيد gcc را با دستور زير براي کامپايل فايل‌هاي بالا به کار گيريد:

gcc -Wall -o pizza_program main.c prices.c display.c

اين برنامه در زمان اجرا پس از نمايش يک پيغام خوش آمدگويي اعلام مي کند که قيمت پيتزاي شما برابر £0.00 است.

2.8 يک تابع جديد ديگر

قبل از ادامه بياييد نگاهي به يکي ديگر از توابع عضو کتابخانه ابزارهاي ورودي/خروجي استاندارد بياندازيم: ()printf. دستور چاپ قالبدار يکي از شکل‌هاي پيشرفته تابع ()printf است. رشته‌اي که براي ()prinf ارسال مي شود مي تواند شامل کاراکترهاي کنترلي که داراي معاني مخصوصي هستند باشد. رفتن به سطر جديد به طور خودکار توسط ()printf صورت نمي گيرد و براي اينکار بايد کاراکترهاي را اضافه نماييد.

2.9 خلاصه اصول اوليه

مطالبي را که تا کنون از آنها عبور کرديم نبايد چندان سخت باشند. اگر قصد کسب تجربه را داريد برنامه‌هايي مشابه که داراي چندين سطر خروجي هستند ايجاد کنيد. برنامه خود را به دو تابع تقسيم کرده و آنها را در دو فايل مجزا قرار دهيد. همواره در هنگام کامپايل اخطارهاي gcc را فعال کنيد. اخطارها خبر از مبهم بودن و يا ناکامل بودن کدهاي شما مي دهند.در اين حالت gcc معناي صحيح آنها را حدس مي زند و اغلب اين کار را به درستي انجام مي دهد اما شما نبايد به آنها اعتماد کنيد. جست و جو براي تصحيح پيغام‌هاي خطا به مهارت شما در استفاده از زبان کمک ميکند. اغلب پيغام‌هاي خطا به همراه شماره سطري که مشکل در آن وجود دارد مي آيند. اگر شما در آن سطر هيچگونه خطايي مشاهده نمي کنيد سطر فوقاني آنرا چک کنيد. در صورتيکه يک دستورالعمل ناکامل باشد gcc تا زماني که به ابتداي دستورالعمل بعدي نرسيده متوجه وجود خطا نخواهد شد.نقطه ويرگول‌هاي خود را فراموش نکنيد.

 
نویسنده: مَهدي رسولي
مترجم :
منبع :
تاریخ :
مطالب مرتبط
 
 A.A.C/ پنگوئني كه از گرمسير آمد - Ubuntu، لينوكسي براي همه‌
 A.A.C/ لينوكس 64 بيتي‌
 A.A.C/ نگاهي به نسخه جديد لينوكس ردهت RHEL4
 A.A.C/ تنظيمات TCP/ IP در لينوكس‌
 A.A.C/ لينوكس سحرآميز ، Mandrake Linux 10.1
 
نظرات
 
نام : شهر :
   
 
 
کلیه حقوق این وب سایت متعلق به شرکت فرا ارتباط می باشد