#include <stdio.h>
#include <string.h>
main()
{
short int x=0x55AA;
printf("%x ",~x);
}
Горната програма дава резултат: ffffaa55. Очаквах o/p само aa55, тъй като short int е 2 байта. Може ли някой да го обясни?
#include <stdio.h>
#include <string.h>
main()
{
short int x=0x55AA;
printf("%x ",~x);
}
Горната програма дава резултат: ffffaa55. Очаквах o/p само aa55, тъй като short int е 2 байта. Може ли някой да го обясни?
Ти имаш:
short int x = 0x55AA;
~x;
Изразът ~x
има тип int
.
int
независимо от това какъв форматен спецификатор се използва. (И %x
всъщност е спецификатор на формат unsigned int
)
- person AnT; 30.08.2014
char
е със знак или без знак. Така че, в зависимост от вашата реализация, ~x
се повишава или до signed int
, или до unsigned int
.
- person Bill Lynch; 30.08.2014
char
... е повишен или до signed int
, или до unsigned int
. Ако int
може да представи всички стойности от оригиналния тип (както е ограничено от ширината, за битово поле), стойността се преобразува в int; в противен случай се преобразува в unsigned int. Те се наричат целочислени промоции C11dr §6.3.1.1 2. Това за мен означава, че 8-битови char
, signed/unsigned
или нито едно от тях няма да бъде повишено до int
, а не unsigned
.
- person chux - Reinstate Monica; 31.08.2014
char
е по-тесен от int
, char
винаги се повишава до int
със знак, независимо дали самият char
е със знак или без знак.
- person AnT; 31.08.2014
Езикът C никога не извършва изчисления в типове, по-тесни от [signed/unsigned] int
. Всеки път, когато използвате стойност от по-тесен тип (като short
или char
) в израз, тази стойност имплицитно се повишава до [signed/unsigned] int
. Една важна подробност тук е, че дори оригиналният тесен тип да е unsigned
, той пак ще бъде повишен до подписан тип int
(ако приемем, че се вписва в диапазона от int
). Това е нещо, което трябва да се има предвид в такива случаи.
Обърнете внимание, че не само изразът ~x
има тип int
, а самият x
е повишен в int
дори преди ~
да има шанс да направи нещо. С други думи, вашето ~x
се интерпретира като ~(int) x
.
Ако имате нужда от резултат от оригиналния тесен тип, трябва изрично да го конвертирате обратно в оригиналния тип. В случай на printf
, където явното преобразуване няма да реши нищо (тъй като променливият аргумент така или иначе ще бъде преобразуван в int
), можете да използвате спецификатори на формат printf
, за да интерпретирате съответния аргумент като стойност от по-тесен тип.
Като странична бележка, спецификаторът на формат %x
очаква аргумент от тип unsigned int
. Предаването на отрицателна int
стойност вместо това не е разрешено.
Освен това винаги е по-добра идея да използвате неподписани типове за всякакви операции със семантика на битово ниво.
~x
обратно към short int
, той ще бъде повишен до int
отново, когато бъде прехвърлен към printf
. В този момент вероятно ще бъде разширен знак (тъй като msb вече е зададен). За да получите желаното поведение, трябва да бъде прехвърлено към unsigned short
или трябва да използвате правилния спецификатор на формат.
- person pat; 30.08.2014
~x
стойностите от тип char
се преобразуват в int
по абсолютно същия начин. Единственият проблем е, че 0x55AA
няма да се побере в типичен char
.
- person AnT; 30.08.2014
main()
{
short int x=0x55AA;
printf("%x ",~x);
}
Тук ~x се третира като signed int. Ако искате o/p като aa55, тогава трябва да направите typecast към unsigned short in. Така че, опитайте така..
main()
{
short int x=0x55AA;
printf("%x ",(unsigned short int)~x);//typecasting
}
В по-голямата си част аритметичните и логическите оператори са дефинирани за int и long, израз, включващ по-малки типове, включва имплицитно преобразуване и резултатът ще бъде по-големият тип.
Освен това "%x" във всеки случай е спецификатор на int формат без знак.
Има различни решения, напр.
short x = 0x55AA ;
short nx = ~x ;
printf("%x ",~nx) ;
short x = 0x55AA ;
printf("%x ",~x & 0x0000FFFF ) ;
~x
и-x
дават различни резултати. Не разбрах въпроса - моя грешка. - person Benjamin Gruenbaum   schedule 30.08.2014~x
е нечие допълнение къмx
.. - person chux - Reinstate Monica   schedule 31.08.2014