طباعة غير موقعة طويلة طويلة الباحث نوع القيمة بإرجاع نتائج غريبة
-
11-12-2019 - |
سؤال
لدي مشكلة أثناء استخدام printf
وظيفة لطباعة قيم النوع unsigned long long int
ليس لدي أي فكرة ما هو الخطأ.أنا باستخدام ديف-كبب 4.9.9.2 و فيسوال ستوديو 2010 المهنية (وأنا أعلم أنه ليس مترجم ج ، ولكن على أي حال ، أراد أن يحاول) على ويندوز 7 المهنية 64 بت.للعرض ، اعتدت %llu
معدل (وفقا ل كيف يمكنك برينتف غير موقعة طويلة طويلة إنت (محدد تنسيق ل غير موقعة طويلة طويلة إنت)?) لكنني حاولت أيضا أنا 64 د دون أي تأثير...
أولا ، أردت فقط طباعة الحد الأدنى والحد الأقصى لقيمة unsigned long long int
(باستخدام ULONG_MAX
من عند limits.h
)
printf("unsigned long long int: \n%llu to %llu \n\n", 0, ULONG_MAX);
المرتجعات:
غير موقعة طويلة طويلة كثافة العمليات:18446744069414584320 إلى 1580552164021 (ديف-حزب الشعب الكمبودي)
غير موقعة طويلة طويلة كثافة العمليات:18446744069414584320 إلى 0 (فيسوال ستوديو)
ثم حاولت استخدام printf
لطباعة اثنين من الأصفار
printf("unsigned long long int: \n%llu to %llu \n\n", 0, 0);
المرتجعات:
غير موقعة طويلة طويلة كثافة العمليات:0 إلى 1580552164021 (ديف-حزب الشعب الكمبودي)
غير موقعة طويلة طويلة كثافة العمليات:0 إلى 0 (فيسوال ستوديو)
حاول أيضا اثنين ULONG_MAX
القيم
printf("unsigned long long int: \n%llu to %llu \n\n", ULONG_MAX, ULONG_MAX);
المرتجعات:
غير موقعة طويلة طويلة كثافة العمليات:18446744073709551615 إلى 1580552164021 (ديف-حزب الشعب الكمبودي)
غير موقعة طويلة طويلة كثافة العمليات:18446744073709551615 إلى 0 (فيسوال ستوديو)
لماذا تتصرف من هذا القبيل?هل يمكن أن تفسر لي?
المحلول
هذا خطأ:
printf("unsigned long long int: \n%llu to %llu \n\n", 0, ULONG_MAX);
يمكنك استخدام unsigned long long
شكل محدد ، ولكن يمكنك تمرير int
و unsigned long
القيمة.تعني قواعد الترويج أنه يمكنك أن تكون قذرا في كل شيء int
- الحجم أو الأصغر ، الذي يفعل لا تنطبق على long long
.
استخدم القوالب:
printf("unsigned long long int: \n%llu to %llu \n\n",
0ULL, (unsigned long long) ULONG_MAX);
الشرح: عند تمرير الحجج إلى printf
, ، أي نوع يمكن أن يصلح في int
يتم ترقيته إلى int
, ، ثم أي نوع يمكن أن يصلح في unsigned int
يتم ترقيته إلى unsigned int
.كما أنه من المقبول تمرير نوع غير موقع إلى محدد تنسيق موقع أو العكس طالما أن القيمة يمكن تمثيل تمريرها باستخدام النوع المحدد بواسطة محدد التنسيق.
لذلك يجب أن تكون حذرا مع long
و long long
, ، ولكن يمكنك أن تكون قذرة مع int
, short
, ، و char
.
معظم المجمعين لديك إعدادات لجعلها تحذرك من هذا النوع من الأخطاء ، حيث يمكن اكتشافه في وقت الترجمة بسهولة إلى حد ما;دول مجلس التعاون الخليجي ورنة لها -Wformat
مما يؤدي إلى التحذيرات التالية:
test.c:5: warning: format ‘%llu’ expects type ‘long long unsigned int’, but argument 2 has type ‘int’ test.c:5: warning: format ‘%llu’ expects type ‘long long unsigned int’, but argument 3 has type ‘long unsigned int’
نصائح أخرى
أنت لا تمر unsigned long longs
.أنت تمر int
(0) و unsigned long
(أولونغ_ماكس).يجب أن تمر إلى printf()
بالضبط ما وعدت بالمرور في سلسلة التنسيق.
جرب هذا بدلا من ذلك:
printf("unsigned long long int: \n%llu to %llu \n\n", 0ULL, (unsigned long long)ULONG_MAX);
ULONG_MAX
يشير إلى unsigned long
وليس ل unsigned long long
.لهذا الأخير ، استخدم ULLONG_MAX
(لاحظ اضافية L
).
تحتاج إلى تغيير printf()
مكالمات مثل ذلك:
printf("unsigned long long int: \n%llu to %llu \n\n", 0ULL, ULLONG_MAX);
printf("unsigned long long int: \n%llu to %llu \n\n", ULLONG_MAX, ULLONG_MAX);
هذا يضمن أن الحجج ل printf()
تطابق محددات التنسيق.
طويل طويل إنت هو نوع من معيار 99 ، مسفك لا يدعم هذا.اتخاذ مترجم مع دعم 99 (مثل مينغو ويندوز) وسوف تعمل.