سؤال

ومرحبا،

ويمكن لبعض واحد يساعدني في فهم السبب في أن قيمة مربع (س) هي 49؟

وأنا باستخدام Visual C ++ 6.0.

#define SQUARE(X) X * X

int main(int argc, char* argv[])
{
    int y = 5;

    printf("%d\n",SQUARE(++y));
    return 0;
}
هل كانت مفيدة؟

المحلول

ونيل بتروورث، مارك وبافل على حق.

وساحة (++ ص) توسع ل++ ذ * ++ ذ، التي الزيادات ضعف قيمة y.

وثمة مشكلة أخرى يمكن أن تواجه: ساحة (أ + ب) توسع ل+ ب * أ + ب وهي ليست (أ + ب) * (أ + ب) ولكن + (ب * أ) + (ب). ويجب الحرص على إضافة أقواس حول العناصر عند الحاجة، مع تحديد وحدات الماكرو: مربع رقم تعريف (X) ((X) * (X)) قليلا أقل مخاطرة. (إيان كيمب كتب لأول مرة في تعليقه)

هل يمكن بدلا من استخدام وظيفة قالب مضمنة (أي أقل كفاءة في وقت التشغيل) مثل هذا واحد:

template <class T>
inline T square(T value)
{
    return value*value;
}

ويمكنك التحقق من ذلك يعمل:

int i = 2;
std::cout << square(++i) << " should be 9" << std::endl;
std::cout << square(++i) << " should be 16" << std::endl;

و(لا حاجة لكتابة

square<int>(++i)

ولأن نوع int هو ضمني لط)

نصائح أخرى

ولأن توسع الكلية إلى:

++y * ++y

والذي يعطي سلوك غير معرف في C ++ - نتيجة يمكن أن يكون أي شيء. يجب تغطية هذه المشكلة معروفة جدا في أي كتاب مدرسي لائق يغطي استخدام وحدات الماكرو. أي واحد الذي تستخدمه؟

ولأن وحدات الماكرو تفعل استبدال نصية حتى يحصل على توسيع الرمز الذي كتب إلى

printf("%d\n",++y * ++y );

ومن ثم ترتيب العمليات هو سلوك غير معرف حتى هذا يرى المترجم 2 الزيادات ومن ثم الضرب

وهكذا نكون حذرين مع وحدات الماكرو أفضل على وظائف الاستخدام والتي كما المترجم يمكن توسيع ويتمشى لن تتخذ أي أطول لتشغيل.

وثانيا لا تتحمل ما سيحدث إذا زيادة والمتغيرات استخدام

وحدات الماكرو ليست وظائف: أنها مجرد تغيير نص البرنامج. وتسمى هذه العملية <م> تجهيزها وانها أعدمت تلقائيا قبل ان يحصل على ترجمة التعليمات البرمجية الخاصة بك. الناس كتابة وحدات الماكرو لتوفير الوقت وإدخال بعض التباين إلى رمز مصدرها.

عند إرسال SQUARE(x)، يحدث عدم وجود مكالمة funciton الفعلية، يتم تعديل النص فقط. وهذه العملية الغبية جدا، لذلك ما عليك القيام به احتياطات إضافية في حالات مثل لك. الرجوع إلى إجابات أخرى لشرح قضيتك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top