Является неподписанным char я эквивалентом unsigned j?

В следующей программе я использовал ключевое слово unsigned.

#include <stdio.h>

int main()
{
        unsigned char i = 'A';
        unsigned j = 'B';
        printf(" i = %c j = %c", i, j);
}

Вывод:

 i = A j = B

Является ли unsigned char i эквивалентным unsigned j?

Ответ 1

Является ли unsigned char i эквивалентным unsigned j?

Нет, когда спецификатор типа опущен и используются какие-либо из спецификаторов signed, unsigned, short или long, предполагается int.

Это означает, что следующие объявления эквивалентны:

long a;
long int a;

unsigned short b;
unsigned short int b;

Проблема с подписью char заключается в том, что когда signed или unsigned опущено, подпись зависит от реализации:

char x; // signedness depends on the implementation
unsigned char y; // definitely unsigned
signed char z; // definitely signed

Ответ 2

unsigned, int и char являются так называемыми спецификаторами типов. Правила в спецификаторах типа C имеют странные и иррациональные причины, иногда по соображениям обратной совместимости.

Глава 6.7.2/2 стандарта C выполняется следующим образом:

  • signed char означает signed char.
  • unsigned char означает unsigned char.
  • char - это отдельный тип, отличный от двух выше, и может быть либо подписанным, либо беззнаковым. Зависит от компилятора.
  • short, signed short, short int, или signed short int означает short.
  • unsigned short, или unsigned short int означает unsigned short.
  • int, signed, или signed int означает int.
  • unsigned, или unsigned int означает unsigned int.
  • long, signed long, long int или signed long int означает long.

И так далее. Если вы считаете, что эта система не имеет большого смысла, это потому, что она не делает.

Учитывая вышеизложенное, мы можем сказать, что unsigned char и unsigned - разные типы.

Однако для всех переменных-аргументов, таких как printf, существует специальное правило case (называемое "продвижением аргументов по умолчанию" ), говорящее, что все мелкие целые типы, такие как char, неявно продвигаются до типа int. Вот почему вы можете printf("%d" для символов, а также для целых чисел. Точно так же %c работает для целых чисел, потому что на самом деле невозможно, чтобы printf получал реальный, не продвигаемый тип символа через его параметры. Все, что типа int или меньше, закончится как int на стороне printf.

Ответ 3

Нет, они не эквивалентны. unsigned char и unsigned - два разных типа (unsigned эквивалентно unsigned int). Они оба являются неподписанными целыми типами, и они могут содержать одни и те же значения.

Спецификатор формата %c для printf ожидает аргумент типа int (который представляет собой целочисленный тип со знаком). Аргумент unsigned char продвигается до int, так что это нормально. Аргумент unsigned int не преобразуется в int, но в этом случае он работает (по причинам, в которые я не буду вдаваться).

Обратите внимание, что символьные константы типа 'A' также имеют тип int.

Ответ 4

Nopes, unsigned j совпадает с unsigned int j.

Согласно C11, глава §6.7.2, спецификаторы типа

unsigned, или unsigned int

Таким образом, очевидно, что опускание int все еще делает переменную целой.

Таким образом, чтобы устранить любую путаницу, списки спецификаций

  • unsigned char

...

  • unsigned, или unsigned int

как два разных типа спецификатора, поэтому, очевидно, они не совпадают.

Ответ 5

Ответ: Нет.

Всякий раз, когда вы не укажете тип в следующих случаях signed unsigned long short, и вы назначаете номер по умолчанию, он принимает значение int.

В случае символов

char a; // Depends on implementations.
signed char b; // Signed
unsigned char c; // Unsigned

Ответ 6

Зависит немного от компилятора и архитектуры, но, как правило, unsigned int имеет длину 4 или 8 байтов, unsigned char обычно имеет длину 1 октет.

Это означает, что unsigned занимает от 4 до 8x пробел и может содержать гораздо большее число (например, unsigned может содержать номер 1024, а типичный unsigned char может содержать только до 255). В зависимости от точности вашего процессора первый октет без знака может быть таким же, как беззнаковая char версия (или нет).

Пока вы не заботитесь об использовании памяти, переполнении или не пытаетесь делать странные вещи с помощью указателей, это одно и то же. Но они начинают отличаться быстро, когда вы начинаете делать более интересные вещи в C.