PDA

View Full Version : سوال: مقادیر Ch بعد از اجرای دستورات زیر کدام است؟



complexcoding
سه شنبه 13 تیر 1391, 20:54 عصر
سلام
مقادیر [0]Ch و [1]Ch بعد از اجرای دستورات زیر کدام است؟
union{
int i ;
;char Ch[2]
}mu;
mu.i=97;
خیلی ممنون از کمکتون

the king
سه شنبه 13 تیر 1391, 21:34 عصر
در پردازنده های Intel و سایر پردازنده های سازگار با اون بایت کم ارزش قبل از بایت پر ارزش نوشته میشه، مثلا i یک عدد دو بایتی int است و قراره مقدار 97 داشته باشه
که از دو بایت 97 و 0 تشکیل شده، 97 اون بایتی است که ارزش کمتری داره و قبل از بایت 0 نوشته میشه، پس در [ch[0 مقدار 97 و در [ch[1 مقدار 0 قرار می گیره.
به این نکته توجه کنید که این مساله دقیقا بر اساس ساختار ذخیره سازی مقدار عددی در پردازنده پاسخ داده میشه، اگر فرضا در مورد یک پردازنده موتورولا به این سوال
جواب می دادیم درست برعکس می شد که البته معمولا منظور همان شیوه Little Endian ای است که در مورد پردازنده های Intel بکار میره.

complexcoding
سه شنبه 13 تیر 1391, 23:30 عصر
union a{
int i ;
;char Ch[2]
}t;
t.ch[0]=0;
t.ch[1]=1;
printf("%d",t.i);

این چگونه جواب 256 می شود؟

the king
سه شنبه 13 تیر 1391, 23:57 عصر
به بایت کم ارزش که [ch[0 ئه مقدار 0 داده و به بایت پر ارزش که [ch[1 ئه مقدار 1. پس مقداری که در i قرار گرفته یک عدد 16 بیتی (دو بایتی) است
که بایت کم ارزش اش 0 است و بایت پر ارزش اش 1
هر بایت هم که 8 بیته، مقداری که در i قرار گرفته رو بصورت باینری اینجوری می نویسیم، هر 8 بیت جدا 00000000 00000001
حالا اگر شما با ماشین حساب عدد باینری 0000000100000000 رو به مبنای 10 (دسیمال) تبدیل کنید میشه 256
برای ساده تر شدن تبدیل یادتون باشه، هر بایت بعدی ارزش اش 256 برابر بایت قبل از خودشه. یعنی اگر بایت کم ارزش 4 و بایت پر ارزش 5 باشه، عدد دو بایتی
که از کنار هم قرار دادن این دو تا بایت ایجاد میشه برابر با 4 + (256 * 5) یعنی 1284
در اون مثال هم می شد 0 + (256 * 1) یعنی 256

Ananas
پنج شنبه 15 تیر 1391, 01:04 صبح
در پردازنده های Intel و سایر پردازنده های سازگار با اون بایت کم ارزش قبل از بایت پر ارزش نوشته میشه، مثلا i یک عدد دو بایتی int است و قراره مقدار 97 داشته باشه
که از دو بایت 97 و 0 تشکیل شده، 97 اون بایتی است که ارزش کمتری داره و قبل از بایت 0 نوشته میشه، پس در [ch[0 مقدار 97 و در [ch[1 مقدار 0 قرار می گیره.
به این نکته توجه کنید که این مساله دقیقا بر اساس ساختار ذخیره سازی مقدار عددی در پردازنده پاسخ داده میشه، اگر فرضا در مورد یک پردازنده موتورولا به این سوال
جواب می دادیم درست برعکس می شد که البته معمولا منظور همان شیوه Little Endian ای است که در مورد پردازنده های Intel بکار میره.
سلام.
در مورد این چطور؟

struct TVec3D
{
union
{
struct
{
float x, y, z;
};
float f[3];
};
};

struct TMatrix_3x3
{
union
{
struct
{
float _11, _12, _13;
float _21, _22, _23;
float _31, _32, _33;
};
TVec3D v[3];
};
};

اگه ما همچین ساختمانهایی داشته باشیم اونوقت تو پردازنده های مختلف موقع مقدار دهی ممکنه برنامه متفاوت عمل کنه؟

the king
پنج شنبه 15 تیر 1391, 01:42 صبح
نه، در مثال اول تون f یک آرایه است، ترتیب در آرایه در پردازنده های مختلف که فرقی نمی کنه، به هر حال اول [f[0 قرار می گیره که x است و
بعد [f[1 که y است و بعد هم [f[2 که z است. این ارتباطی با Little Endian و Big Endian نداره. اون مربوط به نحوه ذخیره سازی یک عدد
چند بایتی بود، نه یک آرایه متشکل از چند عدد مجزا.

تنها یک مساله هست، در این مثال شاید مهم نباشه اما در بعضی struct ها تاثیر داره، البته بیشتر مربوط به کامپایلره تا پردازنده.
در استاندارد زبان ++C / C مشخص نشده که آیا کامپایلر Align رو در آدرس دهی حافظه برای فیلد ها رعایت می کنه یا نه.
اگر فرضا Align چهار بایتی در حافظه رعایت بشه، ممکنه بعد از یک متغیری که یک بایت طول داشته، سه بایت خالی بدون استفاده رها کنند
تا در مجموع فضای اشغال شده مضربی از 4 باشه. اینطوری آدرس شروع هر فیلد در حافظه مضربی از 4 بایت میشه.
اگر دقت کرده باشید در ساختار API ویندوز، نوع فیلد های داخل struct و ترتیب شون رو طوری انتخاب کرده اند که Align 4 و بدون Align نتیجه
یکسانی داشته باشند. یعنی فرضا قراره بعد از یک فیلد WORD یک DWORD قرار بگیره، بجای یک WORD که هر کدوم دو بایتی هستند دو تا WORD
پشت سر هم قرار می دهند تا در مجموع 4 بایت بشوند. اینطوری در ارتباط با کامپایلر ها و زبان های برنامه نویسی مختلف مشکل پیش نمیاد.

Ananas
پنج شنبه 15 تیر 1391, 09:28 صبح
نه، در مثال اول تون f یک آرایه است، ترتیب در آرایه در پردازنده های مختلف که فرقی نمی کنه، به هر حال اول [f[0 قرار می گیره که x است و
بعد [f[1 که y است و بعد هم [f[2 که z است. این ارتباطی با Little Endian و Big Endian نداره. اون مربوط به نحوه ذخیره سازی یک عدد
چند بایتی بود، نه یک آرایه متشکل از چند عدد مجزا.

خوب چه فرقی بین عدد صحیح و یا اعشاری هست؟ منظورتون اینه که برای هر 4 بایت ترتیب عوض میشه؟ اگه اینطور هم باشه بازم خیلی بده نتیجه برنامه ها خیلی عوض بدل میشه که! تو اینجور برنامه ها اصلا نمیشه اطمینان کرد برنامه درست اجرا بشه.



تنها یک مساله هست، در این مثال شاید مهم نباشه اما در بعضی struct ها تاثیر داره، البته بیشتر مربوط به کامپایلره تا پردازنده.
در استاندارد زبان ++C / C مشخص نشده که آیا کامپایلر Align رو در آدرس دهی حافظه برای فیلد ها رعایت می کنه یا نه.
اگر فرضا Align چهار بایتی در حافظه رعایت بشه، ممکنه بعد از یک متغیری که یک بایت طول داشته، سه بایت خالی بدون استفاده رها کنند
تا در مجموع فضای اشغال شده مضربی از 4 باشه. اینطوری آدرس شروع هر فیلد در حافظه مضربی از 4 بایت میشه.
اگر دقت کرده باشید در ساختار API ویندوز، نوع فیلد های داخل struct و ترتیب شون رو طوری انتخاب کرده اند که Align 4 و بدون Align نتیجه
یکسانی داشته باشند. یعنی فرضا قراره بعد از یک فیلد WORD یک DWORD قرار بگیره، بجای یک WORD که هر کدوم دو بایتی هستند دو تا WORD
پشت سر هم قرار می دهند تا در مجموع 4 بایت بشوند. اینطوری در ارتباط با کامپایلر ها و زبان های برنامه نویسی مختلف مشکل پیش نمیاد.
همینطوره، من قبل از تعریف اینطور struct ها از عبارت زیر استفاده میکنم تا با حذف فضای اضافی ساختمان رو فشرده کنه :

#pragma pack(push, 1)

و یا :

#pragma pack(push, 4)

برای 4 بایت.. 4 بایت.

the king
پنج شنبه 15 تیر 1391, 16:55 عصر
متاسفانه در استاندارد زبان های ++C / C یکسری ابهامات هست. فرضا مشخص نشده که انواع داده ای مختلف دقیقا چند بایتی اند،
حتی ترتیبی که در تفسیر عبارات باید بکار برده بشه هم مشخص نشده. اون مواردی هم که اعلام میشه مربوط به کامپایلره، نه استاندارد زبان.
به همین دلیل نتیجه اجرای برنامه هم به پردازنده ای که اجرایش می کنه بستگی داره و هم کامپایلری که کد رو کامپایل کرده. توابع و کتابخانه های
غیر استاندارد هم که بماند. البته اگر کد خیلی با دقت نوشته بشه میشه از موارد ابهام آمیز اجتناب کرد.