PDA

View Full Version : سوال: ایا null در حافظه ذخیره میشه؟؟؟



...StacK...
چهارشنبه 27 آذر 1387, 12:59 عصر
به نام حق

فرض کنید ما یک ارایه(رشته ای) از اشاره گر ها داریم مانند زیر:

[char *iran[10

حالا 10 رشته رو به 10 اشاره گر میدیم .... برای اینکه

پایان یک رشته مثل "barnamenevis" مشخص شه از کاراکتر \0 نال استفاده میشه

ایا این کاراکتر در حافظه هم ذخیره میشه یا نه؟؟؟؟

اگر مثلا اشاره گر [0]iran به رشته ی "barnamenevis" اشاره کنه , این رشته در

حافظه به صورت barnamenevis\0 ذخیره میشه(البته هر کاراکتر در یک بایت)

یا در یک رشته که بعد از اخرین کاراکتر رشته , 0\ قرار میگیره .

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


بزارید مسئله رو با یک مثال باز کنم:این کد رو ببینید:(یه برنامه که یه ارایه از اشاره گر تعریف میکنه و چند رشته

رو به اشاره گر ها تخصیص میده و بعد یک رشته از ورودی میخونه و باید تشخیص بده که این رشته وجود داره یا نه...)


#include <stdio.h>
#include <conio.h>
#include <string.h>
#define k 5
int main(void)
{
int dex;
char name[21];
char *list[k]=
{"ali",
"ahmad",
"saeed",
"morteza",
"abolfazl"
};
printf("\n enter a name for search:");
gets(name);
for(dex=0;dex<k;dex++)
if(!strcmp(list[dex],name))
break;
if(dex==k)
printf("\n name<%s> not exist.",name);
else
printf("\n name <%s> exist.",name);
getche();
printf("\n chape address jaee ke esharegar be oonja eshare mikone<%p>:",list[0]);

printf("\n chape mohtaviyate jaee ke pointer be onja eshare mikone:<%s>:",list[4]);

getche();
return 0;
}
به این تابع printf که نوشتم نگاه کنید:


printf("\n chape address jaee ke esharegar be oonja eshare mikone<%p>:",list[0])تصور من از این خط از کد که نوشتم اینه که ادرس اون بایت از حافظه که کاراکتر a رو در خودش داره رو برام چاپ کنه

یعنی ادرس اولین بایت از رشته ali که میشه a ,که با تست برنامه یک ادرس به من داد....

ایا تصور من درست هست؟؟؟ ایا این ادرس همون ادرس a هست؟؟؟

چه جوری این موضوع رو به خودم اثبات کنم.... وقتی به جای %p از %c استفاده میکنم به جای اینکه اون کاراکتر

رو به من نشون بده اولین عدد از همون ادرس یعنی 0 رو به من میده.

حالا برای اینکه بخوام به ادرس چهارمین بایت از رشته ali , با فرض اینکه 0\ باشه دسترسی پیدا کنم و این کاراکتر رو

چاپ کنم باید چیکار کنم؟؟؟؟

خروجی این برنامه به صورت زیر است- وقتی که در این


printf("\n chape address jaee ke esharegar be oonja eshare mikone<%c>:",list[0]);

خط کد از c% استفاده میکنم:



enter a name for search:ali

name <ali> exist.
chape address jaee ke esharegar be oonja eshare mikone<0>:
chape mohtaviyate jaee ke pointer be onja eshare mikone:<abolfazl>:


و خروجی اون زمانی که از p% استفاده میکنم به صورت زیر است:


enter a name for search:ali

name <ali> exist.
chape address jaee ke esharegar be oonja eshare mikone<00421130>:
chape mohtaviyate jaee ke pointer be onja eshare mikone:<abolfazl>:



دوستان لطف کنید یک پاسخ کامل بدید که کاملا منو قانع کنه....و الا تا فردا سکته مغزی میکنم

emad_67
چهارشنبه 27 آذر 1387, 14:46 عصر
اگر مثلا اشاره گر [0]iran به رشته ی "barnamenevis" اشاره کنه , این رشته در

حافظه به صورت barnamenevis\0 ذخیره میشه(البته هر کاراکتر در یک بایت)
بله ذخیره میشه، یعنی رشته شما در حافظه به صورت barnamenevis\0 هست.

این نال برای فهم کامپایلر هست که بدونه به اخر رشته رسیده, یا اینکه در حافظه هم ذخیره میشه؟؟
مسلما برای اینکه کامپایلر بفهمه که انتهای رشته کجاست نیاز داره که اونو در حافظه ذخیره کنه.

ایا تصور من درست هست؟؟؟ ایا این ادرس همون ادرس a هست؟؟؟
بله درست هست.

حالا برای اینکه بخوام به ادرس چهارمین بایت از رشته ali , با فرض اینکه 0\ باشه دسترسی پیدا کنم و این کاراکتر رو

چاپ کنم باید چیکار کنم؟؟؟؟

برای دستیابی به سومین خونه آرایه که همون 0\ هست اینجوری بنویس:


(int)list[0][3]

نمیدونم با c چه جوری میشه چون با c++ من کار کردم. فقط منظورم اینه که شما باید خونه سوم از آرایه رو به عدد تبدیل کنی. عدد چاپ شده 0 هست که نشون دهنده کد اسکی همون 0\ هست.
در مورد سوالات دیگت چون من هیچی c بلد نیسم و خبر ندارم این %c و اینا چه صیغه ای هست، جواب رو دیگر دوستان بهت میدن.

...StacK...
چهارشنبه 27 آذر 1387, 17:18 عصر
مرسی از اینکه به شاگرد خودتون کمک کردید....

C% برای چاپ کاراکتر به کار میره و P% برای چاپ اشاره گر (pointer)

و S% برای چاپ رشته (string)....

حالا وقتی من خواستم کاراکتر 0\ رو چاپ کنم ...اصلا هیچی نشون نداد....

عنایت کنید-خروجی با خط زیر:


printf("\n chape address jaee ke esharegar be oonja eshare mikone<%c>:",list[0][3]);به این صورت هست:

enter a name for search:ali

name <ali> exist.
chape address jaee ke esharegar be oonja eshare mikone< >:
chape mohtaviyate jaee ke pointer be onja eshare mikone:<abolfazl>:



مطمئنا برنامه هیچ اشکالی نداره , برای اینکه بخاد این کاراکتر رو چاپ نکنه چون

وقتی من میخوام کارکتر سوم رو یعنی (i) از رشته ali رو چاپ کنم -خروجی به درستی

نمایش داده میشه:


printf("\n chape address jaee ke esharegar be oonja eshare mikone<%c>:",list[0][2]);خروجی:


enter a name for search:ali

name <ali> exist.
chape address jaee ke esharegar be oonja eshare mikone<i>:
chape mohtaviyate jaee ke pointer be onja eshare mikone:<abolfazl>:


مگر اینکه خاصیت کاراکتر NULL به گونه ای باشه که با فرمت C% نشون داده نشه که بعید میدونم اینگونه باشه

چون بالاخره یک کاراکتر هست...

نظر شما و دیگر دوستان چیه؟؟؟

emad_67
چهارشنبه 27 آذر 1387, 17:55 عصر
حالا وقتی من خواستم کاراکتر 0\ رو چاپ کنم ...اصلا هیچی نشون نداد....خوب null توی خروجی مثل یه space هست. شما مثال رو جوری تغییر بده که بعد از چاپ null یه جمله دیگه هم نشون داده بشه، بعد میبینی که بینش یه فاصله میفته. البته کد اسکی space عدد 32 هست که با این نباید اشتباه گرفته بشه.

...StacK...
چهارشنبه 27 آذر 1387, 18:59 عصر
کاملا درسته...
--------------------------------------------------------------------------

و اون موردی که گفتم با C% عدد 0 رو نشون میده به این خاطر بوده که من هیچ کاراکتری

رو مشخص نکرده بودم و 0 منظور اولین رقم از اون ادرس حافظه رو به من برمیگردوند...

و الا با فرمت S% خروجی صحیح رو میده...

(بازم اگر کسی نظری غیر از این داره ممنون میشم مطرح کنه...)

--------------------------------------------------------------------------

بازم تشکر میکنم از شما استاد گرامی.(emad_67)

deopen
پنج شنبه 28 آذر 1387, 15:46 عصر
کاملا با همگی موافقم, NULL در حافظه ذخیره میشود . شاخصی است برای رشته های کارکتری , اگر NULL در انتهای رشته نباشد در واقع رشته کامل نیست زیرا پایانی در حافظه برای آن مشخص نشده است , در برنامه زیر ثابت میشود که NULL وجود دارد :



#include<iostream>
using std::cin;
using std::cout;
using std::endl;
int main() {
char b[]="hi";
cout<<"strCHAR : "<<b<<endl;
cout<<"size of strCHAR : "<<sizeof(b)<<endl;
//3 byte or 3 char,1=h,2=i,3=NULL
cin.get();
return 0;
}


برنامه زیر NULL را با 'n\' عوض کرده است و میبینیم که رشته را تا کجا(بیشتر از مقدار تعیین شده) ادامه یافته است.



#include<iostream>
using std::cin;
using std::cout;
using std::endl;
int main() {
char b[]="hi";
cout<<"befor replace NULL : "<<b<<endl;
b[2]='\n';
cout<<"after replace NULL : "<<b<<endl;
cin.get();
return 0;
}


برنامه زیر بیشتر از مقداری که برای رشته تعیین شده بود پیشرفته است ولی در آخر رشته NULL اضافه شده است,مشکلی پیش نمیاد زیرا رشته کامل است ولی در ترتیب حافظه مشکل بوجود آمده و برنامه اقدام به overwright کرده است, و وقتی در حافظه چیزی نوشته شود به مشکل بر میخوریم(برای تست در آخر برنامه کارکتری را وارد کنید اینتر هم یک کارکتر است).



#include<iostream>
using std::cin;
using std::cout;
using std::endl;
int main() {
char b[]="hi";
cout<<"befor overwight : "<<b<<endl;
b[2]='N';
b[3]='U';
b[4]='L';
b[5]='L';
b[6]=NULL;
cout<<"befor overwight : "<<b<<endl;
cin.get();
return 0;
}