#سی
تایپ void
نشون میده که هیچ مقداری در دسترس نیست. در نتیجه، نمیشه متغیرها یا ثابتها رو با این نوع تعریف کرد.
میتونین از void برای اهداف زیر استفاده کنین:
- در اعلانهای تابع
تابعی که مقدار بازگشتی نداره. برای مثال:
همچنین کلمه کلیدی void تو لیست پارامترهای تابع نشون میده که تابع هیچ پارامتری نداره. برای مثال:
در نتیجه، اگه سعی کنین از فراخوانی این تابع مثل
استفاده کنین، کامپایلر پیام خطا صادر میکنه.
اگه تابع بدون void تو لیست پارامترها اعلان بشه،
کامپایلر C هیچ اطلاعاتی در مورد پارامترهای تابع نداره و قادر به تشخیص صحیح بودن فراخوانی تابع نمیشه.
یعنی تابع رو با هر پارامتری فراخوانی کنیم هیچ خطایی از سمت کامپایلر دریافت نمیکنیم.
از استاندارد C23 این موضوع تغییر کرده و اگه موقع تعریف تابع پارامترها رو خالی بذاریم کامپایلر در نظر میگیره این تابع با هیچ پارامتری فراخوانی نشه و نیازی به نوشتن void بطور صریح وجود نداره. همونطور که توی C++ بوده.
- عبارات (expressions) از نوع void
عبارت void عبارتیه که هیچ مقداری نداره.
برای مثال فراخوانی یه تابع که مقدار بازگشتی نداره، عبارتی از نوع void هست:
با cast یه عبارت
به طور صریح مقدار عبارت، مثل مقدار بازگشتی یه تابع، حذف میشه:
بعضی از linterها بابت استفاده نکردن از عباراتی که مقداری دارن هشدار میدن که خب با تبدیل صریحش به void به linter اعلام میکنیم آگاهانه نمیخوایم از مقدارش استفادهای کنیم.
بنظرم اگه توابع استاندارد رو فاکتور بگیریم تو بقیهی موارد ممکنه روی خوانایی کد هم تاثیر مثبت بذاره.
- اشارهگر به void
اشارهگری از نوع void * نشون دهندهی آدرس یه آبجکت هست، اما نوع اون رو نشون نمیده.
میشه از این اشارهگرهای بدون نوع برای اعلان توابعی استفاده کرد که میتونن روی انواع مختلف آرگومانها عمل کنن، یا یه اشارهگر چندمنظوره رو برمیگردونن.
مثل توابع استاندارد مدیریت حافظه:
میشه یه مقدار اشارهگر void رو به هر نوع اشارهگر دیگهای اختصاص داد، یا برعکس، بدون تبدیل صریح نوع.
احتمالا توی بعضی از کدهای C دیدین که مقدار بازگردانده شده از تابعی مثل malloc رو بطور صریح به تایپ اشارهگر مورد نظر cast میکنن.
توی C نیازی به تبدیل صریح از void * به انواع دیگه وجود نداره. اما توی C++ باید صراحتا cast رو انجام بدیم.
بعضا در صورت نیاز بخاطر سازگاری کد با کامپایلرهای C++ اینکار رو انجام میدن. گاهی هم افراد صرفا از روی تقلید و عادت اینکار رو میکنن.
🚁 Hicte Blog | (smm)
تایپ void
نشون میده که هیچ مقداری در دسترس نیست. در نتیجه، نمیشه متغیرها یا ثابتها رو با این نوع تعریف کرد.
میتونین از void برای اهداف زیر استفاده کنین:
- در اعلانهای تابع
تابعی که مقدار بازگشتی نداره. برای مثال:
void perror(const char *);
همچنین کلمه کلیدی void تو لیست پارامترهای تابع نشون میده که تابع هیچ پارامتری نداره. برای مثال:
FILE *tmpfile(void);
در نتیجه، اگه سعی کنین از فراخوانی این تابع مثل
tmpfile("name.tmp")استفاده کنین، کامپایلر پیام خطا صادر میکنه.
اگه تابع بدون void تو لیست پارامترها اعلان بشه،
FILE *tmpfile();
کامپایلر C هیچ اطلاعاتی در مورد پارامترهای تابع نداره و قادر به تشخیص صحیح بودن فراخوانی تابع نمیشه.
یعنی تابع رو با هر پارامتری فراخوانی کنیم هیچ خطایی از سمت کامپایلر دریافت نمیکنیم.
از استاندارد C23 این موضوع تغییر کرده و اگه موقع تعریف تابع پارامترها رو خالی بذاریم کامپایلر در نظر میگیره این تابع با هیچ پارامتری فراخوانی نشه و نیازی به نوشتن void بطور صریح وجود نداره. همونطور که توی C++ بوده.
- عبارات (expressions) از نوع void
عبارت void عبارتیه که هیچ مقداری نداره.
برای مثال فراخوانی یه تابع که مقدار بازگشتی نداره، عبارتی از نوع void هست:
char filename[] = "memo.txt";
if (fopen(filename, "r") == NULL) perror(filename); // A void expression
با cast یه عبارت
(void)expressionبه طور صریح مقدار عبارت، مثل مقدار بازگشتی یه تابع، حذف میشه:
(void)printf("I don't need this function's return value!\n");بعضی از linterها بابت استفاده نکردن از عباراتی که مقداری دارن هشدار میدن که خب با تبدیل صریحش به void به linter اعلام میکنیم آگاهانه نمیخوایم از مقدارش استفادهای کنیم.
بنظرم اگه توابع استاندارد رو فاکتور بگیریم تو بقیهی موارد ممکنه روی خوانایی کد هم تاثیر مثبت بذاره.
- اشارهگر به void
اشارهگری از نوع void * نشون دهندهی آدرس یه آبجکت هست، اما نوع اون رو نشون نمیده.
میشه از این اشارهگرهای بدون نوع برای اعلان توابعی استفاده کرد که میتونن روی انواع مختلف آرگومانها عمل کنن، یا یه اشارهگر چندمنظوره رو برمیگردونن.
مثل توابع استاندارد مدیریت حافظه:
void *malloc( size_t size );
void free( void *ptr );
میشه یه مقدار اشارهگر void رو به هر نوع اشارهگر دیگهای اختصاص داد، یا برعکس، بدون تبدیل صریح نوع.
int *int_ptr = malloc(sizeof(int));
float *float_ptr = malloc(sizeof(float));
free(int_ptr);
free(float_ptr);
احتمالا توی بعضی از کدهای C دیدین که مقدار بازگردانده شده از تابعی مثل malloc رو بطور صریح به تایپ اشارهگر مورد نظر cast میکنن.
int *ptr;
ptr = (int*)malloc(sizeof(int));
توی C نیازی به تبدیل صریح از void * به انواع دیگه وجود نداره. اما توی C++ باید صراحتا cast رو انجام بدیم.
بعضا در صورت نیاز بخاطر سازگاری کد با کامپایلرهای C++ اینکار رو انجام میدن. گاهی هم افراد صرفا از روی تقلید و عادت اینکار رو میکنن.
🚁 Hicte Blog | (smm)
🔥5👍2❤1
Forwarded from خبرنامهٔ امیرکبیر
بر اساس گزارش اختصاصی رسیده به #خبرنامه_امیرکبیر، عرفان عربی، دانشجوی رشته مهندسی کامپیوتر دانشگاه آزاد بیرجند و از فعالان آزادی اینترنت، به ۵ سال حبس محکوم و این حکم روز جاری در دادگاه انقلاب به صورت شفاهی به وی ابلاغ شد. دادگاه انقلاب، آقای عربی را به اتهاماتی مانند «اجتماع و تبانی» و «تبلیغ علیه نظام» به ۸ سال حبس محکوم کرده که ۵ سال از آن قابل اجرا است. دادگاه همچنین از ابلاغ کتبی حکم خودداری کرده و جزئیات محکومیت تنها به شکل شفاهی به این دانشجو ابلاغ شده است.
عرفان عربی، ۲۰ ساله، دانشجوی کامپیوتر دانشگاه آزاد بیرجند و عضو تیم توسعهٔ سیستمعامل پارچ لینوکس، بهمن ماه سال گذشته پس از احضار توسط وزارت اطلاعات جمهوری اسلامی و ضبط دستگاههای الکترونیکیاش، به اتهاماتی مانند «تبلیغ علیه نظام» و «اجتماع و تبانی برای اقدام علیه امنیت ملی» بازداشت و اواخر فروردین امسال، پس از حدود سه ماه از زندان آزاد شد.
#عرفان_عربی
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9
HICTE Blog
#سی 🚁 Hicte Blog | (smm)
وضعیت کد بالا:
Final Results
30%
Safe 🎉
30%
Overflow 💥
14%
Two overflows 😱
11%
Three overflows 💀
16%
Compiler error 👻
👍3
#سی
تبدیلهای حسابی معمول و ارتقای اعداد صحیح
[قسمت اول]
وقتی دو عملوند از انواع مختلف تو یه عبارت شرکت میکنن، کامپایلر اونها رو به یه نوع مشترک تبدیل میکنه [قبل از اینکه عملیات واقعی انجام بشه]. این قرارداد تو استاندارد C با عنوان تبدیلهای حسابی معمول (Usual Arithmetic Conversions یا به اختصار UAC) شناخته میشه.
پردازندههای مدرن دستورالعملهای جداگانهای برای انواع مختلف داده دارن. دستور جمع اعداد صحیح با دستور جمع اعداد اعشاری کاملاً متفاوت هست. وقتی شما مینویسین:
پردازنده نمیتونه مستقیماً یه
قانون راهنمای این تبدیل ساده هست:
همیشه به سمت نوعی که اطلاعات بیشتری رو حفظ میکنه حرکت کن.
انواع اعشاری اولویت بالاتری از انواع صحیح دارن. توی لیست زیر به ترتیب اولویت تبدیل از بالا به پایین میشه:
این تبدیلها برای:
۱. عملگرهای حسابی
۲. عملگرهای رابطه و برابری
۳. عملگرهای بیتی
۴. عملگر سه تایی (برای عملوندهای دوم و سوم)
توسط کامپایلر اعمال میشن.
🚁 Hicte Blog | (smm)
تبدیلهای حسابی معمول و ارتقای اعداد صحیح
یکی از رفتارهای زبان C که مسئول بسیاری از باگها هست اگه درست درک نشه!
[قسمت اول]
وقتی دو عملوند از انواع مختلف تو یه عبارت شرکت میکنن، کامپایلر اونها رو به یه نوع مشترک تبدیل میکنه [قبل از اینکه عملیات واقعی انجام بشه]. این قرارداد تو استاندارد C با عنوان تبدیلهای حسابی معمول (Usual Arithmetic Conversions یا به اختصار UAC) شناخته میشه.
پردازندههای مدرن دستورالعملهای جداگانهای برای انواع مختلف داده دارن. دستور جمع اعداد صحیح با دستور جمع اعداد اعشاری کاملاً متفاوت هست. وقتی شما مینویسین:
int a = 5;
double b = 2.5;
double result = a + b;
پردازنده نمیتونه مستقیماً یه
int و یه double رو با هم جمع بزنه چون ساختار باینری اونها کاملاً متفاوت هست. کامپایلر باید قبل از انجام عملیات، هر دو عملوند رو به یه نوع مشترک تبدیل کنه.قانون راهنمای این تبدیل ساده هست:
همیشه به سمت نوعی که اطلاعات بیشتری رو حفظ میکنه حرکت کن.
انواع اعشاری اولویت بالاتری از انواع صحیح دارن. توی لیست زیر به ترتیب اولویت تبدیل از بالا به پایین میشه:
long double
double
float
long long
long
int
این تبدیلها برای:
۱. عملگرهای حسابی
* / % + -۲. عملگرهای رابطه و برابری
< <= > >= == !=۳. عملگرهای بیتی
& | ^۴. عملگر سه تایی (برای عملوندهای دوم و سوم)
?:توسط کامپایلر اعمال میشن.
🚁 Hicte Blog | (smm)
1👍6❤1
#سی
تبدیلهای حسابی معمول و ارتقای اعداد صحیح
[قسمت دوم] [لینک به قسمت اول]
ارتقای اعداد صحیح (Integer Promotion):
هر نوع دادهای که جایگاه پایینتری از
پردازندههای مدرن برای کار با مقادیر
ارتقا روی هر عملوند به صورت مجزا اتفاق میافته. حتی یه عبارت ساده مثل
بر خلاف تبدیلهای حسابی معمول، ارتقای اعداد صحیح تو همهی عملگرها اتفاق میفته حتی عملگرهایی مثل
استثناها عملگرهای
🚁 Hicte Blog | (smm)
تبدیلهای حسابی معمول و ارتقای اعداد صحیح
[قسمت دوم] [لینک به قسمت اول]
قبل از اینکه UAC بررسی بشه، یه مرحلهی مقدماتی وجود داره؛ ارتقای اعداد صحیح.
ارتقای اعداد صحیح (Integer Promotion):
هر نوع دادهای که جایگاه پایینتری از
int داشته باشه [یعنی _Bool و char و short] به طور خودکار به int ارتقا پیدا میکنه، حتی اگه هیچ متغیری از نوع int تو عبارت وجود نداشته باشه.پردازندههای مدرن برای کار با مقادیر
int بهینه شدن. بنابراین استاندارد C تعیین کرد که همه محاسبات حداقل در سطح int انجام بشن.ارتقا روی هر عملوند به صورت مجزا اتفاق میافته. حتی یه عبارت ساده مثل
c + c که فقط یه char داره، نتیجهاش int هست.بر خلاف تبدیلهای حسابی معمول، ارتقای اعداد صحیح تو همهی عملگرها اتفاق میفته حتی عملگرهایی مثل
~ که فقط یه عملوند دارن.استثناها عملگرهای
++، --، sizeof و عملگر انتساب یا همون = هستن که براشون ارتقای اعداد صحیح رخ نمیده. چون sizeof که کلا با مقدار عملوندش کاری نداره و اندازهی نوع متغیر رو محاسبه میکنه، ++ و -- هم مستقیما روی همون متغیر مینویسن، عملگر انتساب (=) هم منطقا نباید به نوع عملوند سمت چپش دست بزنه پس کلا کاری به این موضوع نداره.🚁 Hicte Blog | (smm)
👍4