Данные копируются правильно, побитно, как вы хотели. Это просто печать, которая отображает его как значение со знаком, потому что 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++;
}
}