• مشکی
  • سفید
  • سبز
  • آبی
  • قرمز
  • نارنجی
  • بنفش
  • طلایی
تعداد مطالب : 351
تعداد نظرات : 75
زمان آخرین مطلب : 6097روز قبل
کامپیوتر و اینترنت
آموزش زبان C بخش سی هفتم
اسامي ماكروهاي از پيش تعريف شده

اسامي تعداد 5 ماكرو ( قبلا"تعريف شده است ) كه به همراه كامپايلر استاندارد
زبان C وجود دارند ، عبارتند از : - LINE( -1
- FILE( -2
- DATE( -3
- TIME( -4
- STDC( -5

ماكروي -LINE- حاوي شماره دستوري از فايل برنامه است كه در حال ترجمه شدن
مي باشد .
ماكروي -FILE- حاوي نام فايلي است كه اكنون در حال ترجمه شدن مي باشد .
ماكروي -DATE- حاوي رشته اي بصورت mm/dd/yy است و حاوي تاريخي است كه فايل
برنامه ، ترجمه شده است ( mm براي بيان ماه ، dd براي بيان روز و yy براي بيان
سال است ) .
ماكروي -TIME- حاوي رشته اي بصورت hh:mm:ss است و شامل زماني است كه فايل
برنامه ، ترجمه شده است ( hh براي بيان ساعت ، mm براي بيان دقيقه و ss براي
بيان ثانيه است ) .
ماكروي -STDC- مشخص مي كند كه كامپايلر مورد استفاده استاندارد است يا خير.
اگر محتويات اين ماكرو برابر با يك (1) باشد ، كامپايلر استاندارد و در غير د استاندارد نيست .
خداییش اگر خوشت اومد نظر بده
دوشنبه 19/6/1386 - 22:8
کامپیوتر و اینترنت
آموزش زبان C بخش سی ششم
حذف ماكروهاي تعريف شده

اگر در برنامه ، ماكرويي توسط دستور # define تعريف گردد ، دستور # undef
مي تواند از يك نقطه دلخواه برنامه ( از نقطه اي كه اين دستور قرار مي گيرد )
به بعد ، تعريف ماكرو را بي اثر سازد . اين دستور بصورت زير بكار مي رود :
<نام ماكرو># undef
تعريف ماكرويي كه نام آن در دستور # undef آمده است از جايي كه اين دستور
در برنامه ظاهر مي گردد به بعد ، منتفي مي شود .

مثال : #define LEN 100
#define WIDTH 100
main)(
{
char array[LEN][WIDTH];
#undef LEN
#undef WIDTH
.
.
.
خداییش اگر خوشت اومد نظر بده
دوشنبه 19/6/1386 - 22:7
کامپیوتر و اینترنت
آموزش زبان C بخش سی پنجم
دستورات پيش پردازنده شرطي

در حالت معمولي ، دستورif براي تصميم گيري در نقاط مختلف برنامه بكار ميرود.
شرطهايي كه در دستور if ذكر مي شوند در حين اجراي برنامه ارزشيابي مي شوند .
يعني اگر شرط ذكر شده در دستور if چه درست باشد يا نادرست ، اين دستور و كليه
دستورات ديگر كه در بلاك if قرار دارند ترجمه مي شوند . ولي در دستورات پيش
پردازنده شرطي ، شرطي كه در آن ذكر مي شود در حين ترجمه ارزشيابي مي شود .
دستورات پيش پردازنده شرطي عبارتند از : # if/ # else/ # endif/ # ifdef/ # ifnder

دستور #if بصورت زير بكار مي رود :
عبارت شرطي # if
مجموعه دستورات # endif

عبارت شرطي كه در دستور # if ذكر مي شود ، عبارتي است كه مقدار آن در زمان
ترجمه معلوم است . اين عبارت در حين ترجمه ارزيابي مي شود . چنانچه داراي ارزش "
درستي " باشد مجموعه دستورات موجود در بين # if ( ابتداي بلاك ) و # endif
( انتهاي بلاك ) ترجمه خواهد شد وگرنه اين مجموعه دستورات ترجمه نمي گردد .

مثال 1: #include "stdio.h"
#define max 100
main)(
{
#if max>90
printf("compiled for array" );
printf(" qreater than 90\n");
#endif
}

خروجي برنامه مثال 1 : compiled for array greater than 90

وقتي برنامه مثال 1 ترجمه ميگردد شرط 90>MAX تست ميشود، چون اين شرط برقرار
است ، دستور بعدي ترجمه شده و آماده اجرا مي گردد كه نتيجه اجراي آن را نيز
مشاهده نموديد .
نحوه عمل #else همانند else در دستور if است ( مثال 2 ) .

مثال 2: #include "stdio.h"
#define max 10
main)(
{
#if max>99
printf("compiled for array...\n" );
#else
printf("compiled for small array" );
#endif
}

خروجي برنامه مثال 2 : compiled for small array

در برنامه مثال 2 چون شرط 99>MAX برقرار نيست ، لذا دستور بعد از آن ترجمه
نميشود. اما دستور بعداز #else ترجمه شده و پس از اجرا نتيجه زير حاصل ميگردد: "Compiled for small array"
#elif
مشابه دستور else if رفتار مي كند و بصورت زير استفاده مي شود :
عبارت شرطي 1 # if
مجموعه دستورات 1
عبارت شرطي # elif 2
مجموعه دستورات 2
عبارت شرطي # elif 3
مجموعه دستورات 3 .
.
.

عبارت شرطي # elif n
مجموعه دستورات n # endif

همانطور كه ملاحظه مي شود ، هر # elif به همراه يك عبارت شرطي است كه اگر
نتيجه ارزيابي آن ارزش " درستي " داشته باشد مجموعه دستورات مربوط به آن ترجمه
شده و كنترل به دستور بعداز# endif برمي گردد، وگرنه شرطهاي موجود در#elif هاي
بعدي مورد بررسي قرار مي گيرند ، اگر هيچكدام از عبارات شرطي ذكر شده در اين
ساختار داراي ارزش " درستي " نباشند ، هيچيك از مجموعه دستورات 1تا nا ترجمه
نخواهد شد .

مثال 3: #define US 0
#define ENGLAND 1
#define IRAN g
#define ACTIVE_COUNTRY US
main)(
{
#if ACTIVE_COUNTRY==US
char currency[]="dolar";
#elif ACTIVE_COUNTRY==ENGLAND
char curreney[]="pound";
#else
char curreney[]="rials";
#endif
printf("\n currency is:");
printf("%s"/currency);
}

خروجي برنامه مثال 3 : currency is:dolar

استفاده از #ifdefو #ifndefو روش ديگري براي پياده سازي ترجمه شرطي دستورات
است ( #ifdef يعني "if defined"و #ifndefو يعني "if not defined" ) .
دستور #ifdef بصورت زير بكار مي رود :
نام ماكرو #ifdef
مجموعه دستورات #endif

اگر ماكرويي كه نام آن در جلوي #ifndef ذكر شده است در يك دستور #define
تعريف شده باشد در اين صورت مجموعه دستورات ذكر شده ، ترجمه خواهند شد وگرنه
اين دستورات ترجمه نمي گردند .
دستور # ifndef كه عكس دستور #ifedf عمل مي كند بصورت زير استفاده مي شود :
نام ماكرو #ifndef
مجموعه دستورات #endif

اگر ماكرويي كه نام آن در جلوي # ifndef ذكر شده است در يك دستور # define
تعريف نشده باشد مجموعه دستورات ذكر شده ، ترجمه مي گردند وگرنه ترجمه نخواهند
شد .

مثال 4: #include "stdio.h"
#define TEN 10
main)(
{
#ifdef TEN
printf("\n TEN defined.");
#else
printf("\n TEN not defined.");
#endif
#ifndef ALPHA
printf("\n ALPHA is not defined.");
#endif
}

در برنامه مثال 4 دستور# ifedf تست مي كند كه آيا ماكروي TEN تعريف شده است
يا خير . چون اين ماكرو در اين برنامه تعريف شده است ، دستور بعد از آن ترجمه
شده و پس از اجراي نتيجه زير حاصل مي شود : TEN defined

خداییش اگر خوشت اومد نظر بده
دوشنبه 19/6/1386 - 22:7
کامپیوتر و اینترنت
آموزش زبان C بخش سی چهارم
ضميمه كردن فايل ها (file inclusion)

در زبان C مي توان در حين ترجمه (compile) برنامه ، يك يا چند فايل را به آن
ضميمه كرده و مورد پردازش قرار داد. به فايلهايي كه بدين طريق به برنامه ضميمه
ميشوند، header file گفته ميشود. ضميمه كردن فايل ها، توسط دستور پيش پردازنده #include
انجام مي شود . اين دستور بصورت هاي زير مورد استفاده قرار مي گيرد : "
اسم فايل #include "
<اسم فايل >#include
فايلهاي header مي توانند به دو دسته تقسيم شوند :
الف ) فايلهايي هستند كه همراه كامپايلر C وجود دارند و انشعاب همه آنها h.
است .
ب ) فايلهايي هستند كه توسط استفاده كننده نوشته مي شوند .
از روش اول استفاده دستور # include براي ضميمه فايلهايي استفاده مي شود كه
توسط استفاده كننده نوشته شده اند و از روش دوم ، براي ضميمه فايل هايي به كار
گرفته مي شود كه همراه كامپايلر C وجود داشته و معمولا" در فهرستي بنام include
قرار دارند .
فايلهاي header از اهميت ويژه اي برخوردارند زيرا : 1
بسياري از توابع مثل ()getchar و ()putchar در فايل هاي header مربوط به
سيستم ، بصورت ماكرو تعريف شده اند . 2
با فايل هاي header معمولي ( مربوط به استفاده كننده ) علاوه بر تعريف
ماكروها ، مي توان از بسياري از تعاريف تكراري جلوگيري كرد .

مثال 1: دستور زير ، موجب ضميمه شدن فايل stdio.h به برنامه مي گردد . # include

فرض كنيد كار ما طوري است كه همواره برنامه هايي مينويسيم كه نياز به محاسبه
مساحت هاي اشكال مختلفي مثل دايره ، بيضي و غيره دارد . بهتر است براي سهولت
كار ، مساحت كليه اشكال را بصورت ماكرو تعريف كرده و در يك فايل header قرار
دهيم . سپس در ابتداي برنامه مورد نظر، آن را توسط دستور # include معرفي كنيم
تا به برنامه ضميمه شود . نام فايل header را كه براي اين منظور نوشته مي شود h
.ar انتخاب كرده ، محتويات آن را مي توان بصورت زير نوشت : #define PI #.14159
#define AREA_CITCLE(radius )\
( PI*radius*radius)
#define AREA_SQUARE(length/width )\
( length*width)
#define AREA_TRIANGLE(base/height )\
( base*height/2)
#define AREA_ELLIPS(radius1/radius2 )\
( PI*radius1*radius2)
#define AREA_TRAPEZOID(heigth/side1/ \
side2( )heigth*(side1+side2)/2)

پس از تشكيل فايل ar.h مي توان با ضميمه نمودن اين فايل به هر برنامه اي كه
نياز به محاسبه مساحت اشكال هندسي ذكر شده در اين فايل را دارد ، از ماكروهاي
تعريف شده در اين فايل استفاده كرد .

مثال 2: برنامه اي كه با استفاده از فايل ar.h مساحت مثلثي را محاسبه ميكند. #include
#include
main)(
{
int bas/height/s;
float s;
base=10;
height=15;
s=AREA-TRIANGLE(base/hight);
printf("%f"/s);
}

نمونه اي از خروجي برنامه مثال 2 : the area of triangle
خداییش اگر خوشت اومد نظر بده
دوشنبه 19/6/1386 - 22:6
کامپیوتر و اینترنت
آموزش زبان C بخش سی سوم
تعريف ماكرو

ماكرو، نامي براي يك رشته است كه اين رشته مي تواند تركيبي از خروف ، ارقام
مقادير ثابت ، توابع و غيره باشد . دستور پيش پردازنده # define براي تعريف
ماكرو استفاده مي شود . اين دستور قبل از تابع ()main به دو صورت بكار مي رود
كه يك روش آن بصورت زير است :
<نام ماكرو> <رشته ># define
نام ماكرو همانند نام يك متغير در C است كه حداقل بايد با رشته تعريف كننده
ماكرو ، يك فاصله داشته باشد و بهتر است جهت مشخص بودن در برنامه با حروف بزرگ
انتخاب شود . بعنوان مثال ، دستور # define MAX 20

موجب مي شود تا مقدار ماكروي MAX در سرتاسر برنامه برابر با 20 فرض شود .
يعني در هر جاي برنامه از ماكروي MAX استفاده شود مثل اين است كه از عدد 20
استفاده شده است .
در مورد دستورات پيش پردازنده در زبان C ، بايد اين نكته را در نظر داشت كه
آنها عليرغم ساير دستورات زبان C ، به ; ختم نمي شوند .

مثال 1: برنامه اي كه چگونگي استفاده از ماكروها را نشان مي دهد. اين برنامه
تعدادي عدد را از ورودي خوانده و مجموع آنها را محاسبه مي كند ( اگر عددي كه
وارد مي شود ، منفي باشد ، برنامه متوقف مي شود ) . #define program main)(
#define FLOAT float
#define WHILE while(
#define DO)
#define BEGIN {
#define end }
#define formatout "the sum is %8.2f\n"
PROGRAM
BEGIN
FLOAT data/sum=0.0;
scanf(FORMATIN/& data);
WHILE data>=0.0 DO
BEGIN
sum+=data;
scanf(FORMATIN/&data);
END
printf(FORMAOUT/SUM);
END

نمونه اي از خروجي برنامه مثال 1 : enter a numbet: 12
enter a numbet: 45
enter a numbet: 83
enter a numbet-: 1
the sum is 140.00

در مثال 1 بجاي تابع اصلي ()mainاز PROGRAMز ، بجاي {از BEGINز ، بجاي } از END
و... استفاده شده است . بديهي است كه انتخاب اين نام ها به نظر برنامه نويس
بستيگ دارد كه مي تواند هر چيز ديگري را بجاي آنها انتخاب نمايد .

مثال 2: برنامه اي كه با استفاده از علامت * ، مثلثي را در صفحه نمايش رسم
مي كند . #define NUMLINE 5
#define BLANK ' '
#define ASTRISK '*'
#define NEWLINE '\n'
main)(
{
int l/le/s ;
1=1;
while( l<=NUMLINE)
{
le=1 ;
while( le++<=NUMLINE-1)
printf("%c"/BLANK);
s=1;
while(s++<=2*1-1)
printf("%c"/ASTRISK);
printf("%c"/NEWLINE);
l++;
}
}

خروجي برنامه مثال 2 : *
* * *
* * * * *
* * * * * * *
* * * * * * * * *

كاربرد ديگر دستور# define در تعريف ماكروهايي است كه داراي پارامتر باشند.
در اين مورد از دستور # define بصورت زير استفاده مي شود . # define READINT(I )scanf("%d/&I)

تعريف ماكرو ، مشخص مي كند كه چه عملي بايد توسط ماكرو انجام گيرد . اسامي
پارامترها متغيرهايي هستند كه در حين اجراي ماكرو به آن منتقل مي شوند . اگر
تعداد آنها بيش از يكي باشد ، با كاما از يكديگر جدا مي گردند . برخلاف توابع
در ماكروها نيازي به تعريف نوع پارامترها نيست . بعنوان مثال دستور # define READINT(I )scanf("%d/&I)

ماكرويي بنام READINT تعريف ميكند كه داراي پارامترI است ، درهنگام فراخواني
اين ماكرو ( كه توسط نام آن انجام مي شود ) بايد آرگوماني را ذكر كنيم . اين
آرگومان در عبارت ("%d"/&I)scanf بجاي متغير I منظور شده و تابع scanf عددي را
از ورودي خوانده و در متغيري كه بعنوان آرگومان ذكر شده است قرار مي دهد . به
عنوان مثال اگر بخواهيم متغيري مثل distance رااز ورودي بخوانيم كافيست ماكروي
فوق را بصورت زير فراخواني كنيم : READINT( distance);

اگر تعريف ماكرو شامل عبارتي طولاني باشد ( به طوري كه در يك خط قابل بيان
نباشد ) مي توان آن را در دو يا چند خط ادامه داد . بدين منظور بايد در انتهاي
هر خط ناتمام ، از كاراكتر \(back slash() استفاده نمود . دستور زير را در نظر
بگيريد : # define IS_EQU( y )y% 4==0 && y %100 != 0 || \
y%400=0

همانطور كه در دستور فوق مشاهده مي گردد در انتهاي اولين خط ، از كاراكتر \
استفاده شد تا بتوان بقيه عبارت ماكرو را در خط بعدي تايپ نمود .
اگر ماكروي IS_EQU با پارامتري بنام year فراخواني گردد ، اين متغير بجاي y
قرار خواهد گرفت . يعني فراخواني : if( IS_EQU( year))

معادل دستور زير است : if( year %4= 0 && year %100 != 0 || year %400 == 0)

در فراخواني ماكروها بايد دقت كافي بخرج داد تا از اجراي آنها نتيجه مطلوبي
بدست آيد . بعنوان مثال ماكروي نوشته شده براي انجام عمل توان يك عدد را درنظر
بگيريد : # define SQURE( x )x*x

اكنون به دو فراخواني ماكرو SQURE توجه نماييد : S= SQURE(b( )1)

( با فراخواني فوق ، حاصل b*b در متغيري s قرار مي گيرد كه منظور برنامه نويس
برآورده مي شود ) . S= SQURE(x+1( )2)

در اثر اين فراخواني ، عبارت x+1 * x+1 ارزيابي شده و نتيجه آن در s قرار
مي گيرد كه با توجه به تقدم عملگرها ( كه تفدم عمل ضرب (*) بيشتر از تقدم عمل
جمع (+) است ) . نتيجه ارزيابي ، با توان عدد x+1 برابر نيست . براي رفع اين
مشكل دو راه حل وجود دارد : راه حل اول x+1 را در يك متغير قرار داده و سپس
آن متغير را بعنوان پارامتر به ماكرو منتقل كرد . راه حل دوم ماكرو را طوري
تعريف نمود كه از ايجاد اين اشتباه جلوگيري شود : # define SQURE(( x )*( x))

اكنون اگر ماكروي فوق با x+1 فراخواني گردد عبارت زير حاصل مي شود كه نتيجه
ارزيابي آن ، صحيح است . S=(( x+1 )*( x+1))


مثال 3: برنامه اي كه با استفاده از يك ماكرو ، مساحت دايره اي را محاسبه
مي نمايد . # define PI 3.14159
# define AREA(X( )PI*X*X)
main)(
{
float radius ;
printf("\n enter radius: " );
scanf("%f"/&radius );
printf("\n area is:" );
printf("%.2f "/AREA(radius ));
}

نمونه اي از خروجي برنامه مثال 3 : en
خداییش اگر خوشت اومد نظر بده
دوشنبه 19/6/1386 - 22:6
کامپیوتر و اینترنت
آموزش زبان C بخش سی دوم
دستورات پيش پردازنده

پيش پردازنده ، نوعي مترجم است كه دستورات توسعه يافته اي از يك زبان برنامه
سازي را گرفته و به دستورات قابل فهم براي كامپايلر همان زبان تبديل مي كند .
بعبارت ديگر، ورودي پيش پردازنده ، برنامه اي با دستورات توسعه يافته است و خروجي
آن ، برنامه ديگري است كه توسط پردازشگر اصلي قابل ترجمه و اجرا است . دستورات
توسعه يافته اي كه در زبان C وجود دارند وتوسط پردازشگر اصلي قابل ترجمه و اجرا
نيستند ، فقط توسط پيش پردازنده قابل فهم هستند و به دستورات پيش پردازنده
معروفند . دستورات پيش پردازنده در زبان C از اهميت ويژه اي برخوردار بوده و اي تنوع خاصي است .
خداییش اگر خوشت اومد نظر بده
دوشنبه 19/6/1386 - 22:6
کامپیوتر و اینترنت
آموزش زبان C بخش سی یکم
آرگومانهاي تابع اصلي (()main)

اولين تابع يك برنامه كه اجرا مي شود ، تابع ()main است . اين تابع همانند
توابع ديگر مي تواند داراي آرگومان باشد. آرگومان هاي تابع اصلي را آرگومان هاي
خط فرمان نيز مي گويند . اين نامگذاري بدين دليل است كه :
وقتي برنامه زبان C توسط كامپايلر زبان ترجمه شد ، اين برنامه در خارج از
محيط C و در سطح سيستم عامل قابل اجرا است و در حين اجراي اين برنامه اسامي
آرگومان ها نيز جهت انتقال به تابع اصلي ذكر مي شوند . بعنوان مثال ، فرض كنيد
برنامه اي بنام test.c نوشته ، توسط كامپايلر C آن را ترجمه كرده و برنامه اي به
نام test.exe از آن ساخته ايم . براي اجراي اين برنامه كافي است در سطح سيستم
عامل بصورت زير عمل كنيم (با فرض اين كه اين برنامه در درايو جاري وجود دارد): A>test

اگر فرض شود كه اين برنامه داراي دو پارامتر باشد ، براي اجراي آن در سطح
سيستم عامل ، بايد اسامي آرگومان ها را با يك فاصله بصورت زير تايپ كنيم : A>test par1 par2
par1
و par2و اسامي آرگومان هايي هستند كه به تابع اصلي منتقل مي شوند .
تابع اصلي داراي دو پارامتر بنام هاي argcو argvو است . پارامتر argc از نوع
صحيح بوده و مشخص كننده تعداد آرگومان هاي خط فرمان است . چون نام برنامه به
عنوان يك آرگومان محسوب مي شود لذا حداقل مقدارargc برابر با 1 است . بنابراين
اگر برنامه اي مانند test داراي دو آرگومان باشد، عددي كه در پارامتر argv قرار
مي گيرد برابر با 3 خواهد بود. پارامتر argv به آرايه اي رشته اي اشاره ميكند كه
عناصر آن ، به آرگومان هاي خط فرمان اشاره مي كند . لذا كليه آرگومان هاي تابع
اصلي بصورت رشته هاي فرض مي شوند . بنابراين اگر خواسته باشيم از اعدادي كه به
عنوان آرگومان به تابع اصلي منتقل مي شوند استفاده كنيم ، بايد به طريق مقتضي
( با استفاده از توابع كتابخانه اي و يا توابعي كه خودمان مي نويسيم ) آنها را
از رشته اي ، به عددي تبديل كنيم .

مثال 1: برنامه اي كه نامي را به عنوان آرگومان پذيرفته و عبارت hello را در
جلوي آن نام قرار مي دهد . main(argc/argv)
int argc ;
char *argv[] ;
{
if(argc!=2)
{
printf("\n number of parameter ");
printf("is wrong ." );
exit(0 );
}
printdf("\n\n hello %s"/argv[1] );
}

فرض كنيد نام برنامه مثال 1را name.cا انتخاب كرده ، سپس توسط كامپايلر زبان C
از آن ، برنامه name.exe را ساخته باشيم . براي اجراي اين برنامه كافيست به
صورت زير عمل شود : A>name Ali

پس از اجراي برنامه name ، نتيجه زير حاصل خواهد شد : hello Ali

در مورد ترتيب دسترسي به آرگومان هاي تابع اصلي بايد دقت داشت كه : argv[0]
بنام برنامه ، argv[1] به اولين آرگومان ، argv[2] به دومين آرگومان
و argv[n]به n امين آرگومان اشاره مي كنند .

مثال 2: برنامه اي كه يك عدد را بعنوان آرگومان پذيرفته ، عمل شمارش معكوس از
آن عدد به صفر را انجام مي دهد . اين برنامه مي تواند آرگومان دوم نيز داشته
باشد . اگر آرگومان دوم برابر با "display" باشد ، نتيجه شمارش معكوس در صفحه
نمايش چاپ خواهد شد . main(argc/argv)
int argc ;
char *argv[] ;
{
int disp/count ;
if(argc<=2)
{
printf("\n number of parameter ");
printf("is wrong ." );
exit(0 );
}
if(argc==3 && !strcmp[argv[2]/
"display"))
disp=1 ;
else
disp=0 ;
for(count=atoi(argv[1]);count
;-- count)
if(disp)
printf("\n %d "/count );
printf("%c"/7 );
}

نمونه اي از خروجي برنامه مثال 2 : C:\TC>6-23 5 display
5
4
3
2
1

در خروجي فوق ، 5 عددي است كه بايد بطور معكوس شمارش شود و 6-23 نام برنامه
است .
در مورد مثال 2 بايد دو مطلب زير را بخاطر داشت : 1
تابع ()atoi يكي از توابع كتابخانه اي است كه مقدار عددي رشته اي را به
مقدار عددي صحيح تبديل مي كند. بكار گرفتن اين تابع بدين دليل بود كه عدد وارد
شده بعنوان آرگومان تابع كه شمارش معكوس آن بايد انجام شود ، بصورت رشته اي به
تابع اصلي منتقل خواهد شد كه براي استفاده از آن ، بايد بصورت عددي تبديل شود. 2
آخرين دستور ()printf پس از عمل شمارش معكوس جهت بصدا درآوردن زنگ سيستم
بكار گرفته شده است .
اگر آرايه argv با دو انديس به كار گرفته شود ، موجب دسترسي به هر يك از
از كاراكترهاي آرگومان تابع ( بطور جداگانه ) مي گردد . ( مثال 3 ) .

مثال 3: برنامه اي كه چگونگي دسترسي به هر يك از كاراكترهاي آرگومان تابع
اصلي را نشان مي دهد . main(int argc/char *argv[])
{
int t / i ;
if(argc<2)
{
printf("number of parameters");
printf("is wrong." );
exit(0 );
}
for(t=0 ; t
{
i=0 ;
while(argv[t][i])
{
printf("\n %c "/argv[t][i] );
i++ ;
}
}
}

نمونه اي از خروجي برنامه مثال 3 : C:\TC>6-24 allah
a

l
l
a
h

در مثال 3 بايد دقت داشت كه اولين انديس آرايه argv[] يعني t به آرگومان
تابع اصلي ( مشخص كننده شماره آرگومان ) كه يك رشته است اشاره مي كند، و دومين
انديس اين آرايه به كاراكتري از اين آرگومان اشاره مي كند كه شماره آن كاراكتر
با اين انديس مشخص مي شود . بعنوان مثال ، منظور از argv[2][3] كاراكتر سوم از
آرگومان دوم مي باشد .
از نظر تئوري مي توان حداكثر از 32767 عدد آرگومان استفاده نمود كه معمولا" تعداد را اجازه مي دهد .

خداییش اگر خوشت اومد نظر بده
دوشنبه 19/6/1386 - 22:5
کامپیوتر و اینترنت
آموزش زبان C بخش سی ام
نكاتي در مورد اشاره گرها

عليرغم قدرت زيادي كه استفاده از اشاره گرها در زبان به برنامه نويس مي دهد
اشكالاتي را نيز مي تواند بوجود آورد كه برنامه نويس بايد آنها را در نظر داشته
باشد .
اشكال اول ) استفاده از اشاره گرهايي كه قبلا" مقدار نگرفته اند .

مثال 1: main)(
{
int x/*p ;
x=10 ;
*p=x ;
}

دربرنامه مثال 1 عدد 10 به متغير x نسبت داده ميشود و دستور *p=x; به ماشين
مي گويد " محتويات متغير x را در آدرسي كه اشاره گر p به آن اشاره مي كند قرار
بده " . چون اشاره گر p بجايي در حافظه اشاره نميكند ( قبلا" مقدار نگرفته است )
عمل مورد نظر انجام نخواهد شد. براي رفع اين مشكل كافي است در اشاره گر p مقدار
معتبري قرار گيرد .

اشكال دوم ) عدم استفاده صحيح از اشاره گرها

مثال 2: main)(
{
int x / *p ;
x=10 ;
p=x ;
printf("\n %d"/*p );
}

هدف برنامه مثال 2 اين بود كه مقدار متغيرx را كه برابر با 10 است در خروجي
چاپ نمايد ولي به دليل نادرست بودن دستور p=x; ( با توجه به اشاره گر بودن p )
نتيجه مطلوب حاصل نخواهد شد . اين دستور موجب مي شود تا عدد 10 ، نه بعنوان يك
مقدار بلكه بعنوان يك آدرس به اشاره گر p منتقل گردد . براي رفع اين مشكل كافي
است اين دستور را بصورت p=&x; نوشت تا آدرس متغير x به اشاره گر p منتقل شود .

اشكال سوم ) فرض هايي كه برنامه نويس در مورد محل قرار گرفتن متغيرها در حافظه
دارد .

وقتي كه متغيرها در حافظه قرار مي گيرند ، جاي آنها براي ما مشخص نيست و در
هر جايي كه فضايي كافي وجود داشته باشد اين متغيرها در آنجا ذخيره مي شوند .
به همين دليل مقايسه اشاره گرهايي كه به عناصري از يك نوع اشاره نمي كنند صحيح
نبوده و با مشكل مواجه مي گردد ( مثال هاي 3و 4و ) .

مثال 3: main)(
{
char s[80]/y[80] ;
char *p1 / *p2 ;
p1=s ;
p2=y ;
if(p1<P2)
printf("p1 points to lower addree.");
}

در مثال 3 مقايسه p1و p2و با يكديگر صحيح نيست ، زيرا محل قرار گرفتن
رشته هاي sو yو براي ما مشخص نيست .

مثال 4: main)(
{
int first[10]/second[10] ;
int *p / t ;
p=first ;
for(t=0 ; t<20 ; t++)
*p++=t ;
}

در مثال 4 سعي شده كه به عناصر آرايه هاي firstو secondو اعداد 0 تا 19 نسبت
داده شود. اگر چه ممكن است اين عمل در بعضي از كامپايلرها به درستي انجام گيرد
ولي در حالت كلي اين طور نيست ، زيرا ممكن است عناصر آرايه هاي firstو secondو
در محل هاي متوالي حافظه قرار نگيرند .
با اشكالاتي كه تاكنون درمورد اشاره گرها گفته شد برنامه نويس بايد در استفاده ا دقت كافي بخرج دهد تا با مشكل مواجه نگردد .

خداییش اگر خوشت اومد نظر بده
دوشنبه 19/6/1386 - 22:5
کامپیوتر و اینترنت
آموزش زبان C بخش بیست نهم
اشاره گر به اشاره گر

اگر متغيري آدرس متغير ديگر را در خود نگهداري كند ، متغير اول يك اشاره گر
است . اگر متغير دوم ، از نوع اشاره گر باشد در اينصورت متغير اول يك اشاره گر
به اشاره گر است ( شكل 1 ) . يادآوري مي شود كه آرايه اي از اشاره گرها ، نوعي
اشاره گر به اشاره گر است .
متغير اشاره گر
ؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤ |
مقدار |ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ آدرس >|
ؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤ
ؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤ |
مقدار |ؤؤؤؤؤؤؤؤؤؤؤؤؤؤ آدرس >|ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ آدرس >|
ؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤ
شكل (1) . اشاره گر به اشاره گر

براي تعريف متغيرهاي اشاره گر به اشاره گر ، از دو علامت * استفاده مي شود .

مثال : برنامه اي شامل اشاره گر به اشاره گر . main)(
{
int x / *p /**q ;
x=10 ;
p=&x ;
q=&p ;
printf("\n the points to value:");
printf("%d"/**q );
}

خروجي حاصل از اجراي برنامه مثال بالا : the points to value:1

خداییش اگر خوشت اومد نظر بده
دوشنبه 19/6/1386 - 22:3
کامپیوتر و اینترنت
آموزش زبان C بخش بیست هشتم
ارزش دهي اوليه رشته ها به عنوان اشاره گر

در اين قسمت مي خواهيم مشخص كنيم كه چگونه ميتوان رشته ها را بعنوان اشاره گر
مقدار اوليه داد . براي روشن شدن موضوع ، به مثال 1 توجه نماييد .

مثال 1: main)(
{
char *text="your name is:";
char name[41] ;
printf("\n enter your name: " );
gets(name );
printf("\n\n %s text" );
puts(name );
}

نمونه اي از خروجي برنامه مثال 1 : enter your name:mohammad
your name is:mohammad

اولين دستور مثال 1 را بصورت زير نيز مي توان نوشت : static char text[] = "your name is:";

اين دو دستور از نظر اثري كه در حافظه مي گذارند تفاوتي با يكديگر ندارند .
ولي چون دستوري كه در برنامه آمده است متغير text را بصورت اشاره گر تعريف كرده
است ، قابليت انعطاف بيشتري به اين متغير داده است . اين امر باعث شده است كه
با دستور ساده ;(text++)puts رشته text كاراكتر به كاراكتر به خروجي منتقل گردد
كه نتيجه زير حاصل خواهد شد : your name is:

وقتي كه رشته ها به صورت اشاره گر تعريف مي شوند ، بخصوص در مواقعي كه طول
عناصر مختلف آن ، متفاوت باشند موجب صرفه جويي در ميزان حافظه مي گردند ( مثال ( . 2


مثال 2: برنامه اي كه براي ذخيره كردن نام هاي تعدادي از افراد ، از آرايه اي
از اشاره گرها استفاده مي كند. اين برنامه با خواندن نام 5 نفر از ورودي ، آنها
را در آرايه اي قرار داده ، سپس نامي را از ورودي دريافت مي كند و تشخيص مي دهد
كه آيا اين نام در ليست وجود دارد يا خير . main)(
{
int dex / exist=0 /k ;
char name[21] ;
static char *list[5]=
{"ali"/
"ahmad"/
"alireza"/
"jalal"/
"mohammad"
} ;
printf("enter a name for search:");
gets(name);
for(dex=0;dex<5;dex++)
{
if(strcmp(list[dex]/name)==0)
{
exist=1 ;
break ;
}
}
if(exist==1)
printf("\n name <%s> exist."/name);
else
printf("\n name " );
printf("<%s> not exist."/name);
}

نمونه اي از خروجي برنامه مثال 2 : enter a name for search: ali
name exist.

اگر در مثال 2 فرض شود كه اولين عنصر آرايه list ( كه حاوي 5 نام است ) در
محل 1000 حافظه قرار داشته باشد . اين آرايه بصورتي كه در شكل (1) آمده است در
حافظه قرار مي گيرد .
اگر درمثال 2 بجاي تعريف آرايه اي از اشاره گرها، آرايه اي از رشته ها را تعريف
ميكرديم آنگاه مي بايست آرايه list بصورت آرايه اي دو بعدي تعريف ميشد كه تعداد
سطرهاي آن برابر با تعداد افراد ( تعداد عناصر آرايه ) و تعداد ستون هاي آن
برابر با طول طولاني ترين نام موجود بود ( شكل 2 و مثال 3 ) .
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤ |A |h |m |a |d |\0|
1000ؤؤ > | 1000 List [0]
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤ |A |l |i |\0|
1006ؤؤ > | 1006 List [1]
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤ |A |m |i |n |\0|
1010ؤؤ > | 1010 List [2]
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤ |y |a |f |a |r |n |e |z |h |a |d |\0|
1015ؤؤ > | 1015 List [3]
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤ |B |a |h |r |a |m |i |\0|
1027ؤؤ > | 1027 List [4]
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤ
شكل (1) . نحوه قرار گرفتن آرايه اي از اشاره گرها در حافظه ، شامل 5 نام


ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ | | | | |
|
|A hh |m |a |d |\0| 1000ؤؤؤؤؤؤؤؤؤ > List [0]
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ | | | | | | |
|
|A ll |i |\0| 1012ؤؤؤؤؤؤؤؤؤ > List [1]
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ | | | | | |
|
|A mm |i |n |\0| 1023ؤؤؤؤؤؤؤؤؤ > List [2]
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ |y aa |f |a |r |n |e |z |h |a |d |\0|
1035ؤؤؤؤؤؤؤؤؤ > List [3]
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ | | |
|
|B aa |h |r |a |m |i |\0| 1047ؤؤؤؤؤؤؤؤؤ > List [4]
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ
شكل (2) . نحوه قرار گرفتن آرايه اي از رشته ها در حافظه ، شامل 5 نام

با توجه به نحوه ذخيره شدن اطلاعات در اشكال 1و 2و ذخيره كردن رشته ها بصورت
آرايه اي از اشاره گرها در صرفه جويي ميزان حافظه بسيار موثر است ولي در همه حالات
اينطور نيست . بعنوان مثال اگر طول همه رشته ها 12 باشد ( به اندازه بزرگترين
طول رشته در مثال 2 )، حافظه تخصيص يافته در روش اول ( آرايه اي از اشاره گرها )
داراي 5 اشاره گر اضافي خواهدبود كه حافظه بيشتري را نسبت به روش دوم ( آرايه اي
از رشته ها ) اشغال مي كند . مزيت عمده بيان رشته ها بصورت آرايه اي از اشاره گرها
سرعت بالاتر و سهولت دسترسي به عناصر آنها است . زيرا نيازي به انجام محاسبات
جهت دسترسي به عناصر آرايه نيست .

مثال 3: برنامه اي كه نام تعدادي از افراد را از ورودي خوانده و در يك آرايه
قرار مي دهد . سپس با استفاده از آرايه اي از اشاره گرها ، آن را مرتب مي كند و
نتيجه را به خروجي مي برد . main)(
{
char name[30][81] ;
char *ptr[30]/*temp ;
const int k=30 ;
int in / out / count=0 ;
while(count<K)
{
printf("\n enter name of number");
printf(" %d:"/count+1 );
gets(name[count] );
if(strlen(name[count])==0)
break ;
ptr[count++]=name[count] ;
}
for(out=0 ; out
for(in=out+1 ; in
if(strcmp(ptr[out]/ptr[in])>0)
{
temp=ptr[in] ;
ptr[in]=ptr[out] ;
ptr[out]=temp ;
}
printf("<< the sorted list is:>>");
for(out=0 ; out
printf("\n name %d is:"/out+1);
printf("%s"/ptr[out]);
}

نمونه اي از خروجي برنامه مثال 3 : enter name of number 1:bahrami
enter name of number 2:amin
enter name of number 3:jafar
enter name of number 4:sadeghi
enter name of number 5:
<< the sorted list is:>>

name 1 is:amin
name 1 is:bahrami
name 1 is:jafar
name 1 is:sadeghi

براي توضيح بيشتر در مورد چگونگي مرتب كردن رشته ها از طريق آرايه اي از
اشاره گرها ، به شكل هاي 3و 4و كه بيانگر نحوه قرار گرفتن عناصر آرايه در حافظه
قبل و بعد از مرتب شدن هستند توجه نماييد .
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤؤؤؤ |B |a |h |r |a |m |i |\0|
ؤؤؤؤؤؤؤؤؤ > | ptr[0]
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤؤؤؤ | |
|
|A |m |i |n |\0|ؤؤؤؤؤؤؤؤؤ > | ptr[1]
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤؤؤؤ |
|
|y |a |f |a |r |\0|ؤؤؤؤؤؤؤؤؤ > | ptr[2]
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤؤؤؤ |s |a |d |e |g |h |i |\0|
ؤؤؤؤؤؤؤؤؤ > | ptr[3]
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤؤؤؤ
شكل (3) . وضعيت اشاره گرها قبل از مرتب شدن


ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤؤؤؤ |B |a |h |r |a |m |i |\0|
ؤؤؤ ؤؤؤؤؤ > | ptr[0]
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ ؤؤؤؤ ؤؤؤؤؤؤؤؤؤؤؤؤ |
| | |A |m |i |n |\0|ؤؤؤؤؤؤؤؤؤ > | ptr[1]
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤؤؤؤ |
| |y |a |f |a |r |\0|ؤؤؤؤؤؤؤؤؤ > | ptr[2]
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤؤؤؤ |s |a |d |e |g |h |i |\0|
ؤؤؤؤؤؤؤؤؤ > | ptr[3]
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤؤؤؤ
شكل (4) . وضعيت اشاره گرها بعد از مرتب شدن

نكته اي كه در مورد مثال 3 بايد مورد توجه قرار گيرد اين است كه آرايه name
بصورت دو بعدي تعريف شده است ولي در حين دسترسي به عناصر آن ، بصورت يك بعدي
مورد استفاده قرار گرفته است . اين مساله بدين دليل است كه در زبان C قسمتي از
آرايه را مي توان بصورت يك آرايه فرض كرد . بعبارت ديگر ، در يك آرايه دو بعدي
هر سطر را مي توان بصورت يك آرايه يك بعدي در نظر گرفت . لذا مي توان گفت كه
آرايه دو بعدي ، آرايه اي از آرايه هاي يك بعدي است . بعنوان مثال در دستور : static char name[30][81];

آرايه name يك آرايه دو بعدي تعريف شده است كه ميتوان آن را بصورت يك آرايه
يك بعدي با تعداد 30 عنصر در نظر گرفت كه هر عنصر آن نيز يك آرايه يك بعدي است.

خداییش اگر خوشت اومد نظر بده
دوشنبه 19/6/1386 - 22:3
مورد توجه ترین های هفته اخیر
فعالترین ها در ماه گذشته
(0)فعالان 24 ساعت گذشته