مثال على شيء هو ، وليس ، "تعبير مستمر" في ج؟

StackOverflow https://stackoverflow.com/questions/3755524

  •  04-10-2019
  •  | 
  •  

سؤال

أنا مرتبك بين ما هو وليس تعبيرًا مستمرًا في C ، حتى بعد الكثير من Google. هل يمكنك تقديم مثال على شيء ما ، وهو ليس ، تعبيرًا مستمرًا في C؟

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

المحلول

يمكن تقييم التعبير المستمر في وقت الترجمة. هذا يعني أنه لا يوجد لديه متغيرات فيه. فمثلا:

5 + 7 / 3

هو تعبير مستمر. شيء مثل:

5 + someNumber / 3

لا ، على افتراض someNumber هو متغير (أي ، ليس في حد ذاته ثابت وقت الترجمة).

نصائح أخرى

هناك دقة أخرى للتعبيرات المستمرة. هناك بعض الأشياء المعروفة للمترجم ، ولكن لا يمكن أن تكون معروفة للمعالج المسبق.

فمثلا (24*60*60) يمكن حسابها من قبل كليهما ، ولكن sizeof struct foo معروف فقط للمترجم. هذا التمييز يمكن أن يهم إذا كنت تحاول التحقق من أن أ struct يُعرّف على تلبية حجمًا مخصصًا خارجيًا ، أو أن أعضائه يتم تعيينهم في الإزاحة المحددة خارجيًا. (غالبًا ما تنشأ حالة الاستخدام عند برامج تشغيل جهاز الترميز حيث struct يصف سجلات الجهاز كما هو موضح في مساحة الذاكرة.)

في هذه الحالة لا يمكنك القول ببساطة #if (sizeof(struct UART) == 12) نظرًا لأن المعالج المسبق يعمل في تمريرة قبل التجميع ولا يمكنه ببساطة معرفة حجم أي أنواع. ومع ذلك ، فهو تعبير مستمر وسيكون صالحًا كمهيئة لمتغير عالمي (على سبيل المثال int UARTwords = sizeof(struct UART) / sizeof(short);) ، أو لإعلان حجم الصفيف (على سبيل المثال unsigned char UARTmirror[sizeof(struct UART)];)

لا أحد يبدو أنه ذكر نوعًا آخر من التعبير المستمر: معالجة الثوابت. عنوان كائن ذو مدة تخزين ثابت هو عنوان ثابت ، وبالتالي يمكنك القيام بهذا النوع من الأشياء في نطاق الملف:

char x;
char *p = &x;

تحدد حرفيات السلسلة المصفوفات مع مدة تخزين ثابتة ، لذلك هذه القاعدة هي أيضًا سبب قيامك بذلك في نطاق الملف:

char *s = "foobar";

أي حرفية ذات قيمة واحدة هي تعبير مستمر.

3     0.0f    '\n'

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

معظم المشغلين (SizeOf ، Casts ، إلخ) المطبقة على الثوابت أو الأنواع هي تعبيرات ثابتة.

sizeof(char)
(byte) 15

أي تعبير ينطوي على تعبيرات ثابتة فقط هو في حد ذاته تعبير مستمر.

15 + 3
0.0f + 0.0f
sizeof(char)

عادة ما يكون أي تعبير يتضمن مكالمات وظائف أو تعبيرات غير ثابتة ليس تعبير مستمر.

strlen("hello")
fifteen + x

أي حالة ماكرو كتعبير مستمر يعتمد على ما يتوسع إليه.

/* Always a constant */
#define FIFTEEN 15

/* Only constant if (x) is
#define htons(x)  (( ((x) >> 8) | ((x) << 8) ) & 0xffff) 

/* Never constant */
#define X_LENGTH  strlen(x)

كان لدي في الأصل بعض الأشياء هنا const المعرفات ، لكنني اختبرت ذلك ويبدو أنه لا ينطبق في C. const, ، من الغريب أن لا تعلن الثوابت (على الأقل ، ليست "ثابتة" بما يكفي لاستخدامها switch صياغات). في C ++ ، ومع ذلك ، فإنه يفعل.

مجعد صغير آخر: في C ، تكون قيمة "التعداد" ثابتة ، ولكن لا يمكن استخدامها إلا بعد اكتمال إعلان "التعداد". ما يلي ، على سبيل المثال ، غير مقبول في المعيار C ، على الرغم من أنه مقبول في C ++:

enum {foo=19, bar, boz=bar+5;};

يمكن إعادة كتابتها:

enum {foo=19, bar}; enum {boz=bar+5;};

على الرغم من أن هذا سينتهي به الأمر إلى تحديد أنواع التعدادات المختلفة المتعددة ، بدلاً من أنواعها التي تحمل جميع القيم.

ايضا integral character constants كما 'a' أو '\n' هي الثوابت التي يتعرف عليها المترجم على هذا النحو. لديهم نوع int.

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