سؤال

لماذا هذه الكتل من التعليمات البرمجية تسفر عن نتائج مختلفة?

بعض التعليمات البرمجية الشائعة:

#define PART1PART2 works
#define STRINGAFY0(s) #s
#define STRINGAFY1(s) STRINGAFY0(s)

الحالة 1:

#define GLUE(a,b,c) a##b##c  
STRINGAFY1(GLUE(PART1,PART2,*))
//yields
"PART1PART2*"

الحالة 2:

#define GLUE(a,b) a##b##*
STRINGAFY1(GLUE(PART1,PART2))
//yields
"works*"

الحالة 3:

#define GLUE(a,b) a##b
STRINGAFY1(GLUE(PART1,PART2*))
//yields
"PART1PART2*"

أنا باستخدام مسفك from من VS.net البرنامج الفرعي 2005 (1)

تحرير:في الوقت الحالي ، أعتقد أن المعالج المسبق يعمل على هذا النحو عند توسيع وحدات الماكرو:الخطوة 1:- خذ الجسم - إزالة أي مسافة بيضاء حول # # المشغلين - تحليل السلسلة ، في حالة العثور على معرف يطابق اسم المعلمة:- إذا كان بجوار عامل تشغيل # # ، فاستبدل المعرف بالقيمة الحرفية للمعلمة (أي.سلسلة مرت في) - إذا لم يكن بجوار عامل تشغيل # # ، فقم بتشغيل عملية التفسير بأكملها على قيمة المعلمة أولا ، ثم استبدل المعرف بهذه النتيجة.(تجاهل سترينجافي واحد ' # ' حالة أجهزة الصراف الآلي) - إزالة جميع # # المشغلين

الخطوة 2:- خذ تلك السلسلة الناتجة وقم بتحليلها لأي وحدات ماكرو

الآن ، من ذلك أعتقد أن جميع الحالات 3 يجب أن تنتج نفس السلسلة الناتجة بالضبط:

جزء1جزء 2*

وبالتالي بعد الخطوة 2 ، يجب أن يؤدي إلى

يعمل*

ولكن على الأقل يجب أن يؤدي إلى نفس الشيء.

هل كانت مفيدة؟

المحلول

الحالات 1 و 2 ليس لها سلوك محدد لأن لديك مغريا للصق * في رمز واحد قبل المعالج.وفقا لقواعد جمعية المعالج الخاص بك هذا إما يحاول الغراء معا الرموز PART1PART2 (أو فقط PART2) و *.في حالتك ، ربما يفشل هذا بصمت ، وهو أحد النتائج المحتملة عندما تكون الأشياء غير محددة.الرمز المميز PART1PART2 تليها * ثم لن يتم النظر في التوسع الكلي مرة أخرى.ثم ينتج التوتير النتيجة التي تراها.

بلدي دول مجلس التعاون الخليجي يتصرف بشكل مختلف على الأمثلة الخاصة بك:

/usr/bin/gcc -O0 -g -std=c89 -pedantic   -E test-prepro.c
test-prepro.c:16:1: error: pasting "PART1PART2" and "*" does not give a valid preprocessing token
"works*"

لذلك لتلخيص قضيتك 1 لديها مشكلتين.

  • لصق اثنين من الرموز التي لا تنتج في رمز معالج مسبق صالح.
  • ترتيب التقييم من ## المشغل

في الحالة 3 ، يعطي المترجم الخاص بك نتيجة خاطئة.يجب أن

  1. تقييم الحجج ل STRINGAFY1
  2. للقيام بذلك يجب أن تتوسع GLUE
  3. GLUE النتائج في PART1PART2*
  4. التي يجب توسيعها مرة أخرى
  5. والنتيجة هي works*
  6. ثم يتم تمريرها إلى STRINGAFY1

نصائح أخرى

تفعل الأمر بالضبط ما تقوله به.تأخذ الأول والثاني أسماء الرموز التي تم تمريرها ولصقها معا في رمز جديد.يستغرق الثالث 2 رموزا ويستخدمها، ثم تقوم بوضع * في السلسلة بنفسك (والتي ستتقيم في النهاية في شيء آخر.)

ما هو بالضبط السؤال مع النتائج؟ماذا توقعت ان تأخذ؟يبدو أن كل شيء يعمل كما أتوقع ذلك.

بعد ذلك بالطبع هو مسألة لماذا تلعب مع الفنون المظلمة للرمز Munging مثل هذا على أي حال؟:)

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