310 likes | 530 Views
مبانی کامپیوتر و برنامه سازی. مدرس: سید حسین خواسته. فصل نهم. برخی ساختارها در زبان C. ساختارها( Structures ) یونیونها( Unions ) ساختارهای بیتی( Bit fields Structures ) شمارشها ( Enumerations ). فهرست مطالب فصل نهم. نوع داده های تعریف شده بوسیله کاربر.
E N D
مبانی کامپیوتر و برنامه سازی مدرس: سید حسین خواسته
فصل نهم برخی ساختارها در زبان C
ساختارها(Structures) یونیونها(Unions) ساختارهای بیتی(Bit fields Structures) شمارشها (Enumerations) فهرست مطالب فصل نهم
نوع داده های تعریف شده بوسیله کاربر • با استفاده از typedef می توان معادلهایی برای نوع داده های استاندارد موجود تعریف نمود • typedefint Length; • با تعریف بالا Length معادل int می شود و می توان از آن برای تعریف متغیرها استفاده نمود Length a, b, len ; Length numbers[10] ; typedef char String[50]; typedefint Array[10]; Stringname; Array ages;
ساختارها • مجموعه ای از متغیرهای مرتبط با یک نام واحد هستند • ساختارها می توانند برخلاف آرایه ها شامل متغیرهایی از انواع مختلف باشند • معمولاً از ساختارها برای تعریف مواردی که در فایلها ذخیره می شوند استفاده می شود
تعریف ساختارها • نام employee نشانه ساختار نامیده می شود • متغیرهایی که بین {} تعریف می شوند، اعضای ساختار هستند structemployee { char firstName[ 20 ]; char lastName[ 20 ];int age; char gender; double hourlySalary; }; struct employee Ali, emp[10]; struct employee { char firstName[ 20 ]; char lastName[ 20 ];int age; char gender; double hourlySalary; } Ali, Sara, empDTS[20]; struct employee Reza, *emp; struct { char firstName[ 20 ]; char lastName[ 20 ];int age; char gender; double hourlySalary; } Ali;
تعریف ساختارها • معمولاً از typedef به همراه ساختارها استفاده می شود تا یک معادل برای ساختار تعریف شود typedefstruct { char firstName[ 20 ]; char lastName[ 20 ];int age; char gender; double hourlySalary; } employee;//معادل employeeAli; /* یک متغیر از نوع ساختار ایجاد می کند*/
تعریف ساختارها • متغیرهای عضو یک ساختار می باید اسامی یکتایی داشته باشند ولی متغیرهای عضو ساختارهای مختلف می توانند نامهای یکسانی داشته باشند. • در انتهای تعریف هر ساختار یک “;” قرار می گیرد 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 ]; // OKint age; char gender; }; struct Student KNTU_92[80];
تعریف ساختارها • یک ساختار نمی تواند شامل متغیری از نوع همان ساختار باشد، ولی متغیری از نوع اشاره گر به همان ساختار مجاز است struct employee2 { // … double hourlySalary; struct employee2 person; /* ERROR */struct employee2 *ePtr; /* pointer */};
تعریف ساختارها • می توان یک نام به عنوان نشانه ساختار درنظر نگرفت • در اینصورت متغیرهای از نوع این ساختار را فقط می توان در کنار تعریف خود ساختار تعریف نمود و در سایر مکانهای برنامه نمی توان این نوع متغیرها را تعریف نمود struct { char firstName[ 20 ]; char lastName[ 20 ];int age; char gender; double hourlySalary; } Ali;
دسترسی به اعضای یک ساختار • اعضای یک ساختار با استفاده از عملگر “.” قابل دسترسی هستند myEmp.firstName ; employee. firstName; // Error • اگر یک اشاره گر به ساختار تعریف شده باشد • employee *emp = &myEmp ; • با استفاده از عملگر “->” نیز می توان به اعضای ساختار دسترسی داشت • emp->firstName; // arrow operator • می توان به صورت زیر نیز به اعضای ساختار دسترسی داشت • (*emp).firstName; struct employee { char firstName[ 20 ]; // … } myEmp;
مقداردهی اولیه ساختار //یک ساختار تعریف می شود ولی فضایی برایش در نظر نمی شود 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.person.gpa = 3.4 ; 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) ; js.personal.id Error js = {"Joe", "Smith", 25, 9, 10} strcpy(js.FirstName, "Joe");
مقداردهی اولیه ساختار //یک ساختار تعریف می شود ولی فضایی برایش در نظر نمی شود 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) ;
آرایه ای از ساختارها struct identity { char FirstName[30]; char LastName[30]; unsigned age; struct personal person; } students[4]; //Create a struct but don’t reserve space struct personal { long id; // student ID float gpa; // grade point average }; struct identity KNTU_Mabani[80] = {"omid", “Vatandoust", 14, 9140153, 20, "Samad", "Shekarestani", 90, 2222222, 20} ; strcpy(KNTU_Mabani[2].FirstName, "KhajeNasir"); strcpy(KNTU_Mabani[2].LastName, "Shekarestani"); KNTU_Mabani[2]. age = 100; KNTU_Mabani[2]. person.id = 11111111; KNTU_Mabani[2]. person. gpa = 20;
مثال #define NFRIENDS 10 struct Date { unsigned year; unsigned month; unsigned day; }; struct Friend { char FirstName[30]; char LastName[30]; struct Date Birthday; }; boolcheck_birthday(struct Date today, struct Date myFriend) { if ((today.month == myFriend.month) && (today.day == myFriend.day)) return (true); return (false); } int main() { struct Friend friends[NFRIENDS]; struct Date today = {2012, 3, 11}; // ... for (i = 0; i < NFRIENDS; i++) { if(check_birthday(today, friends[i].Birthday)) printf ("%s %s\n", friends[i].FirstName, oj.LastName) ; } // … typedefstruct { unsigned year; unsigned month; unsigned day; } Date; boolcheck_birthday(Date today, Date myFriend) { //… }
اشاره گر به ساختارها Date create_date1(int month, int day, int year) { Date d; d.month = month; d.day = day; d.year = year; return (d); } void create_date2(Date *d, int month, int day, int year) { d->month = month; d->day = day; d->year = year; } Pass-by-reference Date today; today = create_date1(9, 4, 2008); create_date2(&today, 9, 4, 2008); Copies date
year: 2008 0x30A8 day: 4 0x30A4 month: 9 0x30A0 d: 0x1000 0x3098 today.year: 0x1008 today.day: 0x1004 today.month: 0x1000 اشاره گر به ساختارها 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); } 2008 4 9
اشاره گر به ساختارها Date * create_date3(int month, int day, int year) { Date *d; d->month = month; d->day = day; d->year = year; return (d); } 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); } 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
یونیونها(Unions) • یک یونیون مشابه یک ساختار است که اعضای آن در یک فضای مشترک در حافظه تعریف می شوند • به دلایلی ممکن است در یک برنامه در عمل فقط یکی از چند متغیر موردنیاز باشد و بنابراین لزومی ندارد که فضای حافظه با درنظر گرفتن فضای جداگانه برای همه آنها هدر دهیم • اعضای یونیون می توانند از هر نوعی باشند • فضای حافظه درنظر گرفته شده برای یونیون به اندازه فضای موردنیاز برای ذخیره عضوی از آن است که بیشترین فضای حافظه را نیاز دارد • فقط یک عنصر (و در نتیجه یک نوع داده) در هر زمان می تواند مورد رجوع قرار گیرد
نمایش یونیونها c union myDataUnion { inti; char c; float f; } u1, u2; union myDataUnion u3; u1.i = 4; u1.c = ’a’; u2.i = 0xDEADBEEF; i f
یونیونها(Unions) • عملگرهای قابل استفاده برروی یونیونها عبارتند از: • نسبت دهی یک یونیون از یک نوع به یک یونیون دیگر از همان نوع • بدست آوردن آدرس با استفاده از & • دسترسی به عناصر یونیون با استفاده از “.” و “->” • یونیونها نمی توانند با استفاده از عملگرهای == و != مورد مقایسه قرا گیرند (به دلیل مشابه دلیل ذکر شده برای ساختارها)
یونیونها(Unions) • یک یونیون می تواند بوسیله یک مقدار از نوع داده اولین عضو خود مقداردهی اولیه شود union a { int a; // OK char b[4]; }; union a b = {10}; printf("%d", b.a);
ساختارهای بیتی • در زبان C می توان مشخص کرد که یک متغیر از نوع int یا unsigned int در یک ساختار یا یونیون دقیقاً در چند بیت ذخیره شود. • به این موارد بخش بیتی (Bit field) می گویند • برای تعریف یک بخش بیتی یک “:” و سپس تعدا بیتهای موردنیاز آورده می شود • بخشهای بیتی مشابه عناصر دیگر ساختارها قابل دسترسی هستند
f1 f2 f3 1 1 0 1 1 0 … … ساختارهای بیتی struct Flags { int f1:3; unsigned int f2:1; unsigned int f3:2; } foo; foo.f1 = -2; foo.f2 = 1; foo.f3 = 2;
شمارشها (Enumerations) • Enumeration یک نوع داده تعریف شده بوسیله کاربر است و با استفاده از کلمه کلیدی enum تعریف می شود • enumtag_name{name_0, …, name_n} ; • tag_name به صورت مستقیم استفاده نمی شود، اسامی قرار گرفته بین {} ثابتهای نمادینی هستند که مقادیر بین 0 تا n به آنها اختصاص می یابد، به عنوان مثال: • enum colors { red, yellow, green } ; • سه مقدار ثابت ایجاد می شود و به ترتیب مقادیر 0 به red، 1 به yellow و 2 به green نسبت داده می شود
شمارشها (Enumerations) • اسامی شناسه ها در یک شمارش می باید یکتا باشند • مقادیر ثابتها در یک شمارش از 0 شروع می شوند، مگر اینکه مقدار دیگری مشخص شود • مقدار هر ثابت در شمارش می تواند به صورت دقیق در هنگام تعریف شمارش معین شود • چند عضو یک شمارش می توانند مقدار یکسان داشته باشند • بعد از تعریف یک شمارش نمی توان مقادیر ثابتهای آنرا تغییر داد
مثال /* این برنامه از شمارشها برای دسترسی به عناصر یک آرایه استفاده می کند*/ #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] ); }
مثال /* ثابتهای شمارش ماههای سال را نمایش می دهند*/ 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] ); }