امیرحسین حسینعلی پور
امیرحسین حسینعلی پور
خواندن ۱۲ دقیقه·۳ سال پیش

زبان C

با تشکر از استاد عزیزم مهندس یعقوبی تبار ،که در این پروژه بهم اطلاعات مکفی رو دادند

(تغيير مسير از زبان برنامه‌نويسي C)

پرش به: ناوبري, جستجو

زبان برنامه‌نويسي C، زباني همه منظوره، ساخت يافته و روندگرا مي باشد که در سال ۱۹۷۲ توسط دنيس ريچي در آزمايشگاه بل ساخته شد

تاريخچه

براي بررسي تاريخچه زبان C بايد به سال ۱۹۶۷ بازگرديم که مارتين ريچاردززبان BCPL را براي نوشتن نرم افزارهاي سيستم عامل و کامپايلر در دانشگاه کمبريج ابداع کرد. سپس در سال ۱۹۷۰ کن تامپسون زبان B را بر مبناي ويژگي‌هاي زبان BCPLنوشت و از آن براي ايجاد اولين نسخه هاي سيستم عامل يونيکس در آزمايشگاه‌هاي بلاستفاده کرد. زبان C در سال ۱۹۷۲ توسط دنيس ريچي از روي زبان Bو BCPL در آزمايشگاه بل ساخته شد و ويژگي‌هاي جديدي همچون نظارت بر نوع داده ها نيز به آن اضافه شد. ريچي از اين زبان براي ايجاد سيستم عامل يونيکس استفاده کرد اما بعدها اکثر سيستم عاملهاي ديگر نيز با همين زبان نوشته شدند. اين زبان با سرعت بسياري گسترش يافت و چاپ کتاب "The C Programming Language" در سال ۱۹۷۸ توسط کرنيگانو ريچي باعث رشد روزافزون اين زبان در جهان شد.

متاسفانه استفاده گسترده اين زبان در انواع کامپيوترها و سخت افزارهاي مختلف باعث شد که نسخه‌هاي مختلفي از اين زبان بوجود آيد که با يکديگر ناسازگار بودند. در سال ۱۹۸۳ انستيتوي ملي استاندارد آمريکا (ANSI) کميته اي موسوم به X3J11 را را مأمور کرد تا يک تعريف فاقد ابهام و مستقل از ماشين را از اين زبان تدوين نمايد. در سال ۱۹۸۹ اين استاندارد تحت عنوان ANSI Cبه تصويب رسيد و سپس در سال ۱۹۹۰، سازمان استانداردهاي بين المللي (ISO) نيز اين استاندارد را پذيرفت و مستندات مشترک آنها تحت عنوان ANSI/ISO Cمنتشر گرديد.

در سالهاي بعد و با ظهور روشهاي برنامه‌نويسي شئ‌گرا نسخه جديدي از زبان Cبنام C++ توسط بيارنه استراوستروپ در اوايل ۱۹۸۰ در آزمايشگاه بل توسعه يافت. در C++ علاوه بر امکانات جديدي که به زبان C اضافه شده است، خاصيت شئ‌گرايي را نيز به آن اضافه شده‌است.

با گسترش شبکه و اينترنت، نياز به زباني احساس شد که برنامه‌هاي آن بتوانند برروي هر ماشين و هر سيستم عامل دلخواهي اجرا گردد. شرکت سان مايکروسيستمزدر سال ۱۹۹۵ ميلادي زبان جاوا را برمبناي Cو C++ ايجاد کرد که هم اکنون از آن در سطح وسيعي استفاده مي‌شود و برنامه هاي نوشته شده به آن برروي هر کامپيوتري که از چاوا پشتيباني کند (تقريباً تمام سيستم‌هاي شناخته شده) قابل اجرا مي‌باشد. شرکت مايکروسافت در رقابت با شرکت سان، در سال 2002 زبان جديدي بنام C# (سي شارپ) را ارائه داد که رقيبي براي Java بشمار مي‌رود.

برنامه نويسي ساخت يافته

