PDA

View Full Version : سوال: یک اشاره گر چند بایت رو اشغال میکنه؟؟؟



...StacK...
جمعه 29 آذر 1387, 11:20 صبح
وقتی ما یک اشاره گر حالا از هر نوعی که باشه تعریف میکنیم ...این اشاره گر

چند بایت از حافظه رو برای ذخیره یک ادرس حافظه اشغال میکنه؟؟؟؟

البته فکر نکنم فرقی بین نوع اون اشاره گر باشه ...چون یک اشاره گر

ادرس اولین بایت رو در خودش ذخیره میکنه... درسته؟؟؟

Mehdi Asgari
جمعه 29 آذر 1387, 12:01 عصر
درسته، اشاره گر یک آدرس رو در خودش ذخیره می کنه. خب ، پس چه مقدار از حافظه رو اشغال می کنه ؟
اندازۀ طول آدرس ماشین
اگه ماشین ما 32 بیتی باشه (غالب PC های دنیا) اون وقت هر نوع اشاره گری 4 بایت حافظه (32 بیت) رو اشغال خواهد کرد. فرقی هم نمی کنه اشاره گر به چی باشه ، چون قراره آدرس یه خونه از حافظه رو در خودش نگه داره و برای بیان یک آدرس در یک ماشین 32 بیتی به 32 بیت نیاز داریم.

...StacK...
جمعه 29 آذر 1387, 12:48 عصر
پس زیاد هم به صرفه نیست استفاده از اشاره گرها....جز موارد خاص.

حالا این موضوع تماما به طول ادرس ماشین بستگی داره و اصلا به کامپایلر ربطی نداره؟؟؟

برای مثال در turbo تحت dos و یا visual c++ هیچ فرقی نداره؟؟

این سوال رو پرسیدم چون که در turbo مثلا نوع int 16 بیتی هست ولی در vc 32 بیتی..!!!

و فکر میکنم همین موضوع باعث میشه که خروجی های turbo خیلی خیلی کمتر از vc باشه...!!!

و اینکه میگید 32 بیتی هست منظور همان ثبات های پردازنده هست؟؟؟

Nima_NF
جمعه 29 آذر 1387, 13:45 عصر
کامپایلر رابطه مستقیم با پلتفرمی دارد که می خواهیم برای آن برنامه بنویسیم،
وقتی شما با یک کامپایلر پیشرفته مثل ++Visual C برنامه خود را کامپایل می کنید باید تعیین کنید که برنامه را به 32 بیت کامپایل می کنید یا 64 بیت یا کلا برای چه پردازنده ای، سپس متناسب با آن آدرس ها و طولشان و غیره مشخص می شود و کامپایل انجام می شود.(16 بیت در ++VC منسوخ شده است) پس شما وقتی به صورت پیش فرض کامپایل می کنید همان 32 بیت است. در اینجا باید سیستم عامل نیز پردازنده و برنامه کامپایل شده شما را پشتیبانی کند.

Turbo C هم کد ها را برای پردازنده های 16 بیتی کامپایل می کند، که قابل اجرا در پردازنده های 32 بیتی است. (البته چون در پردازنده های بالاتر نهایت استفاده را نمی کند این عمل به نوعی اتلاف وقت و قدرت پردازنده ها جدید است).

پس نه تنها سیستم عامل شما باید پشتیبانی کند، باید پردازنده نیز آن را پشتیبانی کند(که بله این طول همان محاسبات و اندازه های قابل انجام در رجیسترهایش است). در حال حاضر 16 بیت در پردازنده های بالاتر مانند 32 بیتی پشتیبانی می شود. (backward compatibility)



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

ضمنا در ازای امکاناتی که اشاره گرها می دهند 4 بایت اصلا چیزی نیست که بخواهیم بگوییم بی فایده اند!

...StacK...
جمعه 29 آذر 1387, 14:54 عصر
کاملا این حرف اشتباه است.

منظور من این بود که در هر جا (مثلا برای سهولت در برنامه نویسی) از اشاره گر ها استفاده نکنیم.

illegalyasync
جمعه 29 آذر 1387, 15:25 عصر
اندازۀ طول آدرس ماشین

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

deopen
جمعه 29 آذر 1387, 20:33 عصر
منظور من این بود که در هر جا (مثلا برای سهولت در برنامه نویسی) از اشاره گر ها استفاده نکنیم.

اتفاقا اشاره گر ها برای سهولت در برنامه نویسی ساخته شده اند, شما بخاطر حافظه ای که یک اشاره گر اشغال میکند نباید چنین عقیده ای داشته باشید, اتفاقا اشاره گر ها در بهینه مصرف کردن حافظه بسیار مورد استفاده قرار میگیرند برای مثال ما میتوانیم با توابع مبتنی بر اشاره گر از امنیت توابع انتقال با مقدار و سرعت توابع ارجاعی برخوردار شویم , به تابع زیر نگاه کنید :


void printByValue(const int arr[],int size) {
for (int i=1;i<=size;i++)
cout<<arr[i-1]<<" ";
cout<<endl;
}

کد بالا برای نمایش مقادیر یک آرایه است, این تابع دو آرگومان میگیرد, اولی آرایه ,دومی سایز آرایه , که اولین آرگومان برای ممانعت در تغییر ثابت اعلان شده است, لازم به ذکر است که نام یک آرایه در واقع اشاره گری به اولین عنصر آرایه است (که به خود مقدار رجوع میکند نه به کپی آن), اما آرگومان سایز این تابع در واقع یک کپی از مقدار اصل را در خود نگه میدارد , و کپی یک مقدار گاهی اوقات باعث کندی در روند کار برنامه میشود (در مواردی که مقادیر بزرگ داده ای وجود دارند).


void printByPtr(const int *arr,const int *size) {
for (int i=1;i<=(*size);i++)
cout<<arr[i-1]<<" ";
cout<<endl;
}

اما تابع بالا دارای آرگومان اشاره گر برای سایز آرایه است, و این مانع از ایجاد کپی در تابع میشود و همچنین با ثابت اعلان کردن آن اصل حد اقل دسترسی نیز رعایت شده است.(آرگومان اول این تابع با تابع اولی هیچ فرقی ندارد فقط برای نشان دادن این که نام آرایه و یا اشاره گر به اولین عنصر آن , هر دو یکی هستند , اینگونه تعریف شده است)


هاروی دیتل:
اگر نیازی به ایجاد تغییر از سوی تابع فراخوانده شده در اشیا بزرگ نیست, آنها را با استفاده از اشاره گر هایی به داده ی ثابت یا ارجاع هایی به داده ی ثابت انتقال دهید, تا از مزایای انتقال با ارجاع بهره مند شوید.

به نظر شما بهتر نیست بجای استفاده از آرگومانی که یک کپی از مقدار یا مقادیر را نگه میدارد و اندازه ی خود مقدار اصلی حافظه اشغال میکند از یک اشاره گر به مقدار ثابت استفاده کنیم؟

saeid99
شنبه 30 آذر 1387, 18:39 عصر
سلام یک اشاره گر تا جایی که میدونم 4 بایت رو اشغال میکنه...
در ضمن استفاده از اشاره گرها بطور کامل در یک برنامه احتمال ایجاد خطای منطقی رو زیاد میکنه
البته کسانی که می خوان با اشاره گر کار کنن باید تسلط کافی داشته باشن که به مشکل بر نخورن..