printf مع sizeof على منصات 32 مقابل 64:كيف أتعامل مع كود التنسيق بطريقة مستقلة عن النظام الأساسي؟

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

  •  05-07-2019
  •  | 
  •  

سؤال

لدي بعض التعليمات البرمجية التي تطبع مقدار الذاكرة التي يستخدمها البرنامج.الخط مشابه لهذا:

printf("The about of RAM used is %u", anIntVariable*sizeof(double) );

حيث anIntVariable هو متغير int لعدد عناصر المصفوفة المزدوجة.على أية حال، في أنظمة 32 بت لم أواجه أية مشكلات مطلقًا، لكن في أنظمة 64 بت، أتلقى تحذيرًا من المترجم بشأن استخدام "%u" لعدد صحيح طويل غير موقّع.يؤدي استخدام "%lu" كرمز التنسيق إلى إصلاح المشكلة على الإصدار 64 بت ولكنه يتسبب في شكوى المترجم على الإصدار 32 بت لأن النوع يعود إلى int غير الموقع.لقد وجدت أن sizeof(double) يُرجع بالفعل قيمة مختلفة على أنظمة 32 مقابل 64 بت.لقد وجدت بعض أدلة صفحات الويب ل يتحول كود من 32 بت إلى 64 بت لكنني أفضل أن يكون لدي كود يعمل على كليهما بدلاً من مجرد التحويل ذهابًا وإيابًا.

كيف أكتب هذا السطر بطريقة مستقلة عن النظام الأساسي؟أعرف العديد من الطرق التي يمكنني من خلالها القيام بذلك باستخدام توجيهات المعالج المسبق ولكن هذا يبدو وكأنه اختراق.بالتأكيد هناك طريقة أنيقة لا أدركها.

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

المحلول

يتم توفير معرفات printf المحمولة في ملف التضمين inttypes.h.

يحتوي ملف التضمين هذا على العديد من المعرفات المحمولة لوقت التشغيل المحدد الخاص بك.على سبيل المثال، تريد PRIuPTR، وهو ما يعني "العلاقات العامةintf أنامعرف الأسنان شموقعة بحجم يصل إلى حجم المؤشر".

سيكون مثالك بعد ذلك:

printf("The amount of RAM used is %" PRIuPTR, anIntVariable*sizeof(double) );

النتائج على نظام Linux 64 بت مع الإصدار 4.3 من مجلس التعاون الخليجي (int anIntVariable = 1):

$ gcc test.c -m32 -o test && ./test
The amount of RAM used is 8
$ gcc test.c -o test && ./test
The amount of RAM used is 8

من أجل الاكتمال، هناك معرفات لـ scanf أيضًا، وبادئاتها هي SCN.

نصائح أخرى

والقيمة عودة sizeof هو size_t. إذا كنت تستخدم مترجم متوافقة C99 يبدو أنك يمكن استخدام <الإضراب> %zd %zu لذلك.

وD'يا: %zu (غير موقعة) بطبيعة الحال. شكرا، بنيويورك.

أولاً، يجب عليك مطابقة المحدد "%" مع نوع البيانات الفعلي الذي تريد طباعته. حجم إرجاع نوع البيانات size_t, ، وكما لا يجب أن تحاول طباعة عدد عائم باستخدام محدد "%d"، لا يجب أن تحاول طباعة size_t باستخدام "%u" أو "%d" أو أي شيء لا يعني حقًا size_t.

أعطت الردود الأخرى بعض الطرق الجيدة للتعامل مع هذا باستخدام المترجمين الأحدث ("%z" وPRIu32)، ولكن الطريقة التي اعتدنا القيام بها كانت ببساطة تحويل size_t إلى الطول غير الموقع، ثم طباعته باستخدام "%lu" :

printf("The amount of RAM used is %lu", (unsigned long)(anIntVariable*sizeof(double)) );

لن يعمل هذا على الأنظمة التي يكون فيها size_t أوسع من الطول، لكنني لا أعرف أيًا من هذه الأنظمة، ولست متأكدًا حتى مما إذا كان المعيار يسمح بذلك.

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