در دهه ۱۹۶۰ ميلادي توسعه نرم‌افزار دچار مشکلات عديده‌اي شد. در آن زمان سبک خاصي براي برنامه نويسي وجود نداشت و برنامه‌ها بدون هيچگونه ساختار خاصي نوشته مي‌شدند. وجود دستور پرش(goto) نيز مشکلات بسياري را براي فهم و درک برنامه توسط افراد ديگر ايجاد مي‌کرد، چرا که جريان اجراي برنامه مرتبا دچار تغيير جهت شده و دنبال کردن آن دشوار مي‌گرديد. لذا نوشتن برنامه ها عملي بسيار زمان بر و پرهزينه شده بود و معمولاً اشکال زدايي، اعمال تغييرات و گسترش برنامه ها بسيار مشکل بود. فعاليتهاي پژوهشي در اين دهه باعث بوجود آمدن سبک جديدي از برنامه نويسي بنام روش ساخت‌يافتهگرديد؛ روش منظمي که باعث ايجاد برنامه‌هايي کاملاً واضح و خوانا گرديد که اشکال‌زدايي و خطايابيآنها نيز بسيار ساده‌تر بود.

اصلي‌ترين نکته در اين روش عدم استفاده از دستور پرش (goto) است. تحقيقات بوهم و ژاکوپينينشان داد که مي‌توان هر برنامه اي را بدون دستور پرش و فقط با استفاده از ۳ ساختار کنترلي ترتيب، انتخابو تکرارنوشت.

ساختار ترتيب، همان اجراي دستورات بصورت متوالي (يکي پس از ديگري) است که کليه زبانهاي برنامه نويسي در حالت عادي بهمان صورت عمل مي‌کنند.

ساختار انتخاببه برنامه‌نويس اجازه مي‌دهد که براساس درستي يا نادرستي يک شرط، تصميم بگيرد کدام مجموعه از دستورات اجرا شود.

ساختار تکرارنيز به برنامه نويسان اجازه مي‌دهد مجموعه خاصي از دستورات را تا زمانيکه شرط خاصي برقرار باشد، تکرار نمايد.

هر برنامه ساخت‌يافته از تعدادي بلوک تشکيل مي‌شود که اين بلوکها به ترتيب اجرا مي‌شوند تا برنامه خاتمه يابد (ساختار ترتيب). هر بلوک مي‌تواند يک دستور ساده مانند خواندن، نوشتن يا تخصيص مقدار به يک متغير باشد و يا اينکه شامل دستوراتي باشد که يکي از ۳ ساختار فوق را پياده سازي کنند. نکته مهم اينجاست که درمورد دستورات داخل هر بلوک نيز همين قوانين برقرار است و اين دستورات مي‌توانند از تعدادي بلوک به شرح فوق ايجاد شوند و تشکيل ساختارهايي مانند حلقه‌هايتودرتو را دهند.

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

از جمله اولين تلاشها در زمينه ساخت زبانهاي برنامه نويسي ساخت‌يافته، زبان پاسکال بود که توسط پروفسور نيکلاس ويرثدر سال ۱۹۷۱ براي آموزش برنامه نويسي ساختيافته در محيطهاي آموزشي ساخته شد و بسرعت در دانشگاهها رواج يافت. اما بدليل نداشتن بسياري از ويژگيهاي مورد نياز مراکز صنعتي و تجاري در بيرون دانشگاهها موفقيتي نيافت.

کمي‌بعد زبان C ارائه گرديد که علاوه بر دارا بودن ويژگيهاي برنامه نويسي ساختيافته بدليل سرعت و کارايي بالا مقبوليتي همه گير يافت و هم اکنون سالهاست که به‌عنوان بزرگ‌ترين زبان برنامه نويسي دنيا شناخته شده است.

مراحل اجراي يک برنامه C

براي اجراي يک برنامه C ابتدا بايد آن را نوشت. براي اينکار مي‌توان از هر ويرايشگر متنيموجود استفاده کرد و سپس فايل حاصل را با پسوند .Cذخيره نمود (فايلهاي C++ با پسوند.CPPذخيره مي‌گردند). به اين فايل، کد مبدأ(source code) گفته مي‌شود. مرحله بعدي تبديل کد مبدا به زبان ماشين است که به آن کد مقصد(object code) گفته مي‌شود. همانطورکه قبلا نيز گفته شد براي اينکار از يک برنامه مترجم بنام کامپايلر استفاده مي‌شود. کامپايلرهاي متعددي براي زبان C توسط شرکتهاي مختلف و براي سيستم عاملهاي مختلف نوشته شده است که مي‌توانيد برحسب نياز از هريک از آنها استفاده نماييد. اما هنوز برنامه براي اجرا آماده نيست. معمولاً برنامه نويسان از در برنامه هاي خود از يک سري از کدهاي از پيش آماده شده براي انجام عمليات متداول (مانند محاسبه جذر و يا سينوس) استفاده مي‌کنند که برنامه آنها قبلا نوشته و ترجمه شده است. اين برنامه ها يا در قالب کتابخانه‌هاي استاندارد توسط شرکتهاي ارائه کننده نرم افزار عرضه شده است و يا توسط ديگر همکاران برنامه نويس اصلي نوشته و در اختيار وي قرار داده شده است. در اين مرحله بايد کد مقصد برنامه اصلي با کدهاي مربوط به اين برنامه هاي کمکي پيوند زده‌شود. براي اينکار نياز به يک پيوند‌زننده(Linker) داريم و نتيجه اين عمل يک فايل قابل اجرا خواهد بود (در سيستم عامل ويندوز اين فايل پسوند .EXEخواهد داشت). مرحله بعدي اجراي برنامه و دادن وروديهاي لازم به آن و اخذ خروجيها مي‌باشد. در شکل زير اين مراحل نشان داده شده اند.

