PDA

View Full Version : سوال: چند تا سوال در مورده سی



jeson_park
دوشنبه 09 شهریور 1388, 00:55 صبح
سلام
چند تا سوال داشتم
1-در مورد sizeof توضیح بدین
به چه درد می خوره؟؟این که فضای اشقال شده رو اعلام میکنه به چه کاری میاد میشه مثال بزنید؟؟
2-فرق #defin با const چیه؟؟
یعنی اگه یه ثابت رو با دستور پیش پردازنده تعریف کنیم چه مزایایی نسبت به اعلام با
const داره؟؟
3- این تابت ها که در هدر limit.h هستن چه کاربردی دارن؟؟
CHAR_BIT
CHAR_MAX
LONG_MAX
LONG_MIN
ULONG_MAX
LLONG_MAX
LLONG_MIN
ULLONG_MAX
4-اپراتور آدرس(&) که در اول یک متغیر گذاشته میشه به چه درد می خوره؟؟
مثل این
scanf("%f", &salary);

clover
دوشنبه 09 شهریور 1388, 02:25 صبح
سلام دوست عزیز

1 ) عملگر sizeof یک عملگر زمان ترجمه ( اجرا ) هست که برای محاسبه طول یک نوع یا متغیر به کار میره . کاربردش بیشتر در مساله قابلیت حمل کد هست . مثلا ممکنه طول نوع int از ماشینی به ماشین دیگه متفاوت باشه . مثلا برای تخصیص حافظه به صورت پویا با استفاده از تابع ()malloc

2 ) وقتی شما از کلمه کلیدی const استفاده می کنید در واقع متغیری تعریف کردید که مقدارش قابل تغییر نیست اما مثل هر متغیر دیگه ای دارای آدرسی هست و فضایی هم اشغال می کنه ( و در کل تمام خصوصیات یک متغیر را دارد ) اما با استفاده از دستور define# شما به پیش پردازنده دستور میدید که کدتونو تغییر بده ، به فرض با دستور :

#define MAX_SIZE 10
هر جایی که در کدتون از MAX_SIZE استفاده کرده باشید با 10 جایگزین خواهد شد و با دستور :

#define MAX_SIZE 10;
هر رخداد MAX_SIZE در کد شما با رشته ;10 جایگزین میشه ، در واقع رشته دوم هر چیزی که باشه ( حتی یک قطعه کد ) عینا در کد شما جایگزین میشه . ( در واقع MAX_SIZE یک ماکرو هست نه یک ثابت ، اما چون کاربردی مشابه ثابت ها داره به عنوان یه ثابت شناخته میشه )

4 ) دقیقا وظیفه ی خودش رو انجام میده ، یعنی آدرس متغیر salary را مشخص می کنه . توابع ()printf و ()scanf برای نوشتن کاراکتر های فرمت از آدرس متغیر ( پارامتر ارجاعی ) استفاده می کنند .

jeson_park
دوشنبه 09 شهریور 1388, 02:33 صبح
دوستان کسی هست واضح تر بگه؟؟

deopen
دوشنبه 09 شهریور 1388, 10:48 صبح
وقتی شما از کلمه کلیدی const استفاده می کنید در واقع متغیری تعریف کردید که مقدارش قابل تغییر نیست اما مثل هر متغیر دیگه ای دارای آدرسی هست و فضایی هم اشغال می کنه ( و در کل تمام خصوصیات یک متغیر را دارد ) اما با استفاده از دستور define# شما به پیش پردازنده دستور میدید که کدتونو تغییر بدهد
دوستمون خیلی کامل توضیح دادند

نقل قول از How To Program Cpp
ضمیمه شماره 3 (پیش پردازش)

" یک عیب متغیرهای const این است که آنها ممکن است نیازمند مکانی از حافظه به اندازه نوع داده خود باشند ; ثابت های نمادین به هیچ وجه حافظه اضافی نیاز ندارند."

بله و یکی از کاربردهای define# جلوگیری از تعریف چند باره ی یک کلاس و اضافه کاری هست , برای مثال :



#ifndef classO
#define classO

