سؤال

اليوم وجدت ما يلي:

#include <stdio.h>

int main(){
char x = 255;
int z = ((int)x)*2;

printf("%d\n", z); //prints -2

return 0;

}

لذلك في الأساس ، أحصل على فائض لأن حد الحجم يتم تحديده بواسطة المعاملات على الجانب الأيمن من = علامة ؟؟

لماذا لا يلقيها إلى int قبل ضرب العمل؟

في هذه الحالة ، أستخدم char و int ، ولكن إذا استخدمت "Long" و "Long Long int" (C99) ، فأنا أحصل على سلوك مماثل. هل ينصح عمومًا بعدم القيام بحساب مع معاملات بأحجام مختلفة؟

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

المحلول

char يمكن توقيعها أو غير موقعة ، اعتمادًا على المترجم الخاص بك.

في حالتك ، يبدو أنه تم توقيعه ، و 255 خارج النطاق يمكن أن تمثله (على الأرجح ، يمكن أن يمثل فقط أرقام من -128 إلى 127).

لذلك تحدث المشكلة عند تعيين 255 إلى char المتغير -ينتج عن هذا قيمة محددة من التنفيذ ، والتي في حالتك ، هي -1.

عندما تتضاعف -1 في 2 ، تحصل على -2. لا لغز هناك. المدلى بها (int) لا شيء - أنواع أضيق من int تتم ترقيتها دائمًا إلى int أو unsigned int قبل إجراء أي حسابات معهم.

نصائح أخرى

يبدو أن char موقعة على النظام الأساسي الخاص بك. لذلك char x = 255 هو نفسه بشكل فعال مثل char x = -1. الممثلون إلى int لا يهم.

حاول تغيير ذلك إلى:

unsigned char x = 255;

لا ، أنت لا تحصل على فائض على السطر الثاني (الضرب). المشكلة هي أن المترجم الخاص بك يستخدم signed char بشكل افتراضي و 255 تدفقات وسوف تعني -1. في الأساس ، تقوم بتهيئة المتغير x مع قيمة -1. سيؤدي الصب -1 إلى int إلى -1 (signed سيتم تمديد المعامل unsigned ستحصل المعاملات على الصفر).

يمكنك فرض char أن تكون unsigned عن طريق إضافة unsigned بادئة:

unsigned char x = 255;

توضح الإجابات الأخرى بشكل جيد كيف يعمل مثالك "يعمل" ، لذلك لن أشرح ذلك مرة أخرى.

ومع ذلك ، اسمحوا لي أن ألاحظ أنه إذا كان ما تريد استخدامه هو "عدد صحيح غير موقعة 8 بت" ، فقط استخدم <stdint.h>uint8_t بالفعل (و 16 ، 32 ، 64 بيلت رفاق) وابتعاد عن كل charس، shortرمل intS في هذا العالم.

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