?

يک برنامه ساده با ورودي و خروجي

مسلما طي مراحل بالا براي اجراي هر برنامه زمانبر مي‌باشد، بهمين دليل اکثر توليد کنندگان کامپايلرها، محيطهايي را براي برنامه نويسي ارائه کرده اند که کليه مراحل بالا را بطور اتوماتيک انجام مي‌دهند.

به اين محيطها IDE (Integrated Development Environment) يا محيط مجتمع توسعه نرم‌افزار گفته مي‌شود. اين محيطها داراي يک ويرايشگر متن مي‌باشند که معمولاً داراي خواص جالبي همچون استفاده از رنگهاي مختلف براي نشان دادن اجزاي مختلف برنامه مانند کلمات کليديو قابليت تکميل اتوماتيک قسمت‌هاي مختلف برنامه مي‌باشد. پس از نوشتن برنامه و با انتخاب گزينه اي مانند Run کليه عمليات فوق بطور اتوماتيک انجام شده و برنامه اجرا مي‌گردد. علاوه براين، اين محيطها معمولاً داراي امكانات اشكالزدايي برنامه (Debug) نيز مي باشند كه شامل مواردي همچون اجراي خط به خط برنامه و يا ديدن محتويات متغيرها در زمان اجرا است. چند محيط معروف برنامه نويسي عبارت‌اند از :

  • Borland C++ 3.1 براي محيط DOS
  • Borland C++ از نسخه 4 به بالا براي Windows
  • Microsoft Visual C++ براي محيط Windows
  • Borland C++ Builder براي محيط Windows

خطاهاي برنامه نويسي

بنظر مي‌رسد خطاها جزء جداناپذير برنامه ها هستند. بندرت مي‌توان برنامه اي نوشت که در همان بار اول بدرستي و بدون هيچگونه خطايي اجرا شود. اما خطاها از لحاظ تأثيري که بر اجراي برنامه ها مي‌گذارند، متفاوتند. گروهي ممکن است باعث شوند که از همان ابتدا برنامه اصلاً کامپايل نشود و گروه ديگر ممکن است پس از گذشت مدتها و در اثر دادن يک ورودي خاص به برنامه، باعث يک خروجي نامناسب و يا يک رفتار دور از انتظار (مانند قفل شدنبرنامه) شوند. بطور کلي خطاها به دو دسته تقسيم مي‌شوند:

1. خطاهاي نحوي (خطاهاي زمان کامپايل): اين خطاها در اثر رعايت نکردن قواعد دستورات زبان Cو يا تايپ اشتباه يک دستور بوجود مي‌آيند و در همان ابتدا توسط کامپايلر به برنامه نويس اعلام مي‌گردد. برنامه نويس بايد اين خطا را رفع کرده و سپس برنامه را مجدداً کامپايل نمايد. لذا معمولاً اين قبيل خطاها خطر کمتري را در بردارند.

2. خطاهاي منطقي (خطاهاي زمان اجرا): اين دسته خطاها در اثر اشتباه برنامه نويس در طراحي الگوريتم درست براي برنامه و يا گاهي در اثر درنظر نگرفتن بعضي شرايط خاص در برنامه ايجاد مي‌شوند. متأسفانه اين دسته خطاها در زمان کامپايل اعلام نمي‌شوند و در زمان اجراي برنامه خود را نشان مي‌دهند. بنابراين، اين خود برنامه‌نويس است که پس از نوشتن برنامه بايد آن را تست کرده و خطاهاي منطقي آن را پيدا کرده و رفع نمايد. متاسفانه ممکن است يک برنامه‌نويس خطاي منطقي برنامه خود را تشخيص ندهد و اين خطا پس از مدتها و تحت يک شرايط خاص توسط کاربر برنامه کشف شود. بهمين دليل اين دسته از خطاها خطرناکتر هستند. خود اين خطاها به دو دسته تقسيم مي‌گردند:

