در ابتدا با ساختار آشنا می شویم تا پیش زمینه ای برای تعریف کلاس و درک مفهوم شی گرایی داشته باشیم. تعریف ساختار در واقع تعریف یک نوع داده جدید توسط برنامه نویس می باشد . برای درک بهتر به ارائه یک مثال می پردازم. فرض کنید می خواهید اطلاعات یک دانشجو شامل کد دانشجویی، نام، نام خانوادگی، رشته تحصیلی و معدل را از ورودی دریافت و در خروجی نمایش دهید. برای این منظور می توان برای هریک از فیلدها، یک متغیر تعریف کرده و مقادیر انها را از کاربر دریافت نموده و به ساده گی در خروجی چاپ نماییم. 


int code;
char* name;
char* family;
char* field;
float avg;

حال اگر بخواهید اطلاعات 100 دانشجو را از ورودی دریافت نمایید در آن صورت بهتر است که از یک آرایه برای نگهداری هر فیلد استفاده نمایید. برای مثال از آرایه code و آرایه name برای ذخیره کد و نام دانشجویان استفاده نمایید. که در آن i-امین عنصر آرایه code در واقع کد دانشجوی i-ام را نشان میدهد. به همین ترتیب آرایه های family، field و avg برای ذخیره سایر فیلدها تعریف نمایید. 


int code[100];
char* name[100];
char* family[100];
char* field[100];
float avg[100];

اگر بخواهیم در یک تابع به نام print اطلاعات تمامی دانشجویان را نمایش دهیم آنگاه باید این تابع دارای پنج آرگومان به ترتیب برای فیلدهای کد، نام، نام خانواده گی، رشته و معدل دانشجویان خواهد بود. 


void print(int code[], char* name[], char* family [],  char* field [], float avg[] )
{
}

حال ممکن است این سوال در ذهن ما مطرح شود که اگر یک نوع داده جدید به نام student وجود داشته باشد انگاه ما دیگر مجبور نخواهیم بود برای هر فیلد یک نوع داده تعریف کنیم. در واقع ما می توانیم یک متغیر از این داده جدید تعریف کرده و مقادیر فیلدهای ان را تنظیم نماییم. همچنین برای ذخیره اطلاعات 100 دانشجو می توان یک آرایه 100 عنصری از نوع student تعریف کرد. و دیگر مجبور به ارسال پنج نوع ارگومان به تابع print نخواهیم بود. 
خوشبختانه زبان برنامه نویسی C این امکان را در اختیار ما قرار می دهد که بتوانیم نوع داده مخصوص خودمان را تعریف نماییم. برای تعریف داده جدید باید از مکانیسمی به نام ساختار به صورت زیر استفاده نماییم. 


struct student {
    int   code;
    char  name[80];
    char  family[80];
    char  field[80];
    float avg;
};

