خب تو این قسمت میخواهیم بررسی کنیم چطور میتونیم تو برنامه ای که مینویسیم مشخص کنیم که یه قسمت مدنظر ما تو کدوم یک از بخش های حافظه ذخیره بشه. کلمات کلیدی زبون C که میتونن برای رسیدن به این هدف بهمون کمک کنن اینا هستند:
اولین مورد از موارد فوق مشخص میکنه که نوع متغیری که میخوایم تعریف کنیم چیه. این قضیه به طور مستقیم روی حافظه ای که قراره این متغیر اشغال کنه تاثیر میذاره. انواع متغیر مثه char ,float ,int و … هرکدوم مقدار مشخصی از حافظه رو اشغال میکنند.
دومین مورد که ما معمولا با کلمه کلیدی const ازش استفاده میکنیم باعث میشه متغیر تعریف شده صرفا قابل خواندن باشه و نشه مقدارش رو تغییر داد. البته کلمه های کلیدی دیگه ای هم تو این دسته جا میگیرند. این متغیرها معمولا در Code segment حافظه و در زیربخش const. قرار میگیرن.
مورد سوم از موارد فوق اندازه و علامت دار یا بی علامت بودن متغیر رو مشخص میکنه. کلماتی از قبیل signed ,short ,long و … از این دست هستند.
آخرین مورد هم مدت زمان باقی موندن متغیر در حافظه و همین طور محدوده دسترسی به متغیر رو مشخص میکنه. چهار مورد مهم تو این دسته قرار میگیرن:
این کلمه مشخص میکنه که این متغیر باید در قسمت stack حافظه ذخیره بشه و مقدار دهی براش صورت بگیره. متغیرهایی که Storage class براشون تعریف نمیشه به صورت پیش فرض از همین دسته در نظر گرفته میشن.
این کلمه میگه که متغیر تعریف شده باید در کل فرایند اجرای پروژه ثابت بمونه و نباید فضایی رو که توی حافظه اشغال کرده ازش گرفته شه به همین خاطر هم طبق توضیحات قبلی بسته به نوع مقدار دهی تو بخش bss یا data از Data segment حافظه ذخیره میشه. فرق مهمی که این نوع داده با داده های سراسری داره اینه که اگه این داده مثلا داخل یه تابع تعریف شه فقط از داخل همون تابع قابل دسترسی هستش و خارج اون نمیشه بهش دسترسی داشت (اگرچه حافظه ای رو که اشغال کرده پس نمیده!)
از این کلمه هم در مواقعی استفاده میشه که یک متغیر سراسری رو بخوایم در فایلی غیر از فایلی که متغیر رو توش تعریف کردیم استفاده کنیم. یه جورایی میشه گفت مفهوم سراسری بودن یه متغیر رو گسترش میده.
این کلمه رو زمانی به کار میبریم که بخوایم داده ای رو به صورت مستقیم در رجیسترهای CPU ذخیره کنیم. بدیهی هستش که چون رجیسترها پرسرعت ترین منابع حافظه در میکروکنترلر ها هستند پس این کار قاعدتا سرعت اجرا رو افزایش خواهد داد ولی این موضوع مشکلاتی رو هم ایجاد میکنه. فرض کنید برای انجام یه عملیات تمام رجیسترهای CPU غیر یکی مشغول باشند و اون یه دونه رو هم شما به این طریق استفاده میکنید. چی میشه؟ اون عملیات به علت اینکه رجیستری برای استفاده نداره انجام نمیشه و اینطوری ممکنه برنامه Performance رو از دست بده. به همین خاطر هم معمولا تو برنامه نویسی ما این کار رو انجام نمیدیم و ترجیح میدیم اینطور بهینه سازی ها رو کامپایلر برامون انجام بده!
در تصویر زیر میتونید مثالی رو مشاهده کنید که از تمام مواردی که تا الان توضیح دادیم نمونه هایی رو داره. نامگذاری متغیرها به نحوی انجام شده که مشخص میکنه هر کردومشون تو کدوم قسمت از حافظه ذخیره میشن:
تا حالا به این فکر کردین که تو یه سیستم کامپیوتری GPU چقدر کارآمد و مهمه ولی به اندازه CPU شناخته شده نیست.یه جورایی همون "مجهولون فی الارض معروفون فی السماء" که میگن! یه حسی بهم میگه کاش بتونم مثه GPU باشم :)
مقالات بیشترسلام
پس volatile چی میشه؟
اونم مگه کلاس ذخیره سازی نیس؟!
بله لطفا در مورد volatile هم توضیح بدید
سلام و ممنون از توضیحاتتون
در قسمت تعریف نوع چه فرقی بین ذخیره سازی متغیر های هم سایز وجود داره (مثلا بین uint_8 و char ) و اینکه مثلا در تابعی که خروجی 8 بیتی دارد از کدام نوع استفاده میکنیم و آیا به جای هم می توان به کار برد یا خیر؟ ممنون
نویسنده شو !
سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.