C qiymatida qo'shimchalar kiritish

#include
int main()
{

  char c =118,a=117;
  c=c+10;
  a=a+10;
  printf("c:%d, a:%d\n", c,a);

}

Javob: c: -128, a: 127.

Kimdir menga c + 10 ning -128 va +10 127 ni nima uchun izohlashi mumkin?

Oldindan rahmat.

0
@deepak Iltimos, sukut bo'yicha imzolanganmi yoki imzosizmi? . Natijada siz kompilyatorga xosdir.
qo'shib qo'ydi muallif Lundin, manba
@Lundin: yomonlik. Agar char kodi int sifatida ko'p sonli bitga ega bo'lmasa, bu dastur haqiqatan ham aniqlangan.
qo'shib qo'ydi muallif Olaf, manba
tizimingizda char aslida char imzolanganligi aniq
qo'shib qo'ydi muallif user3629249, manba
tizimingizda char aslida char imzolanganligi aniq
qo'shib qo'ydi muallif user3629249, manba
tizimingizda char aslida char imzolanganligi aniq
qo'shib qo'ydi muallif user3629249, manba

7 javoblar

Signature 8-bit qiymatlari -128 dan 127 gacha. 127 uchun bitlar 0111 1111 va 128 uchun bitlar soni 1000 0000 bo'ladi. Muammo, imzolangan raqamda yuqori tartib (eng chap) bit belgisi (0 - +, 1 - bu -). Shunday qilib, imzolanganligi sababli, kompyuter buni negativ son sifatida izohlaydi -128 (Bu to'g'ri eslab qolinsa, imzolangan to'ldirish deb ataladi va har bir kishi bu dasturda bir nuqtada yoki boshqa dasturda ishlaydi) (2-ilovani ko'rib chiqing) Nima uchun past 7 bit 128 bo'lmasligini ko'rish uchun 0). char o'rniga c kodini va unsigned char deb e'lon qilish orqali ushbu "muammo" ni aylantira olasiz.

BTW, bu o'zgaruvchini quyidagi tarzda saqlashingiz mumkin:

char a = 117;  printf ("c:% d, a:% d \ n", a + 11, a + 10);

2
qo'shib qo'ydi
@Olaf, nima aniq aniqlangan xatti-harakatlarga e'tibor bera olasizmi? Mening tushuntirishim, nima bo'lishi kerakligini aniqlab olmoqchi emas, OShda aslida nima bo'lganiga javob beradi.
qo'shib qo'ydi muallif andrew, manba

Signature 8-bit qiymatlari -128 dan 127 gacha. 127 uchun bitlar 0111 1111 va 128 uchun bitlar soni 1000 0000 bo'ladi. Muammo, imzolangan raqamda yuqori tartib (eng chap) bit belgisi (0 - +, 1 - bu -). Shunday qilib, imzolanganligi sababli, kompyuter buni negativ son sifatida izohlaydi -128 (Bu to'g'ri eslab qolinsa, imzolangan to'ldirish deb ataladi va har bir kishi bu dasturda bir nuqtada yoki boshqa dasturda ishlaydi) (2-ilovani ko'rib chiqing) Nima uchun past 7 bit 128 bo'lmasligini ko'rish uchun 0). char o'rniga c kodini va unsigned char deb e'lon qilish orqali ushbu "muammo" ni aylantira olasiz.

BTW, bu o'zgaruvchini quyidagi tarzda saqlashingiz mumkin:

char a = 117;  printf ("c:% d, a:% d \ n", a + 11, a + 10);

2
qo'shib qo'ydi
@Olaf, nima aniq aniqlangan xatti-harakatlarga e'tibor bera olasizmi? Mening tushuntirishim, nima bo'lishi kerakligini aniqlab olmoqchi emas, OShda aslida nima bo'lganiga javob beradi.
qo'shib qo'ydi muallif andrew, manba

117 + 10 = 127 which is in range of the char type (-128 to 127)

Agar siz derazangizni programmer rejimida ochsangiz, 118 ikkilik rejimida 1110110 sifatida ko'rsatilganligini ko'rishingiz mumkin. Shuningdek, 10 1010 sifatida ifodalanadi. agar bu ikkisini qo'shsak, natijada 10000000 bo'ladi. char tipidagi intervalda emas, bu raqam -128 ga teng. shuning uchun -128 yoziladi.

2
qo'shib qo'ydi

chunki char 8-bit derazada imzolangan. Shunday qilib, 118 + 10 oralig'ida emas (maksimal 127 ).

Sizning kompilyatoringiz amalga oshirilsa uni "saralaydi" va uning o'rniga -128 ni olasiz.

1
qo'shib qo'ydi
OK, aniqlanmagan, lekin amalga oshirish belgilanadi: derleyici biror narsa qiladi. Yoki qisqartiradi yoki qisqartiradi. Shuning uchun men javobimda juda ehtiyotkorlik bilan harakat qildim, uning amalga oshirilishi (va shunday qilib portativ bo'lmagan, aniqlanmagan harakatlarga juda yaqin)
qo'shib qo'ydi muallif Jean-François Fabre, manba
Bu aniqlanmagan xatti-harakatlar. Har qanday natija to'g'ri bo'ladi.
qo'shib qo'ydi muallif Olaf, manba

chunki char 8-bit derazada imzolangan. Shunday qilib, 118 + 10 oralig'ida emas (maksimal 127 ).

Sizning kompilyatoringiz amalga oshirilsa uni "saralaydi" va uning o'rniga -128 ni olasiz.

1
qo'shib qo'ydi
OK, aniqlanmagan, lekin amalga oshirish belgilanadi: derleyici biror narsa qiladi. Yoki qisqartiradi yoki qisqartiradi. Shuning uchun men javobimda juda ehtiyotkorlik bilan harakat qildim, uning amalga oshirilishi (va shunday qilib portativ bo'lmagan, aniqlanmagan harakatlarga juda yaqin)
qo'shib qo'ydi muallif Jean-François Fabre, manba
Bu aniqlanmagan xatti-harakatlar. Har qanday natija to'g'ri bo'ladi.
qo'shib qo'ydi muallif Olaf, manba

chunki char 8-bit derazada imzolangan. Shunday qilib, 118 + 10 oralig'ida emas (maksimal 127 ).

Sizning kompilyatoringiz amalga oshirilsa uni "saralaydi" va uning o'rniga -128 ni olasiz.

1
qo'shib qo'ydi
OK, aniqlanmagan, lekin amalga oshirish belgilanadi: derleyici biror narsa qiladi. Yoki qisqartiradi yoki qisqartiradi. Shuning uchun men javobimda juda ehtiyotkorlik bilan harakat qildim, uning amalga oshirilishi (va shunday qilib portativ bo'lmagan, aniqlanmagan harakatlarga juda yaqin)
qo'shib qo'ydi muallif Jean-François Fabre, manba
Bu aniqlanmagan xatti-harakatlar. Har qanday natija to'g'ri bo'ladi.
qo'shib qo'ydi muallif Olaf, manba

Sizning holatingizda, char sizning platformangizdagi derleyici tomonidan imzolangan 8-bitli qiymat sifatida ifodalanadi va 2 ning qo'shimcha to'ldirishni . Ya'ni eng yuqori bit belgisi biti (1 bo'lsa, u holda salbiy). Shunday qilib, ikkiliksiz bo'lmagan qiymatlar oralig'i (ikkilik) 00000000-01111111 bo'lib, u kasr sonida 0-127 bo'ladi. Salbiy qadriyatlar (ikkilik) 10000000 dan 11111111 gacha bo'lgan oraliqda -128 dan -1 gacha.

Agar siz 118 dan boshlasangiz ikkilik bilan shunday bo'ladi:

01110110

Agar o'nli kasrlarni qo'shsam, 1010 ikkilikda qo'shiladi:

 01110110
+00001010
---------
 10000000

Endi siz eng yuqori bit belgilanini ko'rasiz, ya'ni to'ldirilgan raqam (kasr sonida maksimal 127dan kattaroq) va endi salbiy raqamni ifodalaydi. 8-bit ikkilik qiymati 10000000 kasrda -128 ni tashkil etadi.

Shunday qilib, (kodirovkada) 10 char qiymatiga 118 qo'shilsa, -128 hosil bo'ladi.

Sizning kodingiz a 117 ni tashkil qiladi, shuning uchun ham 10 + 117 = 127 127 bittaga teng bo'lgan qiymat uchun 7 bitga mos keladi. Yuqorida keltirilgan ikkilik tahlilni qanday amalga oshirilayotganini ko'rish uchun mashq qilishingiz mumkin.

1
qo'shib qo'ydi
Bu UB uchun ahamiyatli emas. Muammo shundaki, UB emas, balki dastur kodi char int bo'lmagani kabi juda ko'p bo'lmasa, noto'g'ri bo'ldim. Ushbu kompilyatorning hujjatlarida ko'rsatilishi kerak.
qo'shib qo'ydi muallif Olaf, manba
Ha, roziman. Men javobni yangilangan platforma va derleyici qaramligi haqida biroz aniqroq bo'lish uchun yangiladim.
qo'shib qo'ydi muallif lurker, manba