Подтвердить что ты не робот

Реальная разница между "int" и "unsigned int"

Int

32-разрядный тип данных int может хранить целые значения в диапазоне  -2,147,483,648 до 2,147,483,647. Вы также можете обратиться к этому типу данных  как подписанный int или подписанный.

unsigned int:

32-битные беззнаковые данные int  тип может содержать целые значения в диапазоне от 0 до 4 294 967 295. Вы  также может ссылаться на этот тип данных просто как unsigned.

Хорошо, но на практике:

int x = 0xFFFFFFFF;
unsigned int y = 0xFFFFFFFF;
printf("%d, %d, %u, %u", x, y, x, y);
// -1, -1, 4294967295, 4294967295

нет разницы, О. Я немного смущен.

4b9b3361

Ответ 1

Хех. У вас есть неявный бросок здесь, потому что вы говорите printf, какого типа ожидать.

Попробуйте это вместо этого:

unsigned int x = 0xFFFFFFFF;
int y = 0xFFFFFFFF;

if (x < 0)
    printf("one\n");
else
    printf("two\n");
if (y < 0)
    printf("three\n");
else
    printf("four\n");

Ответ 2

Да, потому что в вашем случае они используют то же представление.

Бит-шаблон 0xFFFFFFFF выглядит как -1, когда интерпретируется как целое число со знаком 32b и как 4294967295, когда интерпретируется как целое число без знака 32b.

Это то же самое, что и char c = 65. Если вы интерпретируете его как целое число со знаком, то оно 65. Если вы интерпретируете его как символ, то a.


Как показывают R и pmg, технически это поведение undefined для передачи аргументов, которые не соответствуют спецификаторам формата. Таким образом, программа может делать что угодно (от печати случайных значений до сбоев, печати "правильной" вещи и т.д.).

Стандарт указывает на 7.19.6.1-9

Если спецификация преобразования недействительна, поведение не определено. Если любой аргумент не является правильным типом для соответствующего преобразования спецификация, поведение не определено.

Ответ 3

Нет никакой разницы между ними в том, как они хранятся в памяти и регистры, нет никакой подписанной и неподписанной версии int-регистров, нет никакой подписанной информации, хранящейся в int, разница становится актуальной только при выполнении математических операций, есть подписанная и неподписанная версия математических операций, встроенных в ЦП, и подписанность сообщает компилятору, какую версию использовать.

Ответ 4

Проблема заключается в том, что вы вызывали Undefined поведение.


Когда вы вызываете UB, все может случиться.

Назначения в порядке; существует неявное преобразование в первой строке

int x = 0xFFFFFFFF;
unsigned int y = 0xFFFFFFFF;

Однако вызов printf не работает

printf("%d, %d, %u, %u", x, y, x, y);

UB не соответствует спецификатору % и типу аргумента.
В вашем случае вы укажете 2 int и 2 unsigned int в этом порядке, предоставив 1 int, 1 unsigned int, 1 int и 1 unsigned int.


Не выполняйте UB!

Ответ 5

Внутреннее представление int и unsigned int одинаков.

Поэтому, когда вы передаете одну строку формата в printf, она будет напечатана как одна и та же.

Однако при сравнении они отличаются. Рассмотрим:

int x = 0x7FFFFFFF;
int y = 0xFFFFFFFF;
x < y // false
x > y // true
(unsigned int) x < (unsigned int y) // true
(unsigned int) x > (unsigned int y) // false

Это также может быть оговоркой, потому что при сравнении целого числа, подписанного и без знака, одно из них будет неявно выбрано для соответствия типам.

Ответ 6

тип просто сообщает вам, что должен представлять битовый шаблон. биты - это только то, что вы их делаете. одни и те же последовательности можно интерпретировать по-разному.

Ответ 7

Функция printf интерпретирует значение, которое вы передаете в соответствии с спецификатором формата в соответствующей позиции. Если вы сообщите printf, что вы передаете int, но передаете unsigned вместо этого, printf будет переинтерпретировать один как другой и распечатать результаты, которые вы видите.

Ответ 8

Он спрашивает о реальной разнице. Когда вы говорите о поведении undefined, вы находитесь на уровне гарантии, предоставляемой спецификацией языка, - это далеко не реальность. Чтобы понять реальную разницу, проверьте этот фрагмент (конечно, это UB, но он отлично определен в вашем любимом компиляторе):

#include <stdio.h>

int main()
{
    int i1 = ~0;
    int i2 = i1 >> 1;
    unsigned u1 = ~0;
    unsigned u2 = u1 >> 1;
    printf("int         : %X -> %X\n", i1, i2);
    printf("unsigned int: %X -> %X\n", u1, u2);
}

Ответ 9

Это довольно прямолинейно. Бинарное представление - это ключ, о котором он упоминается, но никогда не отображается. Без знака в HEX, если 0XFFFFFFF = машинный код = 1111 1111 1111 1111 1111 1111 1111 1111 = 4 294 967 295 положительные представления числа. Это все прекрасно и денди, но нам нужен способ представления отрицательных чисел. Таким образом, мозги решили добавить два дополнения. Что это значит хорошо, короче говоря, они взяли левую самую цифру и решили, что, когда она равна 1 (за ней следуют все до тех пор, пока вы не достигнете самого значимого бита), число будет отрицательным, если оно положительно. Теперь посмотрим, что произойдет 0000 0000 0000 0000 0000 0000 0000 0011 = 3. Теперь давайте продолжим добавлять к этому числу 0111 1111 1111 1111 1111 1111 1111 1111 = 2,147,483,645 наивысшее положительное число с подписанным int. Пусть добавьте 1 (здесь вы можете посмотреть бинарное дополнение) мы должны довести этот путь до конца. 1111 1111 1111 1111 1111 1111 1111 1110 = -1 Поэтому я предполагаю, что вкратце можно сказать, что разница в том, что одна из них допускает отрицательные числа, а другая - не из-за знака знака или оставила самый бит или самый старший бит.