Данные копируются правильно, побитно, как вы хотели. Это просто печать, которая отображает его как значение со знаком, потому что arr
объявлен как массив значений без знака.
%d
выводит данные, переданные как int
s (по стандартному определению? Не уверен), что на обычных платформах составляет 4 байта. Аргумент, переданный в printf
, перед печатью обновляется до int
, что, в зависимости от того, подписан ли рассматриваемый аргумент или нет, потребует расширения знака или нет.
При печати i
, которое является значением со знаком, значение будет расширено знаком перед печатью. Например, если i
равно -1
(который представлен как 0xFFFF
в 2-байтовом значении со знаком с использованием дополнения до двух), то i
будет обновлено как int
значение 0xFFFFFFFF
(которое также равно -1
, но представлено четырьмя байтами).
Однако, если i
равно -1
, тогда при выполнении arr[arrIndex] = i
arr[arrIndex]
действительно будет установлено в 0xFFFF
, и будет копироваться побитно, как вы хотели. Однако, поскольку arr[arrIndex]
беззнаковый, в мире беззнакового 0xFFFF
представляет 65535
. Затем, когда придет время печатать arr[arrIndex]
, поскольку arr[arrIndex]
беззнаковый, значение не будет расширено по знаку, так как это беззнаковое значение. Следовательно, 0xFFFF
будет обновлен до 0x0000FFFF
, что равно 65535
, и напечатан как таковой.
Мы можем проверить это, заставив arr
считаться подписанным перед печатью. Таким образом, arr
будет обрабатываться так же, как i
.
#include <stdio.h>
int main() {
unsigned short arr[450];
unsigned short arrIndex = 0;
for (signed short i = -32768; i < (32767 - 100) ; i = i + 100 )
{
arr[arrIndex] = i;
printf("short value is : %d\n", i);
printf("unsigned short value is : %d\n", ((signed short*)arr)[arrIndex]);
arrIndex++;
}
}
Выход:
short value is : -32768
unsigned short value is : -32768
short value is : -32668
unsigned short value is : -32668
short value is : -32568
unsigned short value is : -32568
short value is : -32468
unsigned short value is : -32468
short value is : -32368
unsigned short value is : -32368
short value is : -32268
unsigned short value is : -32268
short value is : -32168
unsigned short value is : -32168
Или мы могли бы напрямую объявить arr
как массив значений со знаком для достижения того же результата:
#include <stdio.h>
int main() {
signed short arr[450];
unsigned short arrIndex = 0;
for (signed short i = -32768; i < (32767 - 100) ; i = i + 100 )
{
arr[arrIndex] = i;
printf("short value is : %d\n", i);
printf("unsigned short value is : %d\n", arr[arrIndex]);
arrIndex++;
}
}
person
AnthonyD973
schedule
05.05.2020
int
32-битный, а не 16-битный? - person Weather Vane   schedule 05.05.2020%d
и что вы подразумеваете под целыми числами. Наименьший размерint
составляет 16 бит. Целочисленные аргументы для вариативной функции, которые меньше, чем исходнаяint
, будут повышены доint
в соответствии с обычными целочисленными правилами продвижения. Если вашint
32 бита, он может обрабатывать весь диапазонsigned short
иunsigned short
. - person Weather Vane   schedule 05.05.2020arrIndex
в конце этого цикла? В противном случае вы получите неверное значение. - person templatetypedef   schedule 05.05.2020%X
интерпретирует любые передаваемые вами данные какunsigned
, аprintf
не знает и не заботится о том, как вы определили значение, которое ему было передано. Он видит спецификатор формата во время выполнения и соответствующим образом интерпретирует предоставленные вами байты. Если вы не соответствуете типам, например, передаетеdouble
вместо%X
, он вслепую смотрит на 4 байта и делает то, что ему говорят. - person Weather Vane   schedule 05.05.20201
, значение трактуется как отрицательное (в большинстве систем с двумя компиляциями). Если он рассматривается как неподписанный, особого обращения нет. Так что то, что находится в памяти, не меняется - меняется только то, как вы интерпретируете биты. - person David C. Rankin   schedule 05.05.2020"%X"
могут адресовать недопустимую память. МАК, то есть УБ. - person chux - Reinstate Monica   schedule 05.05.2020