مبانی کامپیوتر و برنامه سازی مدرس :سید حسین خواسته فصل نهم برخی ساختارها در زبان C فهرست مطالب فصل نهم • ساختارها()Structures • یونیونها()Unions • ساختارهای بیتی()Bit fields Structures • شمارشها ()Enumerations 3 نوع داده های تعریف شده بوسیله کاربر • با استفاده از typedefمی توان معادلهاایی بایان عاوا داده اان استاعدارد موجود تعییف عمود ;• typedef int Length • با تعییف باال Lengthمعادل intمی شود و می توان از آن بیان تعییف متغیی ا استفاده عمود ; Length a, b, len ; ]Length numbers[10 ;]typedef char String[50 ;]typedef int Array[10 ;String name ;Array ages 4 ساختارها • مجموعه ان از متغیی ان میتبط با یک عام واحد ستند • ساختار ا می تواعناد بایخ آ آرایاه اا شاامی متغیی اایی از اعاواا مختلف باشند • معموالً از ساختار ا بیان تعییف ماواردن هاه در یایلهاا رخیایه مای شوعد استفاده می شود 5 تعریف ساختارها عشاعه ساختار عامیده می شودemployee • عام اعضان ساختار ستند،• متغیی ایی هه بین }{ تعییف می شوعد struct employee struct employee { { char firstName[ 20 ]; char firstName[ 20 ]; char lastName[ 20 ]; char lastName[ 20 ]; int age; char gender; int age; double hourlySalary; char gender; double hourlySalary; } Ali, Sara, empDTS[20]; }; struct employee Reza, struct employee Ali, *emp; emp[10]; 6 struct { char firstName[ 20 ]; char lastName[ 20 ]; int age; char gender; double hourlySalary; } Ali; تعریف ساختارها • معموالً از typedefبه میاه ساختار ا استفاده مای شاود تاا یاک معادل بیان ساختار تعییف شود typedef struct { ;] char firstName[ 20 ;] char lastName[ 20 ;int age ;char gender ;double hourlySalary معادل} employee; // */یک متغیر از نوع ساختار ایجاد می کند *Ali; / 7 employee تعریف ساختارها • متغیی ان عضو یک ساختار می باید اسامی یکتایی داشته باشند ولی متغیی ان عضو ساختار ان مختلف می تواعند عامهان یکساعی داشته .باشند struct employee { char Name[ 20 ]; char Name[ 20 ]; // Error!!! int age; char gender; double hourlySalary; } Ali, Sara, empDTS[20]; struct employee Reza, *emp; struct Student { char Name[ 20 ]; // OK int age; char gender; }; struct Student KNTU_92[80]; • در اعتهان تعییف ی ساختار یک ”;“ قیار می گیید 8 تعریف ساختارها • یک ساختار عمی تواعد شامی متغیین از عوا مان ساختار باشد ،ولی متغیین از عوا اشاره گی به مان ساختار مجاز است { struct employee2 … // ;double hourlySalary struct employee2 person; /* ERROR */ struct employee2 *ePtr; /* pointer */ ;} 9 تعریف ساختارها • می توان یک عام به عنوان عشاعه ساختار درعظی عگییت struct { ;] char firstName[ 20 ;] char lastName[ 20 ;int age ;char gender ;double hourlySalary ;} Ali • در اینصورت متغیی ان از عوا این ساختار را یقط مای تاوان در هناار تعییف خود ساختار تعییف عمود و در سایی مکاعهان بیعامه عمی تاوان این عوا متغیی ا را تعییف عمود 10 دسترسی به اعضای یک ساختار • اعضان یک ساختار با استفاده از عملگی ” “.قابی دستیسی ستند ; myEmp.firstName employee. firstName; // Error • اگی یک اشاره گی به ساختار تعییف شده باشد ; – employee *emp = &myEmp – با استفاده از عملگی ”> “-عیز می توان به اعضان ساختار دستیسی داشت – emp -> firstName; // arrow operator – می توان به صورت زیی عیز به اعضان ساختار دستیسی داشت ;(* emp).firstName struct employee { ;] char firstName[ 20 … // ;} myEmp 11 – مقداردهی اولیه ساختار //یک ساختار تعریف می شود ولی فضایی برایش در نظر نمی شود struct personal { long id; // student ID float gpa; // grade point average }; struct identity { char FirstName[30]; char LastName[30]; unsigned age; struct personal person; }; struct identity js = {"Joe", "Smith", 25}, *ptr = &js ; js.person.id = 123456789 ; js =js. {"Joe", "Smith", 25,Error 9, 10} strcpy(js.FirstName, .id "Joe"); js.person.gpa = 3.4 ; personal printf ("%s %s %d %ld %f\n", js.FirstName, js.LastName, js.age, js.person.id, js.person.gpa) ; printf ("%s %s %d %ld %f\n", ptr->FirstName, ptr->LastName,ptr->age, ptr->person.id, ptr->person.gpa) ; 12 مقداردهی اولیه ساختار //یک ساختار تعریف می شود ولی فضایی برایش در نظر نمی شود struct personal { long id; // student ID float gpa; // grade point average }; struct identity { char FirstName[30]; char LastName[30]; unsigned age; struct personal person; }; struct identity js = {"Joe", "Smith", 25}, oj ; js.person.id = 123456789 ; js.person.gpa = 3.4 ; oj = js; printf ("%s %s %d %ld %f\n", oj.FirstName, oj.LastName, oj.age, oj.person.id, oj.person.gpa) ; 13 آرایه ای از ساختارها struct identity14, 9140153, 20, struct identity //Create a struct KNTU_Mabani[80] but don’t reserve=space {"omid", “Vatandoust", { struct personal "Samad", "Shekarestani", 90, 2222222, 20} ; char FirstName[30]; { strcpy(KNTU_Mabani[2].FirstName, "Khaje Nasir"); strcpy(KNTU_Mabani[2].LastName, long id; // student ID "Shekarestani"); char LastName[30]; unsigned age; KNTU_Mabani[2]. float gpa;age // grade = 100;point average struct personal person; }; KNTU_Mabani[2]. person.id = 11111111; } students[4]; KNTU_Mabani[2]. person. gpa = 20; FirstName LastName age students[0] omid Vatandoust Students[1] Samad students[2] Khaje Nasir person id gpa 14 9140153 20 Shekarestani 90 2222222 20 Shekarestani 100 11111111 20 students[3] 14 مثال #define NFRIENDS 10 struct Date { unsigned year; unsigned month; unsigned day; }; struct Friend { char FirstName[30]; char LastName[30]; struct Date Birthday; }; bool check_birthday(struct Date today, struct Date myFriend) { if ((today.month == myFriend.month) && (today.day == myFriend.day)) return (true); return (false); } int main() typedef struct { struct Friend friends[NFRIENDS]; unsigned year; struct Datemonth; today = {2012, 3, 11}; unsigned // ... unsigned day; for (i = 0; i < NFRIENDS; i++) } Date; { check_birthday(Date today, Date myFriend) bool { if(check_birthday(today, friends[i].Birthday)) //… printf ("%s %s\n", friends[i].FirstName, oj.LastName) ; } } // … 15 اشاره گر به ساختارها Date create_date1(int month, void create_date2(Date *d, int day, int month, int year) int day, Pass-by-reference { int year) Date d; { d->month = month; d.month = month; d->day = day; d.day = day; d->year = year; d.year = year; } return (d); } Date today; Copies date today = create_date1(9, 4, 2008); create_date2(&today, 9, 4, 2008); 16 اشاره گر به ساختارها void create_date2(Date *d, int month, int day, int year) { d->month = month; d->day = day; d->year = year; } void foo(void) { Date today; create_date2(&today, 9, 4, 2008); } 17 0x30A8 year: 2008 0x30A4 day: 4 0x30A0 month: 9 0x3098 d: 0x1008 today.year: 2008 0x1004 today.day: 4 0x1000 today.month: 9 0x1000 اشاره گر به ساختارها Date * create_date3(int month, int day, int year) { Date *d; d->month = month; d->day = day; d->year = year; return (d); } 18 به چه چیزن اشاره می هند؟!؟!؟d اشاره گر به ساختارها void changeByValue(Date date) { date.day ++; } void changeByRef(Date *date) { date->day++; } void printDate(const Date date) { printf("today(d/m/y) is : \n"); printf("%d/%d/%d\n", date.day, date.month, date.year); } 19 Date today = {2012, 3, 11}; printDate(today); changeByValue(today); printDate(today); changeByRef(&today); printDate(today); today(d/m/y) is : 11/3/2012 today(d/m/y) is : 11/3/2012 today(d/m/y) is : 12/3/2012 مقایسه ساختارها • ساختار ا عباید با استفاده از عملگی ان == و =! مورد مقایساه قایار گییعد زییا اعضان ساختار ا لزوماً در بایتهان متوالی حایظاه رخیایه عمی شوعد { struct a ;int a ;int b ;} ;struct a b, c ;b.a = 10 ;b.b = 30 ;c = b if(c == b) // Error 20 یونیونها()Unions • یک یوعیون مشابه یک ساختار است هه اعضان آن در یاک یضاان مشاتیر در حایظاه تعییف می شوعد • به دالیلی ممکن است در یک بیعامه در عمی یقط یکی از چند متغیای موردعیااز باشاد و بنابیاین لزومی عدارد هه یضان حایظه با درعظی گییتن یضان جداگاعاه بایان ماه آعهاا در د یم • اعضان یوعیون می تواعند از ی عوعی باشند • یضان حایظه درعظی گییته شده بیان یوعیون باه اعادازه یضاان موردعیااز بایان رخیایه عضون از آن است هه بیشتیین یضان حایظه را عیاز دارد • یقط یک عنصی (و در عتیجه یک عوا داده) در ی زمان می تواعد مورد رجوا قیار گیید 21 نمایش یونیونها c union myDataUnion { int i; char c; float f; } u1, u2; union myDataUnion u3; i f u1.i = 4; u1.c = ’a’; u2.i = 0xDEADBEEF; 22 یونیونها()Unions • عملگی ان قابی استفاده بیرون یوعیوعها عبارتند از: – عسبت د ی یک یوعیون از یک عوا به یک یوعیون دیگی از مان عوا – بدست آوردن آدرس با استفاده از & – دستیسی به عناصی یوعیون با استفاده از ” “.و ”>“- • یوعیوعها عمی تواعند با استفاده از عملگی ان == و =! ماورد مقایساه قیا گییعد (به دلیی مشابه دلیی رهی شده بیان ساختار ا) 23 یونیونها()Unions • یک یوعیون می تواعد بوسیله یک مقدار از عوا داده اولین عضاو خاود مقدارد ی اولیه شود union a { int a; // OK ;]char b[4 ;} ;}union a b = {10 ;)printf("%d", b.a 24 ساختارهای بیتی • در زبان Cمی توان مشخص هید هه یک متغیی از عوا intیا unsigned int در یک ساختار یا یوعیون دقیقاً در چند بیت رخییه شود. • به این موارد بخش بیتی ( )Bit fieldمی گویند • بیان تعییف یک بخش بیتی یک ” “:و سپس تعادا بیتهاان موردعیااز آورده مای شود • بخشهان بیتی مشابه عناصی دیگی ساختار ا قابی دستیسی ستند 25 ساختارهای بیتی struct Flags { int unsigned int unsigned int } foo; foo.f1 = -2; foo.f2 = 1; foo.f3 = 2; f1:3; f2:1; f3:2; f1 f2 f3 1 1 0 1 1 0 … … 26 …8 bit … …8 bit … …8 bit … شمارشها ()Enumerations • Enumerationیک عوا داده تعییف شده بوسیله هاربی است و باا استفاده از هلمه هلیدن enumتعییف می شود ; }– enum tag_name {name_0, …, name_n • tag_nameبه صورت مستقیم استفاده عمای شاود ،اساامی قایار گییته بین {} ثابتهان عمادینی ستند هه مقادیی بین 0تا nبه آعها اختصاص می یابد ،به عنوان مثال: ; } – enum colors { red, yellow, green • سه مقدار ثابت ایجاد می شود و به تیتیب مقادیی 0باه 1 ،redباه yellowو 2به greenعسبت داده می شود 27 شمارشها ()Enumerations • اسامی شناسه ا در یک شمارش می باید یکتا باشند • مقادیی ثابتها در یک شمارش از 0شیوا می شاوعد ،مگای اینکاه مقادار دیگاین مشخص شود • مقدار ی ثابت در شمارش می تواعد به صورت دقیق در نگاام تعییاف شامارش معین شود • چند عضو یک شمارش می تواعند مقدار یکسان داشته باشند • بعد از تعییف یک شمارش عمی توان مقادیی ثابتهان آعیا تغییی داد 28 مثال /* *این برنامه از شمارشها برای دسترسی به عناصر یک آرایه استفاده می کند/ #include <stdio.h> int main( ) { int March[5][7]={{0,0,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,0,0}}; enum days {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}; enum week {week_one, week_two, week_three, week_four, week_five}; printf ("Monday the third week of March is March %d\n", March [week_three] [Monday] ); } 29 مثال /* *ثابتهای شمارش ماههای سال را نمایش می دهند/ enum months {JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC }; enum months month; /* *مقداردهی اولیه/ const char *monthName[] = { "", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October“, “November”, “December” /* *حلقه بر روی ماهها/ for (month = JAN; month <= DEC; month++ ) { printf( "%2d%11s\n", month, monthName[month] ); } 30