زبان برنامه نویسی سی/تبدیل و جایگزینی دادهها: تفاوت میان نسخهها
محتوای حذفشده محتوای افزودهشده
بدون خلاصۀ ویرایش |
جزبدون خلاصۀ ویرایش |
||
خط ۱۰۰:
با کامپایل کردن قطعه کد بالا ، با هشداری نظیر : warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
رو به رو خواهید شد ؛ اما برنامه کامپایل میشود . در صورت اجرای برنامه با مقادیر آشغال و زباله ( garbage value ) مواجه خواهید شد ( مقادیر پرت و پلا که نسبت و ارتباطی با آنچه متغیر اشاره شده یعنی c1 در خود جای داده ندارند و در هر بار احضار با مقدار دیگری رو به رو میشوید ) . در قطعه کد بالا ، یک کاراکتر ( c1 ) مقدار و موجودی h را در خود ذخیر کرده است و یک کیلوبایت حجم دارد ؛ کاراکتر دوم اشارهگر است و به کاراکتر c1 اشاره میکند و باز هم یک بایت حجم دارد و در نهایت iptr یک اشارهگر به اشارهگر از نوع صحیح است که در سیستمهای ۶۴ بیتی ، ۴ بایت است و در سیستمهای ۳۲ بیتی قدیمی ، ۲ بایت ؛ بنابراین با اشاره iptr به نوع ناسازگار هم تبدیل مشکل پیدا میکند و هم اینکه فضایی که به آن اشاره میکند از فضایی که باید اشاره کند بزرگتر است و کامپایلر به همین منظور به شما هشدار میدهد
به مثال زیر دقت کنید :
خط ۱۳۷:
{{پایان چپچین}}
در قطعه کد بالا یک متغیر از نوع صحیح بلند با نام ln مقدار 514228935 را در خود ذخیره میکند ، سپس یک متغیر اشارهگر از نوع صحیح بلند با نام lnptr به آن اشاره میکند . در انتها در تابع کتابخانهای printf آرگومان خود را از نوع صحیح معمولی تعیین میکنیم و به آن اشارهگر lnptr را که به عنوان اشارهگر صحیح معمولی کست کردهایم که آن را غیر مستقیم نیز نمودهایم تا مقدار اشاره شده را باز گرداند ، ارجاع دادهایم . در سیستمهای ۶۴ بیتی ، قطعه کد بالا بدون هیچ ایرادی کامپایل شده ، اجرا میشود و خروجی درست را نمایش میدهد ؛ اما از آنجایی که در سیستمهای ۳۲ بیتی قدیمی هر int فقط ۲ بایت است ، مقدار ذخیره شده در ln قابل ذخیره در صحیح معمولی نیست ؛ برای همین با اعداد دیگری مواجه خواهید شد ! به همین ترتیب اگر مقدار خود را در همین قطعه کد بالا و در سیستم ۶۴ بیتی خودمان به 5142289356215 تغییر دهیم ، با اعداد و مقادیر دیگری رو به رو خواهیم شد . بنابراین در کست کردن اشارهگرها نیز باید دقت کنید که اگر نوع داده کست شده ، کوچکتر از نوع داده اصلی باشد و مقداری که در آن ذخیره شده در نوع دادهای که میخواهیم کست کنیم جا نشود یا مقادیری از دست میروند یا با آدرسها و مقادیر اشتباهی و زباله رو به رو خواهیم شد . از سویی دیگر ، اگر نوع داده اصلی از نوع داده کست شده ، کوچکتر باشد ( یعنی نوع داده کست شده بزرگتر باشد ) اشارهگر به خانههایی دیگری اشاره خواهد کرد و باز با مقادیر زباله رو به رو خواهیم شد
اگر مبحث نوع داده پوچ را به یاد داشته باشید ، گفتیم که اشارهگر پوچ نمیتواند غیر مستقیم شود مگر آنکه کست شود ( نقش نوع داده دیگری که جز نوع پوچ است را ایفا کند ) . اشارهگرهای پوچ درست مثل اشارهگرهای معمولی کست میشوند و قوانینی که در مورد کست کردن اشارهگرها گفته شد در مورد اشارهگرهای پوچ (void pointers) نیز صادق است . سعی کنید همواره اندازه نوع دادهای که اشارهگر پوچ به آن اشارهکرده با اندازه دادهای که قرار است کست شود ، برابر باشد تا نه فضای اضافی اشغال شود و یا خطایی ایجاد شود و نه مقداری از دست برود
|