ابتدا کلمه کلیدی struct و به دنبال ان نام ساختار (که همان نام نوع داده سفارشی خودمان است) را قرار دهید. همانطور که می بینید در داخل بدنه ساختار همان متغیر هایی را که قبلا تعریف کرده ایم را قرار داده ایم. یعنی یک داده جدید خود شامل داده های دیگری است که در داخل ان تعریف شده اند. 
حال می خواهیم کمی با نوع جدید خودمان کار کنیم تا با نحوه تعریف و مقداردهی یک متغیر آشنا شویم. در مثال زیر یک متغیر به نام st از نوع student تعریف شده است. مقدارهایی که به هر فیلد تخصیص می یابد را باید به همان ترتیبی که در ساختار آمده اند در داخل } و { لیست نماییم. این مقادیر توسط کاما (,) از هم جدا می شوند. برای مثال کد دانشجویی برابر 100 و نام دانشجو amir می باشد به همین ترتیب برای سایر فیلد ها. 


student st = { 100, "hesam", "alizadeh", "computer", 16.38 };

می توانیم مقداردهی را بعد از تعریف متغیر به صورت جداگانه انجام دهیم. برای این کار ابتدا نام متغیر، عملگر نقطه و بلافاصله نام فیلد مربوطه را قرار می دهیم. ترتیب مقدار دهی در این روش اهمیتی ندارد. 


student st;
st.code = 100;
st.name = "hesam";
st.family = "alizadeh";
st.field = "computer";
st.avg = 16.38;

حال اگر بخواهیم اطلاعات یک دانشجو را از ورودی دریافت و ذخیره نماییم به ساده گی می توانیم یک متغیر از نوع student تعریف کرده و مقادیر دریافت شده را به آنها اختصاص دهیم. برای دریافت اطلاعات 100 دانشجو نیز باید یک آرایه از نوع student تعریف نماییم. و در داخل یک حلقه اطلاعات دانشجوی i-ام را دریافت و در اندیس i-ام آرایه ذخیره نماییم. آرگومان تابع print را می توان یک آرایه از نوع student در نظر گرفت. پس با تعریف داده جدید خودمان می توانیم به راحتی یک متغیر از آن تعریف کنیم همچنین یک ارایه و می توانیم آن را به عنوان ارگومان به توابع منتقل کنیم. 

نکته مهم در تعریف ساختار این است که در یک ساختار ما فقط مجاز به تعریف فیلد(متغیر) هستیم. نمی توان هیچ متد(تابع) را در داخل ساختار تعریف کرد. ولی در تعریف یک کلاس علاوه بر تعریف فیلد می توان متدهایی را برای پردازش فیلدها هم تعریف نماییم. البته ناگفته نماند که اگر از کامپایلر ++C استفاده می کنید می توانید در داخل ساختار متدهایی را هم تعریف نمایید چون کامپایلر ++C هیچ تفاوتی بین تعریف کلاس و ساختار نمی بیند. معمولا برنامه نویسان ++C اکثرا برای نیازهایشان از کلاس استفاده می کنند و لی برنامه نویسان C استفاده ازساختار را ترجیح می دهند. 
اگر بخواهیم خصوصیتی دیگر مثل تاریخ تولد را به ساختار student اضافه کنیم به جای تعریف سه متغیر از نوع صحیح به نام های year، month و day می توان یک داده سفارشی دیگر به نام date تعریف کرده و از آن یک نمونه به نام birthdate در ساختار student استفاده کنیم. در شی st برای دسترسی به فیلد day از شی birthdate باید دوبار از عملگر نقطه به صورت st.birthdate.day استفاده نماییم. همچنین مقدار دهی اولیه به صورت زیر خواهد بود. 


student st = { 100, "hesam", "alizadeh", "computer", 16.38, {1363, 04, 20} };

حال تعریف ساختار student را در زیر مشاهده می نمایید. 


struct date{
    int year;
    int month;
    int day;
};

struct student {
    int   code;
    char  name[80];
    char  family[80];
    char  field[80];
    float avg;
    date birthdate;
};

در مبحث شی گرایی هر موجودیتی را باید به عنوان یک شی(object) همراه با یک سری خاصیت (property) تجسم کنید. برای مثال دانشجو را یک شی از کلاس Student در نظر بگیرد که می تواند خواصی مثل کد، نام، نام خانوادگی، رشته تحصیلی ومعدل و ... داشته باشد. تعریف یک کلاس یا ساختار صرفا یک تعریف است! کامپایلر هیچ حافظه ای را برای تعریف کلاس اختصاص نمی دهد. در واقع زمانی که شما یک متغیر ( یا نمونه یا شی) از کلاس تعریف می کنید، انگاه کامپایلر برای آن شی از سیستم حافظه می گیرد. 

نکته اخر این که معمولا برنامه نویسان برای نام گذاری ساختار از حروف کوچک استفاده می کنند ولی درتعریف کلاس حرف اول نام کلاس را از حروف بزرگ انتخاب می کنند. 
در قسمت های آتی این آموزش مفاهیم کلاس، کلاس مجرد، وراثت و سایر مفاهیم مربوط به شی گرایی را با ذکر مثال توضیح خواهم داد. 
در این آموزش ها هدف ما اموزش برنامه نویسی نیست ولی ناگزیر برای درک بهتر باید مثال هایی هر چند ناقص را ارائه نمایم! 
امیدوارم این اموزش به درک بهتر شما کمک کرده باشد. :)

آیا این پاسخ به شما کمک کرد؟ 119 کاربر این را مفید یافتند (120 نظرات)