سلام به همه
آقا میخواستم ببینم وقتی مثلا من یه متغیر از نوع Long که تعریف میکنم بعد یه عدد مثلا 12345678 رو توش قراز میدم این عدد به چه صورت در این 4 بایت حافظه ذخیره میشه ؟
همونطور که میدونید متغیر های long دارای 32 بیت هستند ( که میشه 4 بایت ) کوچکترین تعداد بیت های قابل آدرس دهی در ماشین هایی که ما از شون استفاده میکنیم 1 بایت هست ( یعنی به ازای هر بایت یک آدرس داریم ) پس باید این عدد رو به شکل 4 بایت پشت سر هم در حافظه ذخیره کنیم .
نکته بسیار مهمی که وجود داره اینه که ترتیب این بایت ها در حافظه چطوره . برای این منظور دو نوع مکانیسم ذخیره وجود داره :
1 - Little-endian که در این روش بایت های بالایی در آدرس های بالاتر قرار میگیرند . مثلا همون عدد 12345678 در مبنای 16 میشه 00BC614E ( صفرها رو برای 8 بایت شدن اضافه کردم ) . حالا زمانی که میخواییم اونو توی حافظه بشکل long ذخیره کنیم ( مثلا آدرس ما از 1024 شروع میشه ) اینطور باید عمل کنیم :
در آدرس 1024 ---- > 4E
در آدرس 1025 ---- > 61
در آدرس 1026 ---- > BC
در آدرس 1027 ---- > 00
2 - Big-endian که در این روش بایت های بالایی در آدرس های پایین تر قرار میگیرند . مثال بالا رو تکرار میکنیم . زمانی که میخواییم اونو توی حافظه بشکل long ذخیره کنیم ( بازهم آدرس ما از 1024 شروع میشه ) اینطور باید عمل کنیم :
در آدرس 1024 ---- > 00
در آدرس 1025 ---- > BC
در آدرس 1026 ---- > 61
در آدرس 1027 ---- > 4E
کامپیوتر های ما از Little-endian استفاده میکنند پس اون روش بالا نشون میده که چطور یک عدد از نوع long در حافظه ذخیره میشه . لینک های زیر اطلاعات خوبی رو ارائه میدن به شما :
http://en.wikipedia.org/wiki/Little_endi..._in_memory
http://www.codeguru.com/vb/gen/vb_misc/a...php/c7495/
سلام آقا خیلی خیلی ممنون بایت توضیحات و لینکها
Mamad2003 نوشته است:مثلا همون عدد 12345678 در مبنای 16 میشه 00BC614E ( صفرها رو برای 8 بایت شدن اضافه کردم ) .
این جا یعنی عدد 12345678 با توجه به اینکه مقدار هکز اون میشه BC614E (6 کاراکتر) میتونیم بگیم 3 = 2/6 بایت حاظه اشغال میکنه ؟؟؟
شرمنده اگه سوالام خیلی مبتدیانه بود
نه !
وقتی شما یه داده از نوع Long تعریف کردی یعنی 4 بایت از حافظه رو اشغال کردی !! حالا اینجا عدد شما از سه بایت اون استفاده میکنه و در نتیجه بایت چهارم رو صفر پر میکنه . اگر شما عددی بزرگتر داشته باشید اونوقت بایت چهارم هم استفاده میشه . در حالتی دیگه اگر عدد شما خیلی کوچیک باشه ممکنه حتی بایت سوم یا دوم هم صفر باشن و استفاده نشن ولی این به این معنی نیست که عدد شما 1 بایت یا دو بایت اشغال میکنه .
هر عددی از کوچکترین تا بزرگترین ( 2,147,483,648- ....... 2,147,483,647) که شما در یک متغیر از نوع Long ذخیره کنی با هر طول و اندازه ای ، 4 بایت از حافظه رو اشغال میکنه !
اگر شما مطمعنی که عددت خیلی کوچیکه باید از نوع کوچکتر مثل Integer یا byte استفاده کنی تا هم حافظه کمتری اشغال بشه و هم کارایی بیشتر باشه !
ممنون اما ظاهرا من یه خورده سوالمو بد پرسیدم
سوالم این بود که مثلا من یه عدد دارم میخوام ببینم برای ذخیره سازی اون باید متغییر رو از چه نوعی تعریف کنم ( با فرض اینکه من میدونم متغییر Byte یک بایت و Integer دو بایت , Long چهار بایت حافظه رو به خودشون اختصاص میدن ولی نمیدونم که مثلا متعییر از نوع Integer حداکثر تا 32767 رو میشه درونش ذخیره کرد )
یعنی ببینم عدد من چند بایت حافظه برای ذحیره شدن احتیاج داره که متناسب با اون نوع متغییر رو تشحیص بدم ؟
یعنی به طور خلاصه عددی مثل 32780 چند بایتیه ؟ یا اگه راه داره بفهمم چند بیته ؟
و ممنون از اینکه وقت میزارید و جواب من مبتدی رو میدید ...
مثلا متغیری از نوع integer دو بایت یا 16 بیت از حافظه رو اشغال میکنه و شما میخوای ببینی که تا چه عددی میتونی داخل این متغیر ذخیره کنی . همونطور که میدونی ما دو نوع بیت داریم 0 و 1 و همینطور 16 خونه خالی .
طبق ریاضیات این میشه ترکیب دو حالت ( 0 و 1 ) در 16 فرم مختلف با امکان جابجایی . فرمول ما هست [تعداد حالات ترکیب] به توان [فرم های ترکیب] و این یعنی 2 به توان 16 .
پس شما تا عدد 2 به توان 16 میتونی توی 16 بیت ذخیره کنی (مثبت ) نکته مهم اینه که توی وی بی ما اعداد بی علامت یا فقط مثبت نداریم (غیر از byte ها ) پس نصف این ترکیبات میشه برای اعداد منفی . با توجه به اینکه 2 به توان 16 میشه 65536 پس خیلی راحت میشه اینطوری گفت :
32767 تا عدد مثبت + 1 عدد صفر + 32768 تا عدد منفی = جمعا 65536 ترکیب
در نتیجه متغیر های از نوع integer میتونن عددی بین 32,768- تا 32,767 رو توی خودشون جا بدن !
** حالا شما یه عدد دارای و مخوای بفهمی چند بیته یا بایته . من مثالی که خودت زدی رو تکرار میکنم همون عدد 32780 . کافیه که این عدد رو به مبنای 16 تبدیل کنی که میشه 800C . هر کدوم از ارقام یک عدد در مبنای 16 دارای طول 4 بیت هستند . اینجا C چهار بیته و هر کدوم از اون صفر ها هم 4 بیت هستند و 8 هم 4 بیته پس کلا میشه 4 ضرب در 4 که میشه 16 بیت یا 2 بایت .
اینکه چه نوع متغییری برای اعداد خودتون انتخاب کنید معمولا با کسب تجربه بدست میاد و کسی این محاسبات رو انجام نمیده . همینطور توابع سیستمی انواع متغیر های ثابتی دارند و شما کافیه که متغیر خودتون رو مطابق با ورودی یا خروجی اون توابع تعریف کنید !
Mamad2003 نوشته است:32767 تا عدد مثبت + 1 عدد صفر + 32768 تا عدد منفی = جمعا 65536 ترکیب
در نتیجه متغیر های از نوع integer میتونن عددی بین 32,768- تا 32,767 رو توی خودشون جا بدن !
** حالا شما یه عدد دارای و مخوای بفهمی چند بیته یا بایته . من مثالی که خودت زدی رو تکرار میکنم همون عدد 32780 . کافیه که این عدد رو به مبنای 16 تبدیل کنی که میشه 800C . هر کدوم از ارقام یک عدد در مبنای 16 دارای طول 4 بیت هستند . اینجا C چهار بیته و هر کدوم از اون صفر ها هم 4 بیت هستند و 8 هم 4 بیته پس کلا میشه 4 ضرب در 4 که میشه 16 بیت یا 2 بایت .
خیلی ممنون از توضیحاتتون
اما من یه جاشو نمیفهمم
اینا رو فهمیدم که چرا 65536 حالت (0 و 1 ) داریم
اما سوال من الان اینه که ما 65536 حالت که 32767 تا برای مثبت هست رو در اختیار داریم اما مگه این عدد 32767
تعداد حالتهای موجود برای قرار گیری صفر و یک ها نیست یعنی 32767 تا عدد میتونیم قرار بدیم حالا 32767
تا عددی که از 2 بایت کمتر باشند ! حالا چه عددهایی از 2 بایت کمترند ! عددهای کوچکتر از 32767 ؟ درسته یا اشتباه میگم ؟
سوال دومم اینه که الان 800C که مقدار هکز 32780 هست میخواد تو حافظه قرار بگیره حالا مثلا C که دارای طول 4 بیت هستش به همون شکل C در حافظه نوشته میشه یا باید به صورت 0 , 1 دربیاد ؟ اگر اینطوره به چه صورت به 0 و 1 تبدیل میشه ؟
یعنی توی این سلول ها چی نوشته میشه ؟
نقل قول: ما سوال من الان اینه که ما 65536 حالت که 32767 تا برای مثبت هست رو در اختیار داریم اما مگه این عدد 32767 تعداد حالتهای موجود برای قرار گیری صفر و یک ها نیست یعنی 32767 تا عدد میتونیم قرار بدیم حالا 32767 تا عددی که از 2 بایت کمتر باشند ! حالا چه عددهایی از 2 بایت کمترند ! عددهای کوچکتر از 32767 ؟ درسته یا اشتباه میگم ؟
من هیچ جایی نگفتم که میتونیم 32767
تا عدد مثبت رو ذخیره کنیم بلکه گفتم که
یک عدد مثبتی رو میتونیم ذخیره کنیم که بین 0 تا 32767 باشه ( این عدد 2 بایت خواهد بود و کوچکتر یا مساوی 32767 باید باشه )
نقل قول: سوال دومم اینه که الان 800C که مقدار هکز 32780 هست میخواد تو حافظه قرار بگیره حالا مثلا C که دارای طول 4 بیت هستش به همون شکل C در حافظه نوشته میشه یا باید به صورت 0 , 1 دربیاد ؟ اگر اینطوره به چه صورت به 0 و 1 تبدیل میشه ؟ یعنی توی این سلول ها چی نوشته میشه ؟
من از شکل مبنای 16 استفاده کردم چون حالت فشرده داره تا مجبور نباشم قطاری از 0 و 1 ها رو اینجا بنویسم و گرنه تو حافظه کامپیوتر همه چیز 0 و 1 هست و کامپیوتر فقط مبنای 2 رو میفهمه !! تمام این اعداد بشکل 0 و 1 در حافظه ذخیره میشن و اونهم به شکل Little-endian . بیت آخر بایت آخر ( اینجا بیت آخر بایت دوم) بیت علامت نام داره که مشخص میکنه عدد ما مثبت هست یا منفی ( 0 برای مثبت و 1 برای منفی ) اعداد مثبت کوچکتر از 32767 باعث میشن که بیت علامت همیشه 0 بمونه و برای همینه که تمام اعداد مثبت ما باید کوچکتر یا مساوی با این عدد باشند تا بدرستی توی حافظه ذخیره بشن .
عدد 32780 بزرگتر از 32767 و نمیشه اونو به درستی توی یه متغیر integer ذخیره کرد (در واقع میشه ذخیره اش کرد چون 2 بایته اما اگر اونو ذخیره کنیم به عنوان یک عدد منفی محسوب خواهد شد چون بیت علامت اون 1 میشه )
( در این عکس عدد ما از آدرس 1024 شروع شده و به شکل little-endian ذخیره شده . این عدد در زمان محاسبه کامپایلر یک عدد منفی و برابر با 32756- خواهد بود )
فکر کنم حالا باید برای شما جا افتاده باشه که چرا نمیتونیم عددی بزرگتر از 32767 در متغیر integer مون ذخیره کنیم با وجود اینکه اعداد بزرگتر از اون هم در 2 بایت جا میشن !!
در زبانهایی مثل زبان C ما میتونیم متغیر های خودمون رو بدون علامت یا unsigned تعریف کنیم و همین به ما این اجازه رو میده که اعداد اینچنینی رو در 2 بایت ذخیره کنیم و نمایش بدیم ( در واقع کامپایلر بیت علامتی در نظر نمیگیره و عدد منفی نخواهیم داشت ) متاسفانه در وی بی همچین امکانی وجود نداره و برای ذخیره چنین عددی مجبوریم از 32 بیت بجای 16 بیت استفاده کنیم .
Mamad2003 نوشته است:فکر کنم حالا باید برای شما جا افتاده باشه که چرا نمیتونیم عددی بزرگتر از 32767 در متغیر integer مون ذخیره کنیم با وجود اینکه اعداد بزرگتر از اون هم در 2 بایت جا میشن !!
در زبانهایی مثل زبان C ما میتونیم متغیر های خودمون رو بدون علامت یا unsigned تعریف کنیم و همین به ما این اجازه رو میده که اعداد اینچنینی رو در 2 بایت ذخیره کنیم و نمایش بدیم ( در واقع کامپایلر بیت علامتی در نظر نمیگیره و عدد منفی نخواهیم داشت ) متاسفانه در وی بی همچین امکانی وجود نداره و برای ذخیره چنین عددی مجبوریم از 32 بیت بجای 16 بیت استفاده کنیم .
درسته دقیقا برام جا افتاد که چرا عدد بزرگتر از 32767 رو نمیتونیم قرار بدیم (اون عکسی که گذاشتی همه چی رو مشخص میکنه )
ایکه در C میتونیم متغییر های خودمون رو بدون علامت تعریف کنیم اما در VB نمیتونیم به کامپایلر هاشون بستگی داره ؟
و اینکه در مورد متغییر های رشته ای هم همین طوره ؟ یعنی فرض کنید ما یه متغییر از نوع String داریم و میخواهیم مثلا کاراکتر a رو درون این متغییر ذخیره کنیم a به صورت 0 , 1 در میاد بعد به صورت Littele-Edition در متغییر قرار میگیره ؟ درسته ؟
در ضمن تبدیل کارکتر ها به صورت 0 , 1 یعنی همون تبدیل به Binary ؟
نقل قول: در C میتونیم متغییر های خودمون رو بدون علامت تعریف کنیم اما در VB نمیتونیم به کامپایلر هاشون بستگی داره ؟
بله ! کامپایلر یا بطور کل زبان وی بی همچین امکانی رو نداره و برنامه نویس مجبوره خودش این رو دستی انجام بده اگر واقعا بهش نیاز داشته باشه .
یه نمونه جمع و تفریق بدون علامت در وی بی به کمک عملگر های بیتی :
http://www.freevbcode.com/ShowCode.asp?ID=4331
نقل قول: و اینکه در مورد متغییر های رشته ای هم همین طوره ؟ یعنی فرض کنید ما یه متغییر از نوع String داریم و میخواهیم مثلا کاراکتر a رو درون این متغییر ذخیره کنیم a به صورت 0 , 1 در میاد بعد به صورت Littele-Edition در متغییر قرار میگیره ؟ درسته ؟
بله . همه چیز به صورت 0 و 1 در میاد و بایت ها هم بشکل little-endian ذخیره میشن . نکته مهم اینه که رشته های وی بی یونیکد هستند یعنی برای هر حرف 2 بایت فضا اشغال میکند .
اینکه رشته ها چطور بصورت 0 و 1 ذخیره میشن ممکنه برای شما سوال باشه .
هر حرف در کامپیوتر های ما یک کد عددی مخصوص به خودش داره که در گذشته به کد ASCII معروف بودن و هر حرف اون فقط 8 بیت یا 1 بایت جا میگیره . طبق همون فرمول ترکیبی که در بالا به شما دادم [2 به توان 8] حالت یا 128 حرف میتونستن با استفاده از کدهای ASCII نمایش داده بشن . این تعداد حرف برای تمام زبانها که حروف بیشتری دارن مثل چینی کافی نبود . پس اومدن و استاندارد جدیدی به نام یونیکد رو ساختند که امروز به ما اجازه میده تمام زبانهای زنده دنیا رو کد بندی کنیم .
جدول ASCII رو میتونی توی لیک مقابل ببینی :
http://www.asciitable.com/
البته نحوه ذخیره شدن string های وی بی 6 در حافظه از یک نوع خاص از داده با نام BSTR استفاده میکنه که توی ویندوز تعریف شده و مکانیسم تقریبا پیچیده ای داره !
نقل قول: در ضمن تبدیل کارکتر ها به صورت 0 , 1 یعنی همون تبدیل به Binary ؟
تبدیل اعداد به صفر و یک میشه تبدیل به Binary . البته در مورد کاراکتر ها در بالا توضیح دادم کد عددی اونها به 0 و 1 تبدیل میشه و توی حافظه نوشته میشه .