Почему у нас есть тип char в C, если символьный литерал всегда имеет тип int? Разве весь тип char в C не является избыточным?

В отличие от C++, в C символьный литерал всегда имеет тип int.


Но почему тогда у нас есть тип char для хранения символьного значения?


В вопросе Почему литералы символов C представляют собой целые числа вместо символов? < / а>,

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

Внутри вопроса Если символьные константы имеют тип `int', почему они присваиваются переменным типа `char`? тогда мы углубляемся в вопрос, почему мы на самом деле присваиваем символьные литералы переменным типа char если они типа int, но предоставленные ответы оставили озабоченность, зачем вообще нужен тип char.


Мои вопросы сейчас:

  • Почему у нас тип char, если любые символьные литералы всегда имеют тип int?
  • Тогда не является ли тип char избыточным?
  • Какова цель типа char, если он кажется избыточным?

person RobertS supports Monica Cellio    schedule 23.12.2019    source источник
comment
Как вы собираетесь объявлять массив символов, если тип char будет отсутствовать?   -  person Vlad from Moscow    schedule 23.12.2019
comment
@VladfromMoscow Концепция всего типа char сейчас кажется мне неверной. Для меня язык должен был быть определен по-другому в этой теме, чтобы дать модификатор или что-то в этом роде, чтобы указать компилятору, что контекст, если необходимо, относится к буквальным символам, а не к обычным целочисленным значениям. , используя тип int.   -  person RobertS supports Monica Cellio    schedule 23.12.2019
comment
Деталь: В отличие от C++, в C символьная константа ...... C не определяет символьный литерал. В C литерал может иметь свой адрес.   -  person chux - Reinstate Monica    schedule 23.12.2019
comment
@chux-ReinstateMonica Хорошо, с определением символьного литерала, которого нет в стандарте C, я понимаю. Но я думал, что литералы — это только жестко закодированные значения. Как у них могут быть адреса?   -  person RobertS supports Monica Cellio    schedule 23.12.2019
comment
Тип char и литеральная константа char являются двумя отдельными объектами, размеры которых определяются в соответствии со стандартом как наименьшая единица памяти, доступная в системе, для первого и как стандартный тип int для второго. Любая попытка сделать эквивалентность между типом char и литералом char, то есть 'abc', формально неверна.   -  person Frankie_C    schedule 23.12.2019
comment
Символ может иметь разное измерение на разных машинах, 8, 16 или даже 32 бита, а присваивание между символьным литералом и переменной char подразумевает преобразование типа из int в char.   -  person Frankie_C    schedule 23.12.2019
comment
re В C литерал существует в некоторой ячейке памяти, поэтому у него есть адрес. Исследуйте строковый литерал, составной литерал. Константа типа 'A' не обязательно должна существовать по адресу - например. может быть значением в исполняемом коде.   -  person chux - Reinstate Monica    schedule 23.12.2019
comment
Концепция всего типа char сейчас кажется мне неверной. -- Миллионы программистов думают иначе... когда начинающие программисты задают вопрос, им лучше немного посидеть и послушать, прежде чем делать собственные выводы. Для меня язык должен был быть определен по-другому в этой теме ... -- Трудно понять смысл этого и остального предложения.   -  person Jim Balter    schedule 24.12.2019


Ответы (3)


Тот факт, что символьная константа в исходном коде C имеет тип int, не означает, что тип char бесполезен.

Тип char занимает 1 байт. Таким образом, вы можете использовать его везде, где значения находятся в диапазоне char, который включает символы ASCII. Вы можете читать и записывать эти символы либо из консоли, либо из файла как однобайтовые объекты. Тот факт, что символьная константа в исходном коде имеет другой тип, этого не меняет.

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

char * также можно использовать для доступа к отдельным байтам любого объекта, если вам нужно увидеть, как этот объект представлен.

person dbush    schedule 23.12.2019
comment
... но обратите внимание, что когда char передается в качестве аргумента функции, он сначала превращается в int, вероятно, потому, что нет машины, которая может поместить один байт в стек. - person Paul Ogilvie; 23.12.2019
comment
@PaulOgilvie С точки зрения ABI да, однако с точки зрения языка переменная типа char, переданная функции, которая ожидает аргумент типа char, не будет преобразована. - person dbush; 23.12.2019
comment
@PaulOgilvie Это неправда. Большинство 8-битных микроконтроллеров могут размещать отдельные байты в стеке и/или передавать их в качестве аргументов с помощью регистров. - person th33lf; 23.12.2019
comment
@PaulOgilvie обратите внимание, что когда char передается в качестве аргумента функции, он сначала превращается в int - это верно только в том случае, если нет прототипа. Если есть прототип, то char может занимать или не занимать в стеке столько же байтов, сколько int, в зависимости от определения вызывающей последовательности. вероятно, потому, что нет машины, которая может поместить в стек один байт — нет, это неправда и не имеет ничего общего с тем, почему char и short преобразуются в int в отсутствие прототипа. (И комментарий dbush не имеет смысла.) - person Jim Balter; 24.12.2019
comment
@dbush Есть ли разница между символьными константами и символами ASCII? Я думал, что они будут одинаковыми. - person RobertS supports Monica Cellio; 24.12.2019
comment
@RobertS-ReinstateMonica ASCII — это особая кодировка символов. Например, ASCII сопоставляет символ 'A' со значением 65, а EBCDIC сопоставляет 'A' со значением 193. Константы символов в языке C сопоставляются любой кодировке, используемой работающей системой. - person dbush; 24.12.2019

Тип char позволяет адресовать каждый байт (наименьшую адресуемую единицу ЦП). Так, например, он позволяет указать объем памяти любого количества байтов, например, для использования в memcpy или memmove.

Также как объявить массив символов без типа char?

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

person Vlad from Moscow    schedule 23.12.2019

Почему у нас есть тип char в C, если символьный литерал всегда имеет тип int?

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

Разве весь тип char в C не является избыточным?
Почему у нас есть тип char, если любые символьные литералы всегда имеют тип int?
Разве тогда тип char не является избыточным?

Нет. Размеры объектов выигрывают от различных размеров, а константы — в меньшей степени.

Какова цель типа char, если он кажется избыточным?

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


Код может формировать составной литерал типа char, если требуется "литерал char`". .

char a = (char){'B'};
person chux - Reinstate Monica    schedule 23.12.2019