До 255 я могу понять, как целые числа хранятся в char
а также unsigned char
;
#include<stdio.h>
int main()
{
unsigned char a = 256;
printf("%d\n",a);
return(0);
}
В приведенном выше коде у меня есть вывод 0 за символ без знака так же как голец.
За 256 Я думаю, что это способ хранения целого числа в коде (это всего лишь предположение):
Первый 256 преобразуется в двоичное представление, которое 100000000 (всего 9 бит).
Затем они удаляют удалить крайний левый бит (бит, который установлен), потому что тип данных char имеет только 8 бит памяти.
Таким образом, его хранение в памяти, как 00000000 , вот почему его печать 0 в качестве вывода.
Правильно ли предположение или есть какое-то другое объяснение?
Ваше предположение верно. Преобразование в тип без знака использует модульную арифметику: если значение выходит за пределы диапазона (либо слишком большое, либо отрицательное), то оно уменьшается по модулю 2N, где N — количество битов в целевом типе. Так что, если (как это часто бывает) char
имеет 8 битов, значение уменьшается по модулю 256, так что 256 становится равным нулю.
Обратите внимание, что такого правила для преобразования в тип со знаком не существует — значения вне диапазона дают результаты, определенные реализацией. Также обратите внимание, что char
не указано, что оно имеет ровно 8 бит, и может быть больше на менее популярных платформах.
На вашей платформе (как и на любой другой «нормальной» платформе) unsigned char
имеет ширину 8 бит, поэтому он может содержать числа от 0 до 255.
Попытка назначить 256 (что является int
буквально) к этому приводит к целочисленное переполнение без знака, это определено стандартом, чтобы привести к «циклу». Результат u = n
где u
является целым типом без знака и n
целое число без знака вне диапазона u = n % (max_value_of_u +1)
,
Это просто запутанный способ сказать то, что вы уже сказали: стандарт гарантирует, что в этих случаях присваивание выполняется с сохранением только тех битов, которые соответствуют целевой переменной. Эта норма существует, поскольку большинство платформ уже реализуют это на уровне ассемблера (целочисленное переполнение без знака обычно приводит к такому поведению плюс некоторый флаг переполнения, установленный на 1
).
Обратите внимание, что все это не распространяется на целые числа со знаком (как это часто бывает char
является): подписанный Целочисленное переполнение — неопределенное поведение.
Да, это правильно. 8 бит могут содержать от 0 до 255 без знака или от -128 до 127 со знаком. Выше этого, и вы попали в ситуацию переполнения, и биты будут потеряны.
Компилятор выдает предупреждение по приведенному выше коду? Вы можете увеличить уровень предупреждения и что-то увидеть. Он не предупредит вас, если вы назначите переменную, которая не может быть определена статически (до выполнения), но в этом случае совершенно ясно, что вы назначаете что-то слишком большое для размера переменной.