ضرب char و int معا في ج
سؤال
اليوم وجدت ما يلي:
#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
رمل int
S في هذا العالم.