1. خطاهاي مهلک: در اين دسته خطاها کامپيوتر بلافاصله اجراي برنامه را متوقف کرده و خطا را به کاربر گزارش مي‌کند. مثال معروف اين خطاها خطاي تقسيم بر صفر مي‌باشد.

2. خطاهاي غيرمهلک: در اين دسته خطا،d. اجراي برنامه ادامه مي‌يابد ولي برنامه نتايج اشتباه توليد مي‌نمايد. به‌عنوان مثال ممکن است دراثر وجود يک خطاي منطقي در يک برنامه حقوق و دستمزد،e. حقوق کارمندان اشتباه محاسبه شود و تا مدتها نيز کسي متوجه اين خطا نشود!

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

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

يك برنامه نمونه

در اين قسمت براي آشنايي اوليه با زبان C يك برنامه نمونه آورده شده است كه بدون هيچ تغييري در محيط BorlandCPPقابل اجرا است.

// This Program Computes the Area of a Circle

#include <stdio.h>

void main(void) {

int radius;

float area;

printf( "please enter radius : " );

scanf( "%d", &radius );

area = 2 * 3.14 * radius;

printf( "Area is %f \n", area );

return();

}

please enter radius : 10

Area is 62.8

درمورد برنامه فوق به نکات زير توجه کنيد:

  • خط اول يک توضيح درمورد برنامه است. در زبان C براي توضيحات يک خطي از علامت // استفاده مي‌گردد. اما چنانچه توضيحات بيش از يک خط بود، آن را با علامت /* شروع کرده و با */ پايان دهيد. کامپايلر از اين توضيحات صرفنظر خواهد کرد. اين توضيحات باعث مي‌شوند که برنامه شما خواناتر شده و ديگران بهتر آن را درک کنند.
  • هر دستوري که با علامت # شروع شود، يک دستور C نيست، بلکه جزو دستورات پيش پردازنده محسوب مي‌گردد. دستورات پيش پردازنده دستوراتي هستند که توسط کامپايلر قبل از شروع به کامپايل انجام مي‌شوند. به‌عنوان مثال دستور #include باعث مي‌شود که تعاريف اوليه مربوط به توابعي (زيربرنامه هايي) که قصد استفاده از آنها را داريم به برنامه اضافه شود. در مثال بالا براي استفاده از توابع printf و scanf که در کتابخانه استاندارد C تعريف شده‌اند، فايل سرآمد stdio.h را که اين توابع در آن تعريف شده‌اند را استفاده کرده‌ايم.
  • هر برنامه C بايد داراي تابعي به نام main باشد که اجراي برنامه از آن شروع مي‌شود و در حقيقت همان برنامه اصلي است. البته مي‌توان هر تعداد ديگري تابع (زيربرنامه) نيز تعريف کرد، اما وجود تابع main الزامي است. دقت کنيد که گرچه اين تابع پارامتر ورودي ندارد، اما از پرانتز باز و بسته تنها استفاده شده است.در اين برنامه چون تابع main داراي ورودي و خروجي نمي باشد قبل از اين تابع و نيز در داخل پرانتز main از کلمه void استفاده مي شود.
  • در زبان C هر بلوک برنامه با علامت { آغاز شده و با } پايان مي‌يابد. اين دو معادل دستورات begin و end در زبانهاي ديگر ازجمله پاسکال مي‌باشند که براي سادگي زبان انتخاب شده اند.
  • دو خط بعدي به تعريف متغيرهاي radius و area مي‌پردازد. در زبان C قبل از استفاده از هر متغيري بايد آن را اعلان نماييد. اعلان متغير شامل نام و نوع متغير است. در مثال فوق، متغير radius از نوع عدد صحيح (integer) و متغير area از نوع عدد اعشاري (float) تعريف شده‌اند.
  • توابع printf و scanf جزو کتابخانه استاندارد C محسوب مي‌گردند و به ترتيب براي چاپ اطلاعات در خروجي استاندارد (نمايشگر) و دريافت اطلاعات از ورودي استاندارد (صفحه کليد) استفاده مي‌شوند. براي چاپ رشته مورد نظر بايد آنها را در داخل علامت " قرار داد.
  • دقت کنيد که در پايان هر دستورالعمل از علامت ; استفاده شده است. در مجموع C يک زبان قالب آزاد است و شما مي‌توانيد دستورات را به هر نحوي که دوست داريد قرار دهيد (مثلاً چند دستور در يک خط از برنامه). تنها چيزي که نشان‌دهنده پايان يک دستور است، علامت ; است (و نه انتهاي خط).
  • از آنجا که C يک زبان قالب آزاد است، مي‌توان با استفاده از مکان نوشتن دستورات شکل بهتري به برنامه داد. به‌عنوان مثال دقت کنيد که پس از شروع تابع main، دستورات حدود ۳ کاراکتر جلوتر نوشته شده‌اند. به اين نحوه نوشتن دستورات، دندانه‌گذاري مي‌گويند. بطور کلي هربار که بلوک جديدي آغاز مي‌شود، بايد آن را کمي‌جلوتر برد. اين مسئله باعث جدا شدن بلوکها از يکديگر و خوانايي بهتر برنامه مي‌شود.
  • در پايان برنامه و در داخل مستطيل خاکستري، يک نمونه از اجراي برنامه که شامل يک ورودي و خروجي نمونه است، آورده شده است.