class classO {

{
#endif

در کد بالا ifndef به معنای if no define هست یعنی اگر تعریف نشده بود بدنه ی آن تا endif اجرا میشود.

همچنین کاربرد دیگر define برای ایجاد ماکروها هست که معمولا در کدهای C از آن استفاده می شد اما حالا با توابع inline میتوان output بهتری گرفت.


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


double array[20];
cout<<sizeof(array)
output:: 160
همونطور که اشاره کردم اندازه آرایه را بر حسب بایت برمی گرداند هر double به اندازه 8 بایت فضا اشغال میکند و آرایه 20 تایی آن 160 بایت فضا اشغال میکند , حال ما میتوانیم تعداد عناصر آرایه را برگردانیم :


double array[20];
cout<<sizeof(array)/sizeof(double)


output:: 20
با توجه به این که (sizeof(double اندازه یک double را برمیگرداند ما با این ترفند میتوانیم تعداد عناصر آرایه را مشخص کنیم.
این تابع یک مقدار از نوع size_t بر میگرداند که در اکثر ماشینها نوع int بدون علامت یعنی اعداد صحیح مثبت می باشد.

مهم ترین نکته ای که دوستمون هم بهش اشاره کرد اینه که size of یک عملگر زمان کامپایل است یعنی شما نمیتوانید در زمان اجرا از آن استفاده کنید مثلا نمی تونید از اندازه آرایه یا متغیری که در زمان اجرا تغییر بعد یا اندازه داده مطلع بشید . به همین دلیل بیشتر موارد استفاده ی آن همان چیزی هست که دوستمون clover گفت.


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

Saeed_m_Farid
دوشنبه 09 شهریور 1388, 11:37 صبح
در تکمیل صحبت های clover : (البته کاش سوالاتون رو تو تاپیکهای جداگانه می پرسیدید)


===============================



1-در مورد sizeof توضیح بدین
به چه درد می خوره؟؟این که فضای اشقال شده رو اعلام میکنه به چه ماری میاد میشه مثال بزنید؟؟



همیشه اینطوری نیست که شما بدونید اندازه متغیر یا نوع تون چقدره، مثلاً وقتی قراره بافر هایی از بلاک های یک نوع (struct) که شامل انواع اشاره گر داخلش هست (برای آرایه های پویا) رو از یه فایل بخونید، باید به fread بگید که اندازه بافرهایی که باید بخونه چقدره و یا حتی وقتی قرار به یه آرایه پویا اندازه ای متغیر (هونطورکه clover گفت با malloc) بدید؛ دو تا مثال برای این دو مورد که گفتم (البته کل کد رو میارم که تکه تکه نشه، شما قسمتی رو که بدردت میخوره ببین) :

یه مثال ساده از MSDN برای درک تفاوت اندازه آرایه و اندازه محتویاتش:

// expre_sizeof_Operator.cpp
// compile with: /EHsc
#include <iostream>

size_t getPtrSize( char *ptr )
{
return sizeof( ptr );
}

using namespace std;
int main()
{
char szHello[] = "Hello, world!";

cout << "The size of a char is: "
<< sizeof( char )
<< "\nThe length of " << szHello << " is: "
<< sizeof szHello
<< "\nThe size of the pointer is "
<< getPtrSize( szHello ) << endl;
}






برای کاربرد آرایه پویا و خوندن از فایل :

/* fread example: read a complete file */
#include <stdio.h>
#include <stdlib.h>
int main ()
{
FILE * pFile;
long lSize;
char * buffer;
size_t result;
pFile = fopen ( "myfile.bin" , "rb" );
if (pFile==NULL)
{
fputs ("File error",stderr);
exit (1);
}
// obtain file size:
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);
// allocate memory to contain the whole file:
buffer = (char*) malloc (sizeof(char)*lSize);
if (buffer == NULL)
{
fputs ("Memory error",stderr);
exit (2);
}
// copy the file into the buffer:
result = fread (buffer,1,lSize,pFile);
if (result != lSize)
{
fputs ("Reading error",stderr);
exit (3);
}
/* the whole file is now loaded in the memory buffer. */
// terminate
fclose (pFile);
free (buffer);
return 0;
}




===============================



2-فرق #defin با const چیه؟؟
یعنی اگه یه ثابت رو با دستور پیش پردازنده تعریف کنیم چه مزایایی نسبت به اعلام با
const داره؟؟



مقادیر ثابت (const) در محدوده حافظه هستند و مستعد تغییر، زیرا در زمان اجرا (runtime) معنی پیدا می کنند و تغییرات سهوی هم میتونه شامل هر بلاکی از حافظه بشه؛ بعنوان نمونه در صورت buffer overrun شدن در محدوده ثابت مورد نظر، و یا wild pointer ها و ... امکان تغییر و ایجاد شرایط پیش بینی نشده برای برنامه های حساس هست. در صورتیکه محدوده پیش پردازنده ها (preprocessor) فایل هست و این شرایط برای اونها صدق نمی کنه؛ بنابراین در برنامه های سیستمی و مثلاً درایورها، سیستمهای همزمان (Realtime) و ... بهتره برای موارد حساس از این ذستورات استفاده بشه.


یه کاربرد دیگه هم برای پیش پردازنده ها (از جمله define#) قابلیت استفاده در کامپایل شرطی هست، چیزی که بسیار در مورد قابلیت حمل برنامه روی سیستم عامل های مختلف و شرایط سخت افزاری متفاوت مفید خواهد بود.

===============================



3- این تابت ها که در هدر limit.h هستن چه کاربردی دارن؟؟
CHAR_BIT
CHAR_MAX
LONG_MAX
LONG_MIN
ULONG_MAX
LLONG_MAX
LLONG_MIN
ULLONG_MAX

حداقلش اینه قابلیت خوانایی برنامتون رو افزایش میدن و از طرف دیگه کدتون رو قابل حمل روی کامپایلرهای مختلف خواهند کرد؛ برای اینکه معنی اونها رو هم بدونید میتونید به لینک زیر مراجعه کنید :
Sizes of integral types (http://www.cplusplus.com/reference/clibrary/climits/)


===============================


4-اپراتور آدرس(&) که در اول یک متغیر گذاشته میشه به چه درد می خوره؟؟
مثل این



scanf("%f", &salary);

برای دیدن کاربردها و نحوه کار & در ارسال آدرس متغیر در پارامترهای تابع، دنبال "پارامتر ارجاعی" یا "Call by reference" تو همین سایت بگردید، اینجا (http://www.cplusplus.com/doc/tutorial/functions2/)هم توضیح کاملی در مورد انواع پاس دادن پارامترها به توابع میتونید مشاهده کنید.
برای مشاهده کاربردهای & میتونید به اینجا (http://www.hermetic.ch/cfunlib/ast_amp.htm)هم مراجعه کنید.
برای مشاهده نحوه کار scanf میتونید اینجا (http://www.cppreference.com/wiki/c/io/scanf)رو ببینید.
موفق باشید.

Saeed_m_Farid
دوشنبه 09 شهریور 1388, 11:43 صبح
من این پست (http://barnamenevis.org/forum/showpost.php?p=794181&postcount=4)رو از deopen ندیدم، واسه چند تا سوال ساده خیلی طوالانی شد پست هامون!!!