آموزش زبان C
مقدمه
زبان برنامه نویسی C یکی از قدرتمندترین و پرکاربردترین زبانهای برنامه نویسی است که در زمینههای مختلف نرمافزاری و سختافزاری به کار میرود. در اینجا، به بررسی استفادههای زبان C، ارتباط آن با برنامه نویسی میکروکنترلرها، ساختار اصولی زبان C و دستورات آن میپردازیم.
استفاده های زبان C
زبان C به عنوان یک زبان برنامهنویسی عالی، در زمینههای گوناگون مورد استفاده قرار میگیرد. از جمله استفادههای آن میتوان به توسعه نرمافزارهای سیستمی (مانند سیستمعاملها)، برنامهنویسی سطح بالا، توسعه درایورها، و حتی برنامه نویسی میکروکنترلرها اشاره کرد. زبان برنامه نویسی C به خوبی به دستورالعملهای سختافزاری تبدیل میشوند و سابقه طولانی استفاده در برنامههایی را دارد که قبلا به زبان اسمبلی نوشته شده بودند.
مزیت های زبان C
زبان برنامه نویسی C به دلیل ویژگیهای متعدد و انعطافپذیریاش، یکی از زبانهای محبوب و پرکاربرد در صنعت برنامهنویسی است.
1- کاربرد گسترده: زبان C در مختلف حوزههای برنامه نویسی استفاده میشود از جمله سیستمعاملها، درایورها، برنامههای سختافزاری و به خصوص در برنامه نویسی میکروکنترلرها.
2- سرعت اجرا: زبان C به دلیل نزدیکی به زبان ماشین و کنترل دقیق بر روی سختافزار، اجرای سریع و بهینه را فراهم میکند.
3- انعطافپذیری: برنامه نویسان در زبان C انعطاف زیادی دارند و قادرند کنترل دقیقی بر روی منابع سیستمی خود داشته باشند. و به آنها این امکان را میدهد که به صورت دقیقتر و بهینه تر برنامه نویسی کنند.
4- قابلیت نزدیکی به سختافزار: زبان C به برنامهنویسان این امکان را میدهد تا به طور مستقیم با سختافزار ارتباط برقرار کنند. این ویژگی به ویژه در برنامهنویسی میکروکنترلرها و سیستمهای سختافزاری مفید است.
5- کتابخانههای گسترده: زبان C دارای کتابخانههای بسیار گستردهای است که برنامه نویسان میتوانند از آنها در پروژههای خود استفاده کنند و این امر باعث سهولت در توسعه برنامهها میشود.
6- انتقالپذیری: برنامههای نوشته شده به زبان C معمولاً قابلیت اجرا بر روی سیستمهای مختلف را دارند، بدون نیاز به تغییرات گسترده در کد.
7- آموزش آسان: زبان C دارای نحوه نوشتن ساده و آموزش قابل فهمی است که به افرادی که در حال یادگیری برنامه نویسی هستند کمک زیادی میکند.
8- پشتیبانی گسترده: زبان C از لحاظ ابزارها و محیط های توسعه دارای پشتیبانی گستردهای است که برنامه نویسان میتوانند از آنها برای توسعه و اجرای پروژههای خود استفاده کنند.
این مزایا باعث محبوبیت و استفاده گسترده زبان C در صنعت برنامه نویسی شدهاند.
ارتباط با میکروکنترلرها
زبان C به دلیل ساختار کد بهینه و کنترل دقیق بر روی منابع سختافزاری، به طور ویژه در برنامه نویسی میکروکنترلرها مورد استفاده قرار میگیرد. این زبان معمولاً با استفاده از کامپایلرهای خاصی به زبان ماشین تبدیل شده و بر روی میکروکنترلرها اجرا میشود.
ساختار زبان C
زبان C دارای ساختار ساده و بهینه است که به برنامه نویسان این امکان را میدهد که کنترل دقیقی بر روی منابع سیستمی داشته باشند. ساختار اصولی این زبان شامل انواع داده، کنترل جریان (شرطی و حلقهها)، توابع و آرایههاست.
ساختار کلی برنامههای نوشته شده به زبان C برای میکروکنترلرها به طور کلی شامل موارد زیر است:
اضافه کردن کتابخانه ها به برنامه
تعریف توابع استفاده شده در برنامه
تعریف و مقداردهی اولیه به متغیرها
حلقه اصلی (main loop)
توابع کمکی
مثال:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | افزودن کتابخانه ها // #include <avr/io.h> #include <util/delay.h> // تعریف توابع استفاده شده در برنامه در صورت نیاز void function_1(void); تعریف و مقداردهی اولیه به متغیرها // int variable = 10 تابع اصلی برنامه // int main(void) { // تعریف و مقدار دهی اولیه پین خروجی DDRB |= (1 << DDB5); // حلقه بینهایت while (1) { // تغییر وضعیت پین خروجی PORTB ^= (1 << PORTB5); // تاخیر 1 ثانیه _delay_ms(1000); } // مقدار بازگشتی از تابع return 0; } // تابع استفاده شده در برنامه function_1() { } |
زبان C يك زبان Case Sensitive است و بين حروف كوچك و بزرگ تفاوت قائل مي شود.
متغییرها در زبان C
تعريف متغير يعني انتخاب نام دلخواه براي مكاني از حافظه جهت ذخیره داده
فرم تعريف متغير
نام متغییر نوع متغییر ;
مثال:
1 | int variable; |
انواع متغییرها
زبان برنامهنویسی C انواع مختلفی از متغیرها را پشتیبانی میکند.
1- متغیرهای عدد صحیح (Integer Variables):
متغیرهایی که اعداد صحیح (بدون اعشار) را در خود نگه میدارند.
نمونه:
1 | int num = 10; |
2- متغیرهای اعشاری (Floating-Point Variables):
برای نمایش اعداد با اعشار.
نمونه:
1 2 3 | float pi = 3.14; double pi = 3.14; |
3- متغیرهای حرفی (Character Variables):
برای ذخیره کاراکترها (یک حرف یا یک عدد کوچک).
نمونه:
1 | char value = 127; |
4- متغیرهای لاجیکی (Boolean Variables):
برای نمایش مقادیر منطقی صحیح یا غلط (true یا false).
نمونه:
1 | bool isTrue = true; |
5- متغیرهای مرجع (Reference Variables):
متغیرهایی که به یک مکان حافظه اشاره میکنند. (اشاره گرها)
نمونه:
1 | int *ptr; |
6- متغیرهای ثابت (Constant Variables):
متغیرهایی که مقدار آنها در طول اجرای برنامه تغییر نمیکند.
نمونه:
1 | const int MAX_VALUE = 100; |
7- متغیرهای بیتی (Bitwise Variables):
برای کنترل و مدیریت بیتها در سطح پایین.
نمونه:
1 | unsigned int bitmask = 0b00001111; |
8- متغیرهای رشته (String Variables):
برای ذخیره و کار با رشتهها (ترکیبی از کاراکترها).
نمونه:
1 | char name[] = "John"; |
انواع داده ها
Range | Bits (Size) | Type |
0 , 1 | 1 | bit |
-128 to 127 | 8 | char |
0 to 255 | 8 | Unsigned char |
-128 to 127 | 8 | Signed char |
-32768 to 32767 | 16 | int |
-32768 to 32767 | 16 | Short int |
0 to 65535 | 16 | Unsigned int |
-214783648 to 2147483647 | 32 | Long int |
0 to 4294967295 | 32 | Unsigned long int |
+/- 1.175e-38 to +/- 3.402e38 | 32 | float |
+/- 1.175e-38 to +/- 3.402e38 | 32 | Double |
انواع عملگرها
1- عملگرهای حسابی
نتیجه | مثال | عملکرد | عملگر |
8 | 4 x 2 | ضرب | x |
2 | 4 / 2 | تقسیم | / |
6 | 4 + 2 | جمع | + |
2 | 4 – 2 | تفریق | – |
1 | 10 % 3 | باقی مانده | % |
2- عملگرهای بیتی
نتیجه | مثال | عملکرد | عملگر |
0x00 | 0x05 & 0x00 | AND | & |
0x11 | 0x10 | 0x01 | OR | | |
0x01 | 0x01 ^ 0x00 | XOR | ^ |
0xF0 | 0x0F | مکمل یک | ~ |
0x0F | 0xF0 >> 4 | شیفت به راست | << |
0xF0 | 0x0F << 4 | شیفت به چپ | >> |
3- عملگرهای یکانی
نتیجه | مثال | عملکرد | عملگر |
C = C x -1 | -C | قرینه | – |
C = C + 1 | C++ | افزایش یک واحد به متغییر | ++ |
C = C – 1 | C– | کاهش یک واحد از متغییر | — |
4- عملگرهای مقایسه
نتیجه | مثال | عملکرد | عملگر |
False | 3<2 | بزرگتر | < |
True | 3>2 | کوچکتر | > |
True | 7=<7 | بزرگتر یا مساوی | =< |
True | 8=>4 | کوچکتر یا مساوی | => |
False | 3==2 | مساوی | == |
True | 3!=2 | نامساوی | != |
5- عملگرهای منطقی
عملکرد | عملگر |
AND منطقی | && |
OR منطقی | || |
نقیض | ! |
6- عملگرهای انتسابی
نتیجه | مثال | عملکرد | عملگر |
b => a | a = b | انتساب | = |
a = a * b | a *= b | ضرب – انتساب | *= |
a = a + b | a += b | جمع – انتساب | += |
a = a – b | a -= b | تفریق – انتساب | -= |
a = a / b | a /= b | تقسیم – انتساب | /= |
اگر مقدار val صحیح باشد متغییر a برابر x و در غیر اینصورت برابر y میشود | انتساب شرطی | a = (val)? x : y |
دستورات زبان C
زبان C دارای دستورات متنوعی است که به برنامه نویسان این امکان را میدهد تا عملیات مختلف را انجام دهند. به عنوان مثال، دستورات کنترل شرطی (if، else)، حلقه (for، while)، دستورات ورود و خروج، تعریف و فراخوانی توابع و … از جمله دستورات اصلی زبان C هستند.
لیستی از دستورات زبان C و رجیسترهای میکروکنترلرهای AVR
دستورات پایه:
#include: برای درج کتابخانه ها
#define: برای تعریف ثابت ها
typedef: برای تعریف نوع داده های جدید
volatile: برای تعریف متغیرهایی که توسط وقفه ها تغییر می کنند
main(): نقطه شروع برنامه
متغیرها:
char: برای ذخیره کاراکترها
int: برای ذخیره اعداد صحیح
float: برای ذخیره اعداد اعشاری
struct: برای تعریف ساختارهای داده
عملگرها:
+,-,*,/,: عملگرهای ریاضی
&&,||,!: عملگرهای منطقی
==,!=,<,>,<=,>=: عملگرهای مقایسه
++,–: عملگرهای افزایش و کاهش
دستورات شرطی:
if: برای بررسی یک شرط
else: برای تعیین یک بلوک کد جایگزین
switch: برای انتخاب یک بلوک کد از بین چندین بلوک
حلقه ها:
for: برای تکرار یک بلوک کد برای تعداد مشخصی
while: برای تکرار یک بلوک کد تا زمانی که یک شرط برقرار باشد
do while: برای تکرار یک بلوک کد حداقل یک بار
توابع:
void: برای تعریف توابع بدون مقدار برگشتی
int: برای تعریف توابع با مقدار برگشتی
return: برای برگشت از یک تابع
call: برای فراخوانی یک تابع
دستورات ورودی/خروجی:
printf(): برای چاپ متن در کنسول
scanf(): برای خواندن ورودی از کاربر
DDRx, PORTx: برای تنظیم جهت و مقدار پورت های I/O
PINx: برای خواندن مقدار پین های I/O
وقفه ها:
ISR(vect): برای تعریف یک روال وقفه
sei(): برای فعال کردن وقفه ها
cli(): برای غیرفعال کردن وقفه ها
تایمرها:
TCNTx: برای خواندن مقدار تایمر
OCRnx: برای تنظیم مقدار مقایسه تایمر
TCCRnx: برای تنظیمات تایمر
مبدل آنالوگ به دیجیتال (ADC):
ADMUX: برای تنظیمات ADC
ADCSRA: برای کنترل ADC
ADCL, ADCH: برای خواندن مقدار دیجیتال تبدیل شده
مبدل دیجیتال به آنالوگ (DAC):
DACx: برای تنظیم مقدار خروجی DAC
توضیح برخی دستورات پر کاربرد زبان C
if (condition)
دستور if یکی از دستورات شرطی در زبان برنامهنویسی C است و برای اجرای بخشهایی از برنامه بر اساس یک شرط خاص استفاده میشود. ساختار کلی دستور if به صورت زیر است:
1 2 3 4 5 6 7 | if (condition) { // این بخش اجرا میشود اگر شرط درست باشد // دستورات اجرایی } else { // این بخش اجرا میشود اگر شرط درست نباشد // دستورات اجرایی } |
توضیحات:
Condition: یک عبارت منطقی که مقدار بولین (صحیح یا غلط) دارد. اگر مقدار این عبارت صحیح باشد، بخش دستورات داخل if اجرا میشود. در غیر این صورت، بخش دستورات داخل else (اگر وجود داشته باشد) اجرا میشود.
{}: این بلوکها برای تعیین محدوده دستوراتی که در صورت درست بودن شرط یا در صورت درست نبودن شرط اجرا میشوند، استفاده میشوند. این بلوکها میتوانند شامل یک دستور یا چندین دستور باشند.
مثال:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include <stdio.h> int main() { int number = 10; if (number > 0) { printf("The number is positive.\n"); } else if (number < 0) { printf("The number is negative.\n"); } else { printf("The number is zero.\n"); } return 0; } |
در این مثال، اگر number مثبت باشد، پیام “The number is positive.” چاپ میشود. اگر منفی باشد، پیام “The number is negative.” چاپ میشود. و اگر صفر باشد، پیام “The number is zero.” چاپ میشود.
while(condition)
دستور while
یکی از حلقههای تکرار در زبان برنامهنویسی C است. این حلقه به شما امکان میدهد تا یک بلاک از دستورات را تا زمانی که یک شرط مشخص صحیح باشد، تکرار کنید. ساختار کلی while
به صورت زیر است:
1 2 3 | while (condition) { // دستورات اجرایی } |
توضیحات:
condition: یک عبارت منطقی که مقدار بولین (صحیح یا غلط) دارد. اگر مقدار این عبارت صحیح باشد، بلاک دستورات داخل while
اجرا میشود. در غیر این صورت، حلقه تکرار متوقف میشود و اجرای برنامه به دستور بعد از حلقه ادامه پیدا میکند.
{}: این بلوکها برای تعیین محدوده دستوراتی که در صورت درست بودن شرط اجرا میشوند، استفاده میشوند. این بلوکها میتوانند شامل یک دستور یا چندین دستور باشند.
مثال:
1 2 3 4 5 6 7 8 9 10 11 12 | #include <stdio.h> int main() { int i = 1; while (i <= 5) { printf("Iteration %d\n", i); i++; } return 0; } |
در این مثال، حلقه while
از ۱ تا ۵ اجرا میشود. هر بار که به انتهای حلقه میرسیم (i++
افزایش مییابد)، شرط i <= 5
بررسی میشود. اگر این شرط صحیح باشد، دستورات داخل حلقه اجرا میشوند. این پروسه تا زمانی که شرط صحیح باشد ادامه پیدا میکند و پس از آن اجرای برنامه به دستور بعد از حلقه ادامه مییابد.
switch (expression)
دستور switch
در زبان برنامهنویسی C یک دستور شرطی است که برای اجرای یکی از چندین بلوک کد متناظر با مقدار یک عبارت یا متغیر مورد استفاده قرار میگیرد. ساختار کلی switch
به صورت زیر است:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | switch (expression) { case constant1: // دستورات اجرایی برای constant1 break; case constant2: // دستورات اجرایی برای constant2 break; // موارد دیگر ادامه مییابد default: // دستورات اجرایی برای هیچکدام از موارد بالا } |
توضیحات:
expression: یک عبارت که مقدار آن با یکی از مقادیر constant1
, constant2
, و … مقایسه میشود.
case constant1: بلوک کدی که اگر expression
با constant1
برابر باشد، دستورات داخل این بلوک اجرا میشوند. هر case
باید با یک break
به پایان برسد تا اجرای بلوکهای بعدی جلوگیری شود.
default: بلوک کدی که اگر هیچکدام از case
ها با expression
برابر نشود، دستورات داخل default
اجرا میشوند. default
اختیاری است.
مثال:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #include <stdio.h> int main() { int day = 3; switch (day) { case 1: printf("Monday\n"); break; case 2: printf("Tuesday\n"); break; case 3: printf("Wednesday\n"); break; case 4: printf("Thursday\n"); break; case 5: printf("Friday\n"); break; default: printf("Invalid day\n"); } return 0; } |
در این مثال، اگر day
برابر با 3 باشد، پیام “Wednesday” چاپ میشود. اگر مقدار day
با هیچکدام از case
ها برابر نشود، بلوک دستورات داخل default
اجرا میشود و پیام “Invalid day” چاپ میشود.
do-while
دستور do-while
یکی از حلقههای تکرار در زبان برنامهنویسی C است. این حلقه به شکل زیر تعریف میشود:
1 2 3 | do { // دستورات اجرایی } while (شرط); |
در این حلقه، بلافاصله بعد از do
بلوکی از دستورات اجرایی قرار دارد. این دستورات حتماً یک بار اجرا میشوند حتی اگر شرط درست نباشد. سپس شرط در while
بررسی میشود. اگر شرط درست باشد، حلقه به بلوک do
باز میگردد و دستورات دوباره اجرا میشوند. این فرآیند تا زمانی ادامه پیدا میکند که شرط درست نباشد.
مثال:
1 2 3 4 5 6 7 8 9 10 11 12 | #include <stdio.h> int main() { int i = 1; do { printf("Iteration %d\n", i); i++; } while (i <= 5); return 0; } |
در این مثال، حلقه do-while
از 1 تا 5 اجرا میشود و عبارت “Iteration” به همراه شماره تکرار چاپ میشود. حتی اگر شرط i <= 5
از ابتدا درست نباشد، حلقه یکبار حتماً اجرا میشود.
for (شرایط اولیه; شرط; عملیات پس از هر تکرار)
حلقه for
یکی از حلقههای تکرار در زبان برنامهنویسی C است که برای اجرای تعداد مشخصی از تکرارها با استفاده از یک متغیر کنترلی و یک شرط مشخص میشود. ساختار کلی حلقه for
به صورت زیر است:
1 2 3 | for (شرایط اولیه; شرط; عملیات پس از هر تکرار) { // دستورات اجرایی } |
توضیحات:
شرایط اولیه: عبارتی که در ابتدای حلقه اجرا میشود و معمولاً مقدار اولیه یک متغیر کنترلی را تعیین میکند.
شرط: یک عبارت منطقی که اگر درست باشد، حلقه ادامه پیدا میکند و اگر نادرست باشد، حلقه خاتمه مییابد.
عملیات پس از هر تکرار: عبارتی که بعد از اجرای بلوک دستورات اجرایی در هر تکرار اجرا میشود و معمولاً برای تغییر مقدار متغیر کنترلی استفاده میشود.
{}: بلوکی از دستورات که بر اساس شرایط for
تکرار میشود.
مثال:
1 2 3 4 5 6 7 8 9 | #include <stdio.h> int main() { for (int i = 1; i <= 5; i++) { printf("Iteration %d\n", i); } return 0; } |
در این مثال، حلقه for
از i=1
شروع میشود، تا زمانی که i
کمتر یا مساوی 5 باشد ادامه پیدا میکند، و هر بار با افزایش i
اجرای بلوک دستورات داخل حلقه انجام میشود. عبارت “Iteration” به همراه شماره تکرار چاپ میشود.
نتیجهگیری
زبان برنامه نویسی C به دلیل قدرت، سرعت اجرا، و کنترل دقیق بر روی سختافزار، همچنان یکی از زبانهای محبوب در صنعت برنامه نویسی است. ارتباط این زبان با میکروکنترلرها و ساختار اصولی آن باعث جذب برنامه نویسان در حوزه های مختلف و به ویژه در حوزه الکترونیک و میکروکنترلرها شده است.