انجمن‌های فارسی اوبونتو

لطفاً به انجمن‌ها وارد شده و یا جهت ورود ثبت‌نام نمائید

لطفاً جهت ورود نام کاربری و رمز عبورتان را وارد نمائید


ارائه ۲۴٫۱۰ اوبونتو منتشر شد 🎉

نویسنده موضوع: یک سوال خفن در C  (دفعات بازدید: 2973 بار)

0 کاربر و 2 مهمان درحال مشاهده موضوع.

آفلاین ARH

  • Full Member
  • *
  • ارسال: 135
  • جنسیت : پسر
  • Hardware Enthusiast
    • پروفايل شخصي من در گوگل
یک سوال خفن در C
« : 11 تیر 1388، 06:49 ب‌ظ »
سلام

آقا من که عقلم به جایی راه‌نمیده ! کسی میتونه بفهمه این یک تیکه کد چی چی داره می‌گه :
#define __READ_SPECMEM(SRC, SRC_V) \
  (addr = (SRC), \
   (spec_mode \
    ?   spec_mem_access(Read, addr, &SRC_V, sizeof(SRC_V))      \
    :  mem_access(Read, addr, &SRC_V, sizeof(SRC_V))),         \
   SRC_V)

البته خوب فکر کنم مشخصه که جای READ_SPECMEM میاد و اون یک تیکه کد رو می گذاره اما اگر فرض کنیم , (کاما) هم تو دستورات Pre-Compile معادل ; (سمی‌کولون) خودمونه خط آخرش اصلا معنی نمی‌ده !

آفلاین جادی

  • عضو کاربران ایرانی اوبونتو
  • *
  • ارسال: 1610
    • در دفاع از آزادی بیان
پاسخ به: یک سوال خفن در C
« پاسخ #1 : 11 تیر 1388، 08:55 ب‌ظ »
با اپراتور ? توی سی آشنا هستی؟ اگر احیانن نه، یک نگاه به اینجا بنداز http://www.space.unibe.ch/comp_doc/c_manual/C/SYNTAX/conditional.html
آزادی کیبورد حق هر انسان است - جادی

آفلاین ARH

  • Full Member
  • *
  • ارسال: 135
  • جنسیت : پسر
  • Hardware Enthusiast
    • پروفايل شخصي من در گوگل
پاسخ به: یک سوال خفن در C
« پاسخ #2 : 11 تیر 1388، 09:05 ب‌ظ »
با اپراتور ? توی سی آشنا هستی؟ اگر احیانن نه، یک نگاه به اینجا بنداز http://www.space.unibe.ch/comp_doc/c_manual/C/SYNTAX/conditional.html

نه مشکل اون اپراتور نیست ! مشکل اون , (کاما) ها هستند که من ازشون سر در نمی‌آورم ! ضمن اینکه تمام این کد با ماکروهای Pre-Compile نوشته شده

آفلاین سعید رسولی

  • ilius, saeedgnu
  • عضو کاربران ایرانی اوبونتو
  • *
  • ارسال: 1543
  • جنسیت : پسر
پاسخ به: یک سوال خفن در C
« پاسخ #3 : 11 تیر 1388، 09:52 ب‌ظ »
با اپراتور ? توی سی آشنا هستی؟ اگر احیانن نه، یک نگاه به اینجا بنداز http://www.space.unibe.ch/comp_doc/c_manual/C/SYNTAX/conditional.html

نه مشکل اون اپراتور نیست ! مشکل اون , (کاما) ها هستند که من ازشون سر در نمی‌آورم ! ضمن اینکه تمام این کد با ماکروهای Pre-Compile نوشته شده
بله. حق با شماست. کاما نقش سمی‌کالن رو داره. بنابراین کاری که این تابع انجام میده اینه که اول مقدار SRC رو می‌ریزه توی addr و بعدش با توجه به درست و غلط بودن spec_mode میاد یکی از توابع spec_mem_access و mem_access رو اجرا میکنه. فقط تنها مسئاله اینه که هدفش از اون قسمت سوم چی بوده، یعنی اون SRC_V آخر به نظر نمیاد کاری انجام بده!
یعنی به نظر میاد با این کد یکی هست:
#define __READ_SPECMEM(SRC, SRC_V) \
  (addr = SRC, \
  (spec_mode \
    ?   spec_mem_access(Read, addr, &SRC_V, sizeof(SRC_V))      \
    :  mem_access(Read, addr, &SRC_V, sizeof(SRC_V))) )

آفلاین ARH

  • Full Member
  • *
  • ارسال: 135
  • جنسیت : پسر
  • Hardware Enthusiast
    • پروفايل شخصي من در گوگل
