این ضمیمه به معرفی اجمالی دستورات ANSI C اختصاص دارد.
هدف از ارائه این ضمیمه، دو مسأله می باشد.
نخست آنکه کمکی هر چند کوچک به یادگیری دستورات ANSI C برای کسانی که آشنایی مختصری با این دستورات دارند باشد.
دوم آنکه خلاصه ای از این دستورات در کنار کامپایلر Coodevison AVR موجود باشد تا خواننده بتواند در مواقع ضروری به جای استفاده از کُتب مرجع، از همین کتاب برای رفع مشکلات خود در زمینه دستورات ANSI C سود بَرد.
عملگرها
در این بخش به بررسی مختصر تمامی عملگرهای موجود در زبان C می پردازیم.
چنانچه دو عملگر با هم بکار روند، ابتدا آنکه تقدّم بالاتری دارد انجام می شود و سپس عملگر بعدی اجرا می شود مگر آنکه این دو توسط پرانتز از یکدیگر جدا شده باشند.
در زیر انواع عملگرها برحسب اولویّت بیان می شوند:
عملگر شرطی ?
:
از این عملگر معمولاً برای نسبت دهی شرطی بکار می رود.
بعنوان مثال عبارت زیر باعث می شود که اگر حاصل (a>b) درست باشد، مقدار max برابر a و در غیر اینصورت برابر b باشد:
max = (a>b) ?
a:b
عملگر کاما ً , ً
در ادامه با توضیح دستورات C با موارد کاربرد این عملگر آشنا خواهید شد.
متغیرها
تعریف متغیرها
برای معرفی یک متغیر، از قالب بندی زیر استفاده می شود:
data – type verialbe_list;
«مثال»
char a,b;
- data – type : مشخص کننده نوع داده می باشد که می تواند یکی از انواع char ، int ، float short in ، long int و double باشد که در زیر به توضیح مختصر هر یک از انواع آنها می پردازیم:
- char : نشان دهنده آن است که متغیر از نوع کاراکتر و در محدوده اعداد 128- تا 127+ می باشد.
- in و short int : هر دو نوع داده، نشان دهنده آن هستند که متغیر از نوع عدد صحیح و در محدوده اعداد 32768- تا 32767+ می باشند.
- long int : نشان دهنده آن است که متغیر از نوع عدد صحیح بلند و در محدوده اعداد 2147483648- تا 2147483647+ می باشد.
- float و double : هر دو نوع داده، نشان دهنده آن هستند که متغیر از نوع عدد اعشاری و مقدار تقریبی قدر مطلق آن در محدوده اعداد (37-10 × 43/8 تا 1038 × 37/3) می باشند.
با قرار دادن کلمه کلیدی unsigned قبل از هر یک از انواع داده فوق، نوع داده بدون علامت می شود و محدوده عدد مثبت آن تا دو برابر بعلاوه یک، افزایش می یابد.
در زمان تعریف یک متغیر می توان آنرا مقداردهی اولیه نیز نمود.
مثال زیر نمونه ای از این مطلب را نشان می دهد:
char a=2 , b=3;
کلمات کلیدی const و volatile
می توان بهنگام تعریف یک متغیر، پیش از نوع داده data-type از کلمات کلیدی const و volatilc استفاده کرد، که توضیح آن ها در زیر آورده شده است:
const : این کلمه کلیدی باعث می شود تا تغییر محتوای متغیری که به این شکل تعریف شده است، در برنامه غیرممکن باشد.
Volatile: این کلمه کلیدی برای متغیرهایی که امکان تغییر آنها بدون اطلاع برنامه وجود دارد، بکار می رود.
کلاس ذخیره سازی متغیرها
در تعریف یک متغیر، می توان کلاس ذخیره سازی آنرا قبل از data-type معین کرد.
بدین ترتیب شکل کلی تعریف متغیر بصورت زیر می باشد:
variable_list;
«مثال»
static int a,b,c;
می تواند یکی از انواع extern, static, auto و register باشد که توضیح هر یک از آنها بصورت زیر می باشد:
auto : نشان دهنده آنست که متغیر از نوع خودکار می باشد.
این نوع متغیر فقط در داخل تابع شناخته شده است و با برگشت از تابع مقدار آن از بین می رود.
معمولاً این کلمه کلیدی در اعلان متغیر ذکر نمی شود زیرا چنانچه متغیری در داخل تابع بدون ذکر کلاس ذخیره سازی اعلان شود، کامپایلر آن را از نوع خودکار فرض خواهد کرد.
static : نشان دهنده آنست که متغیر از نوع ایستا می باشد.
چنانچه این اعلان در داخل تابع انجام شود، تابع دوباره فراخوانده شود، متغیر مقدار قبلی را داراست و چنانچه این اعلان در خارج از تابع انجام شود، متغیر فقط در کامپایل جاری شناخته شده است و از این متغیر نمی توان در فایل های دیگر (در برنامه های چند فایلی) استفاده کرد.
extern : نشان دهنده آنست که تعریف اصلی (اختصاص حافظه) و مقدار اولیه متغیر، در فایل دیگری انجام شده است و در فایل جاری، می توان از آن متغیر استفاده کرد.
register : نشان دهنده آنست که مکان متغیر در یکی از رجیسترهای میکروکنترلر می باشد.
آرایه ها و رشته ها یک آرایه مجموعه ای از متغیرهای بهم مرتبط است که بوسیله یک نام مشترک، مورد رجوع قرار می گیرند.
آرایه ها می توانند از یک تا چندین بُعد را دارا باشند.
نحوه تعریف یک آرایه یک بُعدی بصورت زیر می باشد: data – type var_name [size]; «مثال» char A[20]; در این تعریف data-type نوع داده، var_name نام آرایه مورد نظر و size تعداد عناصر این آرایه می باشد.
برای دسترسی به عنصر یک آرایه از شماره آن عنصر به عنوان زیرنویس آن آرایه استفاده می شود.
زیرنویس یک آرایه با صفر شروع می شود.
بطور نمونه در مثال فوق آرایه A دارای عناصر A[0] تا A[19] می باشد.
علاوه بر آرایه یک بُعدی می توان آرایه هایی با دو یا چند بُعد ساخت.
نحوه تعریف یک آرایه چند بُعدی بصورت زیر می باشد: data – type var_name [size_1] [size_2] … [size_N]; «مثال» char A[20] [10] ; از متداول ترین کاربرد آرایه های یک بُعدی، تعریف رشته ها می باشد.
یک رشته در حقیقت آرایه ای از کاراکترها می باشد که به یک کاراکتر تهی (NULL) ختم می شود، کاراکتر تهی نشان دهنده پایان رشته می باشد.
بعنوان مثال آرایه زیر می تواند رشته ای با طول حداکثر 10 کاراکتر را در خود نگه دارد که عضو یازدهم آرایه، کاراکتر تهی می باشد: char name [11] ; مقداردهی اولیه آرایه ها: همانند دیگر متغیرها، آرایه ها را نیز می توان در هنگام تعریف مقداردهی اولیه نمود و برای این منظور از قالب بندی زیر استفاده می شود.
data – type array_name={value_list}; «مثال» int A [5]={1, 4, 7, 3, 9}; cahr b [3] [3]={‘a’ , ‘m’ , ‘n’ , ‘o’ , ‘p’ , ‘q’ , ‘r’ , ‘s’ , ‘t’}; در این قالب بندی value_list فهرستی از مقادیری است که به وسیله کاما از هم جدا می شوند.
در چنین فهرستی، اولین مقدار ثابت در اولین مکان آراینه قرار می گیرد و دومین مقدار ثابت در دومین مکان آرایه و … برای مقداردهی اولیه آرایه های رشته ای، می توان از روش های ساده تری مطابق آنچه در زیر آورده شده است، استفاده کرد: char name [ ] = "TEXT"; اشاره گرها (Pointers) اشاره گر، متغیری است که آدرس حافظه یک شیء را در خود نگاه می دارد.
مثلاً اگر متغیری با نام a حاوی آدرس متغیر دیگری با نام b باشد، در اینصورت گفته می شود که a به b اشاره می کند.
شکل کلی تعریف یک متغیر اشاره گر بصورت زیر می باشد: data – type *var_name; «مثال» int *p; در این تعریف data – type نوع داده ای است که اشاره گر به آن اشاره می کند.
دو نوع عملگر که مخصوص کار با اشاره گرها می باشند، عبارتند از عملگر آدرس "&" و عملگر محتوای آدرس " * ".
مثال زیر نمونه ای از کاربرد این عملگرها را نشان می دهد: main ( ) { int *a, b, c; b = 100 ; a = &b; c = *a } در این مثال a حاوی آدرس b خواهد بود، یعنی اگر b در خانه 2000H حافظه باشد، مقدار a برابر 2000H خواهد بود.
از طرفی c برابر محتوای آدرس ذکر شده در a یعنی محتوای آدرس 2000H می باشد.
لذا مقدار c برابر همان مقدار b یا 100 خواهد بود.
اشاره گرهای void : از void برای تعریف اشاره گرهای خالی استفاده می شود.
یک اشاره گر خالی به هر نوع شیئی می تواند اشاره گر باشد.
از محاسن این اشاره گر آنست که می توان هر نوع اشاره گری را (حتی اگر با هم ناسازگار باشند) به آن نسبت داد.
مثال زیر نمونه ای از این مطلب را نشان می دهد: int *p; void *v; v = p; در مثال فوق اگر اشاره گر v نوع دیگری غیر از int و void می بود، کامپایلر تولید خطا می کرد.
اشاره گر NULL : یک اشاره گر NULL دارای مقدار تهی (یعنی صفر) می باشد و فرض بر آنست که این اشاره گر به هیچ چیزی اشاره نمی کند.
برای ساخت یک اشاره گر تهی، باید به آن، مقدار صفر را نسبت داد.
ماکروی NULL در stdlib.h به این منظور تعبیه شده است.
این ماکرو معادل ((void*)0) می باشد.
مثال زیر نمونه ای از این نسبت دهی را نشان می دهد: int *ptr = NULL; از اشاره گرها می توان برای ارسال داده ها به توابع و برگرداندن آنها از توابع نیز استفاده کرد.
این روش معمولاً برای ارسال بلوکی از داده ها (مانند آرایه ها و ساختارها) به تابع و یا برگرداندن آنها از تابع بکار می رود.
دستورات کنترلی دستور if – else : شکل کلّی استفاده از دستور if – else بصورت زیر می باشد: if (expression) statement1 else statement2 «مثال» if (num abs_num=-num; else abs_num=num; در قالب بندی فوق، چنانچه مقدار برگشتی expression درست باشد (یعنی 1 منطقی)، statement1 اجرا می شود و در غیر اینصورت (مقدار برگشتی، 0 منطقی باشد)، statement2 اجرا می شود.
حلقه while : شکل کلی ایجاد یک حلقه while بصورت زیر می باشد: while (expression) statement «مثال» while (i>0) { i--; A[i]=i; } در قالب بندی فوق، حلقه while تا زمانی که expression درست باشد، به تکرار statement می پردازد.
تذکّر: مقدار عبارت expression در ابتدای حلقه امتحان می شود و اگر در همان ابتدا نادرست باشد، این حلقه حتی برای یکبار هم اجرا نخواهد شد.
حلقه do-while : شکل کلی ایجاد یک حلقه do-while بصورت زیر می باشد: do statement while (expression) «مثال» do { i--; A [i] = i ; } while (i>0) این حلقه، دستور یا دستورات داخل خود را تا زمانیکه expression درست باشد (مقدار برگشتی آن مخالف صفر باشد) تکرار می کند.
وقتی این عبارت نادرست شود، این حلقه متوقف می شود.
این حلقه حداقل یکبار دستورهای داخلی خود را اجرا می کند، زیرا عبارت کنترل کننده حلقه در پایان حلقه آزمایش می شود.
حلقه for : شکل کلی ایجاد یک حلقه for بصورت زیر می باشد: for (exp 1; exp2 ; exp3) statement for (i = 0; i A [i] = i; B [i] = 2*i ; } در یک حلقه for عبارت exp1 فقط برای یکبار و در ابتدای حلقه اجرا می شود.
این عبارت معمولاً حاوی مقداردهی اولیه متغیرهای حلقه می باشد.
پس از آن exp2 امتحان می شود، اگر عبارت exp2 درست باشد (مقدار برگشتی آن مخالف صفر باشد) تکرار حلقه با اجرای دستورات موجود در بخش statement ادامه می یابد و در غیر اینصورت از حلقه خارج می شود.
پس از هر بار تکرار حلقه، عبارت exp3 محاسبه می شود، این عبارت معمولاً وظیفه افزایش یا کاهش شمارنده حلقه را بر عهده دارد.
دستور goto : شکل کلی ایجاد یک دستور goto بصورت زیر می باشد: goto identifier; «مثال» loop: … goto loop; از این دستور برای انتقال بدون شرط کنترل به یک برچسب محلی که توسط شناسه مشخص شده، استفاده می شود.
دستور break : این دستور برای خارج شدن بدون شرط از حلقه، مورد استفاده قرار می گیرد.
هرگاه برنامه به دستور break برسد از حلقه خارج شده و ادامه برنامه از اولین دستور بعد از حلقه دنبال می شود.
دستور continue: این دستور باعث می شود که با صرف نظر کردن از دستورات باقیمانده حلقه، دور بعدی حلقه انجام شود.
بطور نمونه در مثال زیر دستور i++ هیچگاه انجام نمی شود و در نتیجه این حلقه هیچگاه پایان نمی یابد.
«مثال» i = 0 ; while (i continue; i++; } دستور switch : شکل کلی ایجاد یک دستور switch بصورت زیر می باشد: switch (expression) { case constant1: statement sequence break; case constant2 : statement sequence break; … default: atatement sequence } این دستور برای انتخاب یکی از چند گزینه ممکن در اجرای برنامه بکار می رود.
نحوه کار آن به این صورت است که مقدار عبارت expression متوالیاً با فهرستی از ثابتهای صحیح یا کاراکتری مقایسه می شود.
زمانیکه مورد انطباقی یافت شود، دستور یا دستورهای مربوط به آن انطباق اجرا می شود و اگر هیچ انطباقی یافت نشد، دستورات مربوط به قسمت default اجرا می شود.
بکار بردن default دلخواه می باشد و اگر این قسمت استفاده نشود، در اینصورت با یافت نشدن مورد انطباق هیچ کاری صورت نمی گیرد.
از طرفی اگر دستور break حذف شود، آنگاه برنامه پس از اجرای مورد انطباق، بقیه انتخاب ها را بهمراه default اجرا کرده تا به انتهای دستور switch برسد مگر آنکه سر راه اجرای خود به یک دستور break دیگر برسد که در اینصورت دستور از مکان break قطع شده و ادامه کار از دستور بعد از switch دنبال می شود.
«مثال» switch (p) { case '1' : i = 10 ; break; case '2' : i = 20 ; break; default : i = 30 ; } توابع توابع، ارکان اصلی یک برنامه C را تشکیل می دهند.
در حقیقت یک برنامه C عبارت از چندین تابع C می باشد.
هنگامی که یک برنامه شروع می گردد، اولین تابعی که اجرا می شود تابع main() می باشد، بدین ترتیب هر برنامه باید دارای یک تابع main() باشد.
یک تابع، زیرروالی است که شامل یک یا چند دستور C بوده و عمل بخصوصی را انجام می دهد.
شکل کلی تعریف یک تابع بصورت زیر می باشد: return – type function_name (parameter list) { /* body of the function */ } «مثال» char max (char a, char b) { if (a else return a; } در قالب بندی فوق return-type نوع داده برگشتی تابع می باشد که بطور پیش فرض int است.
این مقدار می تواند یکی از انواع داده های ذکر شده در بخش متغیرها باشد.
چنانچه تابعی مقدار برگشتی نداشته باشد، نوع برگشتی آن باید void تعریف شود.
برای برگرداندن مقدار در داخل بدنه تابع، از دستور return استفاده می شود.
این دستور باعث قرار دادن مقدار برگشتی در مکان مخصوص و خارج شدن از تابع می شود.
اگر نوع داده برگشتی void باشد، دیگر احتیاج به دستور return نبوده و با پایان یافتن بدنه تابع، برنامه از تابع خارج می شود.
Parameter list آرگومان های تابع می باشند که هر یک بصورت data-type parameter_name تعریف شده و با عملگر ً , ً از هم جدا می شوند.
از آرگومان ها برای ارسال مقدار به تابع استفاده می شود.
اگر یک تابع فاقد آرگومان باشد، parameter list از تعریف تابع حذف می شود ولی پرانتزها باقی می مانند، مانند عبارت func_name ().
فراخوانی یک تابع بصورت function_name(parameter name) می باشد.
بعنوان مثال می توان در متن برنامه از جمله number=max(i,2) استفاده کرد.
در اینصورت a مقداری برابر i و b برابر 2 می شود و طبق تعریف تابع max ، مقدار بزرگتر به متغیر number نسبت داده می شود.
در ابتدای بدنه تابع، می توان به تعریف متغیرهای مورد نیاز تابع پرداخت.
این نوع متغیرها را اصطلاحاً محلی (local) می گویند.
میدان دید یک متغیر محلی فقط داخل تابع می باشد، به این معنی که با خارج شدن از تابع این متغیرها ناشناخته می باشند.
برای آنکه یک متغیر همگانی (global) باشد، باید آنرا در خارج از بدنه تابع تعریف کرد.
یک تابع قبل از آنکه برای نخستین بار مورد استفاده قرار گیرد، باید معرفی شود.
برای معرفی یک تابع از پیش الگوی تابع (function prototype) استفاده می شود.
شکل زیر قالب بندی کلی یک پیش الگوی تابع را نشان می دهد.
در این قالب بندی ذکر parameter name ضروری نیست.
Storage-class return-type function_name ( Type parameter_name1, … , type parameter_nameN) ; «مثال» char max (char a, char b) ; extern char max (char, char) ; توابع در زبان C به دو صورت می باشند.
یکی توابعی که توسط کاربر تعریف می شوند مانند تابع main() و دیگر توابعی که توسط کامپایلر فراهم شده اند، به این توابع، توابع کتابخانه ای گویند.
همانطوریکه پیشتر گفته شد، برای استفاده از هر تابع، ابتدا باید توسط پیش الگوی تابع آنرا اعلان کنیم، لذا توابع کتابخانه ای نیز از این قاعده مستثنی نیستند.
اعلان توابع کتابخانه ای در فایل های سرآمد می باشند و برای استفاده از توابع کتابخانه ای باید فایل سرآمد مربوط به آنرا قبلاً در ابتدای برنامه قرار داد.
برای انجام این امر، باید از رهنمود پیش پردازنده "include" استفاده کرد.
مثالی از نحوه استفاده فایل سرآمد در زیر بیان شده است: # include main( ) { int a = 2,b; b=abs (a); } ساختارها، یونیونها و شمارش ها علاوه بر انواع داده های درون ساخته C ، می توان انواع داده های مخصوص بخود را نیز ساخت.
اینکار با استفاده از ساختارها، یونیونها و شمارش ها قابل انجام می باشد.
ساختارها قالب بندی یک ساختار بصورت زیر می باشد: struct type_name { type member1; type member2; … type memberN; } varible_list; «مثال» struct data { int month; int day; int year; } birthday; کلمه کلیدی struct به کامپایلر تفهیم می کند که یک نوع داده ساختاری در حال تعریف شدن می باشد.
در این قالب بندی هر type بیانگر یک نوع داده مجاز C می باشد.
type_name ، نام نوع داده ای است که توسط ساختار تعریف می شود و variable_list ، متغیرهایی می باشند که از نوع ساختار تعریف می شوند.
چنانچه از این نوع ساختار، دیگر استفاده نمی شود، می توان type_name را از تعریف آن حذف کرد.
همچنین می توان با حذف variable_list ، تعریف متغیرهای ساختار را به بعد موکول کرد.
اگر نوع داده ساختاری قبلاً تعریف شده باشد، می توان به شکل زیر متغیرهایی را از آن نوع، معرفی نمود.
Struct type_name variable_list; دسترسی به اعضای ساختار: برای دسترسی به اعضای یک ساختار، می توان از عملگر ً .
ً استفاده کرد.
مثال زیر نمونه ای از این دسترسی را نشان می دهد: birthday.
Month = 10; اگر اشاره گری به یک ساختار تعریف شده باشد، می توان از عملگر "->" برای دسترسی به اعضای آن ساختار استفاده کرد.
مثال زیر این نحوه دسترسی را نشان می دهد: struct date *ptr ; ptr-> day = 21 ; میدان های بیتی: میدان بیتی عضوی از یک ساختار است که از یک یا چند بیت تشکیل می گردد.
با استفاده از میدان های بیتی می توان به کمک یک نام، به یک یا چند بیت موجود در داخل یک بایت یا یک کلمه دسترسی پیدا کرد.
برای تعریف یک میدان بیتی از شکل کلی زیر استفاده می شود: type name:size در این قالب بندی، type می تواند از نوع int, unsigned char, char و unsigned باشد.
size نشان دهنده تعداد بیتهای میدان تعریف شده می باشد.
این روش در تعریف متغیرها، باعث استفاده بهینه از فضای حافظه می شود و در مقابل، کُدهای تولید شده برای دسترسی به متغیر بیشتر می شود.
«مثال» struct bits { char a:4 ; char b:3 ; char c:5 ; } یونیونها یونیون، یک نوع داده جمعی دیگر است که از یک مکان حافظه که بین دو یا چند متغیر به اشتراک گذاشته شده باشد تشکیل می گردد.
تعریف یک یونیون درست مانند تعریف ساختارها می باشد.
با این تفاوت که بجای کلمه کلیدی struct از کلمه کلیدی union استفاده می شود.
مثال زیر نمونه ای از تعریف یک یونیون را نشان می دهد: union u_type { char a[3] ; int b; char c; } sample; نحوه دسترسی به اعضای یونیون ها مانند دسترسی به ساختارها می باشد.
تذکر: میزان فضای اشغال شده برای متغیر یونیونی sample فقط 3 بایت می باشد.
در حالیکه اگر بجای یونیون از ساختار استفاده می شد، این فضا 6 بایت می بود.
علت این امر آنست که در ساختار برای هر عضو مکانی از حافظه در نظر گرفته می شود، ولی در یونیون ها برای همه اعضا، از یک مکان مشترک استفاده می شود و تعداد بایتهایی که بزرگترین عضو اشغال می کند تعیین کننده میزان فضای حافظه می باشند.
شمارش ها یک شمارش، مجتمعی از لیست ثابتهای صحیح دارای اسم می باشد.
شمارش ها معمولاً برای با معنی تر کردن برنامه بکار می روند، و گرنه استفاده از آنها ضرورتی ندارد.
قالب بندی یک شمارش بصورت زیر می باشد: enum type_name {enumaration_list} variable_list; «مثال» enum colors {red, yellow, green} foreground, backqround; در این تعریف، enum کلمه کلیدی تعریف یک شمارش می باشد و type-name نام نوع داده ای است که این شمارش آن را می سازد و cnumaration_list فهرست نامهایی است که هر کدام بیانگر یک مقدار مجاز می باشند.
دسترسی به شمارش: عبارت زیر نحوه دسترسی به یک عضو شمارش مثال فوق را نشان می دهد.
Foreground = green; همچنین پس از تعریف یک شمارش می توان بصورت زیر نیز به تعریف متغیرهایی از آن نوع مبادرت ورزید: enum colors shirt, hat; دستور Typedef با استفاده از دستور typedef می توان برای یک نوع داده موجود، نام تازه ای را ایجاد کرد.
شکل کلی کاربرد این دستور بصورت زیر می باشد: typedef old_name new_name; «مثال» typedef char BYTE; در صورت استفاده از مثال فوق، می توان به اینصورت در داخل برنامه، یک متغیر کاراکتری را اعلان کرد.
BYTE C; رهنمودهای پیش پردازنده C پیش پردازنده C بخشی از کامپایلر است که قبل از تبدیل برنامه مرجع به کُد object ، عملیات متنی گوناگونی روی برنامه انجام می دهد.
به پیش پردازنده می توان فرمان های متنوعی داد که به این فرمان ها، رهنمودهای پیش پردازنده می گویند.
پیش پردازنده C شامل رهنمودهای زیر می باشد: #if #ifdef #ifndef #else #elif #endif #include #define #undef #line #error #pragma در اینجا به توضیح برخی از این رهنمودها می پردازیم: #include : این رهنمود به کامپایلر دستور می دهد تا فایل مرجع دیگری را در محل رهنمود #include بگنجاند.
اسم فایل مورد نظر باید بین یک جفت گیومه ( " " ) یا ، قرار داده شود: «مثال» #include #include "stdlib.h" #define : از این رهنمود جهت تعریف یک شناسه معادل با یک دنباله کاراکتری استفاده می شود، بطوریکه در مرجع برنامه هر جا با آن شناسه برخورد شود، دنباله کاراکتری مفروض جانشین شناسه می شود (اصطلاحاً به آن شناسه ماکرو گفته می شود).
شکل کلی استفاده از این رهنمود بصورت زیر است: #define macro_name character_sequence «مثال» #define TRUE 1 #define NAME "ALI" از ویژگیهای دیگر رهنمود #define آنست که نام ماکرو می تواند شامل آرگومان نیز باشد.
از این ویژگی می توان برای تعریف ماکروهای شبه تابع نیز استفاده کرد.
مثال زیر نمونه ای از آن را نشان می دهد: define MIN (a,b) ((a) به این ترتیب چنانچه در برنامه از عبارت MIN (x,y) استفاده شود، این عبارت توسط عبارت زیر جایگزین می شود: ((x) #pragma : این رهنمود به سازنده کامپایلر این امکان را می دهد تا بدون مداخله کامپایلرهای دیگر، به تعریف رهنمودهای مورد نظر خود بپردازد.
شکل کلی استفاده از این رهنمود بصورت زیر است: #pragma name «مثال» #pragma code چنانچه name برای کامپایلر نامفهوم باشد، کامپایلر بدون گزارش خطا، این خط را نادیده می گیرد.
این رهنمود در کامپایلر C51 کاربرد زیادی دارد، بطوریکه بیشتر پارامترهای کنترلی C51 را می توان توسط رهنمود #pragma در داخل برنامه مورد استفاده قرار داد.