ب م م (و ک م م) بازگشتي

#include
#include
int m(int,int);
int main()
{
clrscr();
int x,y,z;
cin>>x>>y;
z=m(x,y);
cout<<"BMM: "<<Z<<ENDL<<"KMM: z;

حل 2 معادله 2 مجهول بروش ماتريس معکوس

ابتدا درايه هاي ماتريس اول (ضريب متغيرها) را وارد کنيد سپس اعداد بعد از مساوي
#include
#include
int main(){
clrscr();
int m[2][2];
float m2[2][2];
int r[2];
int i,j,p;
cout<<"enter 4 num ";
for(i=0;i<2;i++)
for(j=0;j<2;j++){
cin>>m[i][j];
m2[i][j]=m[i][j];
}
cout<<"enter 2 num ";
cin>>r[0]>>r[1];
int t;
t= ( m[0][0] * m[1][1] ) - ( m[0][1] * m[1][0] );
p=m2[0][0];m2[0][0]=m2[1][1];m2[1][1]=p;
m2[0][1]*=-1;m2[1][0]*=-1;
for(i=0;i<2;i++)
for(j=0;j<2;j++)
m2[i][j]/=t;
float x,y;
x = ( m2[0][0] * r[0] ) + ( m2[0][1] * r[1] );
y = ( m2[1][0] * r[0] ) + ( m2[1][1] * r[1] );
cout<<"x = "<<X<<" mailto:alireza2habibi@yahoo.com? y="<<Y;
getch();
return 0;
}

حل معادله نيوتن رافسون

#include
#include
#include
void main(void)
{

float h,x1,f,f1,g,a,b,x;
int i,conter;

top: clrscr();
printf(" \n******************************in file**************************");
printf("\ninput [a,b]");
printf("\ninput a=");
scanf("\n%f",&a);
printf("input b=");
scanf("\n%f",&b);
printf("\nbaseh f(x)=> [%f,%f]",a,b);
x=a;
/**************** f(x) ****************/
f=x*pow(2,x)-1;
g=x*x*2;
/*******************************************/
printf("\nf(a)=%f",f);
x=b;
/***************** f(x) ***************/
f1=x*pow(2,x)-1;
/*******************************************/
printf("\nf(b)=%f",f1);
if ((f1*f)<0)
printf("\nIF ONE TRUE");
else
{
printf("\n IF ONE FALSE --F(a)F(B)<0--");
goto top;
}
//****************************************************************
printf("\ninput x1:=");
scanf("%f",&x1);
printf("\nnumber repeter :=");
scanf("%d",&conter);
printf("\n************************out file****************************");

for(i=1;i<=conter;i++)
{
h=x1-(f/g);
printf("\n%f ",h);
x1=h;
}

getch();
}

ان مين اعداد اول

====ان مين عدد اول ====

#include<iostream.h>
#include<conio.h>
void main()
{
int z=1,n,k,p,f,i,s=0,sum=0;
textattr(0x1d);
clrscr();
cout<<"enter a number: ";
cin>>n;
if(n==1){ gotoxy(3,4); cout<<" 1 adad avval nist ! \n" ;}
p=2;
while (z<=n)
{
s-=s;
for(i=1;i<=(p/2);i++)
{
k=p%i;
if(k==0) s++;
}
if(s==1) {
cout<<p<<"\n";
z++;
}
p++;
}
cout<<n<<" min adad avval :"<<p-1;
getch();
}

مهندس یعقوبی تبارحسینعلی پورزبانcدانشگاه صدرا
شاید از این پست‌ها خوشتان بیاید