پاسخ به: یک سوال خفن در C
« پاسخ #4 : 11 تیر 1388، 10:11 ب‌ظ »
من هم تو همون خط آخر موندم ! وقتی دقیق تر شدم متوجه شدم این SRC_V در زمان اجرا به اسم یک متغییر  static اشاره میکنه ! حالا این که در خط اخر آوردن نام یک متغییر از نوع char چه معنی میتونه داشته باشه ؟
نکته جالب دیگه اینه که این تایع __READ_SPECMEM خروجی داره منظورم اینه که از خروجی این تابع استفاده شده است اما هر جفت توابع mem_access و spec_mem_access از نوع void هستند. اما مقدار اون SRC_V رو با اشاره‌گر Set می‌کنند ! حالا میشه اینطور استنباط کرد که خروجی تابع READ_SPECMEM رو همون خط آخر (متغییر SRC_V) تولید میکنه ! تغیریبا type هاشون هم به همدیگه می‌خوره !


آفلاین pedrambehroozi

  • Jr. Member
  • *
  • ارسال: 37
  • جنسیت : پسر
پاسخ به: یک سوال خفن در C
« پاسخ #5 : 11 تیر 1388، 11:38 ب‌ظ »
سلام

آقا من که عقلم به جایی راه‌نمیده ! کسی میتونه بفهمه این یک تیکه کد چی چی داره می‌گه :
#define __READ_SPECMEM(SRC, SRC_V) \
  (addr = (SRC), \
   (spec_mode \
    ?   spec_mem_access(Read, addr, &SRC_V, sizeof(SRC_V))      \
    :  mem_access(Read, addr, &SRC_V, sizeof(SRC_V))),        \
   SRC_V)

البته خوب فکر کنم مشخصه که جای READ_SPECMEM میاد و اون یک تیکه کد رو می گذاره اما اگر فرض کنیم , (کاما) هم تو دستورات Pre-Compile معادل ; (سمی‌کولون) خودمونه خط آخرش اصلا معنی نمی‌ده !

منم به یه همچین کدی برخورد کردم. تا جایی که من می دونم، این کد معادله با این کد:
#define __READ_SPECMEM(SRC, SRC_V)    \
do {    \
    addr = SRC;    \
    spec_mode ? spec_mem_access(READ, addr, &SRC_V, sizeof(SRC_V) :  mem_access(Read, addr, &SRC_V, sizeof(SRC_V))   \
    SRC_V;    \
} while(0)

و اگه این قضیه درست باشه، خط SRC_V; اصلا کامپایل نمیشه!
من کد زیر رو کامپایل کردم:
int a = 1;
a;
هیچ کد اسمبلی به ازای خط آخر تولید نمیشه!

این فرضیه هم که ممکنه خروجی تابع باشه رد میشه چون کدی که من دیدم تابعش هیچ خروجی نداشت.
شاید اگه توی یه فروم تخصصی C بپرسی زودتر جواب بگیری.
به هرحال اگه جوابشو پیدا کردی به ما هم یه خبرب بده  ;)
« آخرین ویرایش: 11 تیر 1388، 11:41 ب‌ظ توسط pedrambehroozi »
Avoid the Gates of Hell. Use Linux

آفلاین سعید رسولی

  • ilius, saeedgnu
  • عضو کاربران ایرانی اوبونتو
  • *
  • ارسال: 1543
  • جنسیت : پسر
پاسخ به: یک سوال خفن در C
« پاسخ #6 : 12 تیر 1388، 07:52 ق‌ظ »
من هم تو همون خط آخر موندم ! وقتی دقیق تر شدم متوجه شدم این SRC_V در زمان اجرا به اسم یک متغییر  static اشاره میکنه ! حالا این که در خط اخر آوردن نام یک متغییر از نوع char چه معنی میتونه داشته باشه ؟
نکته جالب دیگه اینه که این تایع __READ_SPECMEM خروجی داره منظورم اینه که از خروجی این تابع استفاده شده است اما هر جفت توابع mem_access و spec_mem_access از نوع void هستند. اما مقدار اون SRC_V رو با اشاره‌گر Set می‌کنند ! حالا میشه اینطور استنباط کرد که خروجی تابع READ_SPECMEM رو همون خط آخر (متغییر SRC_V) تولید میکنه ! تغیریبا type هاشون هم به همدیگه می‌خوره !
بله. بازم خودتون جواب خودتون رو دادید! ظاهراً همون مقدار آخر رو برمی‌گردونه. یعنی اون SRC_V از تابع return میشه. با تستهایی که انجام دادم که اینطور بود. حتی توی اون قسمت آخر مقداردهی کرده باشیم، بازم همون برگردونده میشه.
یعنی اگه اون قسمت سوم نباشه، تابع void خواهد شد و نمیشه ازش خروجی گرفت(و اگه بگیریم ارور میده و کامپایل نمیشه). یعنی نوع خروجی تابع رو نوع خروجی قسمت آخرش تعیین میکنه.

جالب بود. :)
این جور کدها(مثل همین توابع pre-compile) اگرچه خوانایی برنامه رو کم می‌کنن، ولی در performance تاثیر مثبت دارن(چون قبل از کامپایل با کد جایگزین میشن، و موقع اجرا زمان سربارگذاری از بین میره). ضمن اینکه میشه بعضی توابع ساده رو بصورت cross-type تعریف کرد، یعنی نوع آرگومان‌ها و خروجی تابع موقع تعریف مشخص نیست، بلکه موقع فراخوانی مشخص میشه. شبیه زبانهای اسکریپتی!