Единственный справочник C, которому я доверяю, - это "C: Справочное руководство" Harbison & Steele ( careferencemanual.com ). Конечно, стандарт - это последнее слово, но он не очень читабелен и дает лишь малейшую информацию о предстандартном и обычном (то есть, POSIX) использовании, которые находятся за пределами стандарта. Harbison & Steele довольно читабелен, детален и, вероятно, более точен, чем большинство ссылок. Однако это также не учебник, поэтому, если вы находитесь на начальных этапах обучения, вам, вероятно, не стоит прыгать.
Майкл Берр
15
Я думаю, что книга, которую вы читаете, называется C: The Complete Reference , написанная Гербертом Шильдтом. Из обзора этой книги ( accu.informika.ru/accu/bookreviews/public/reviews/c/c002173.htm ): я не собираюсь рекомендовать эту книгу (слишком многие из вас придают слишком большое значение моему мнению), но Я не думаю, что это заслуживает того же осуждения, которое было законно брошено на некоторые другие его работы. Как говорит Майкл, гораздо лучше справиться с Harbison & Steele .
Алок Сингхал
Мои два цента здесь: Потому что charмогут быть без знака, как правило, использовать intдля чтения значения с использованием getchar(), которое может вернуть EOF. EOFобычно определяется как -1или другое отрицательное значение, сохранение unsignedкоторого не является тем, что вы хотите. Вот декларация: extern int getchar();Кстати, эта рекомендация также взята из книги "C: Справочное руководство".
Максим Четруска
6
Единственная ссылка C, которой я доверяю, - это ISO / IEC 9899: 2011 :-)
Джефф
3
@MaxChetrusca хороший совет, но плохое обоснование: даже для подписанного charслучая вам придется использовать intдля хранения возвращаемого значения.
Антти Хаапала
Ответы:
204
Книга не права. Стандарт не определяет, является ли обычный charподписанным или неподписанным.
На самом деле, стандарт определяет три различных типа: char, signed char, и unsigned char. Если вы, #include <limits.h>а затем посмотрите CHAR_MIN, вы можете узнать, charявляется ли значение равным signedили unsigned(если CHAR_MINоно меньше 0 или равно 0), но даже тогда эти три типа различны. в отношении стандарта.
Обратите внимание, что charэто особенный способ. Если вы объявляете переменную, так как intона на 100% эквивалентна объявлению ее как signed int. Это всегда верно для всех компиляторов и архитектур.
@Alok: то же самое не верно для некоторых других типов данных, например, intозначает signed intвсегда, верно? Кроме charкаких других типов данных есть такая же путаница C?
Lazer
8
@eSKay: да, charэто единственный тип, который может быть подписан или не подписан. intэквивалентно, signed intнапример.
Алок Сингхал,
28
Есть истерическая, э-э, историческая причина этого - в начале жизни C «стандарт» переворачивался как минимум дважды, и некоторые популярные ранние компиляторы заканчивались тем или иным способом, а другие - другим.
Hot Licks
9
@AlokSinghal: Также определяется, определено ли битовое поле типа со знаком intили без знака.
Кит Томпсон
@KeithThompson спасибо за исправление. Я склонен забывать некоторые детали о типах битовых полей, так как я их мало использую.
Алок Сингхал
67
Как указывает Алок , стандарт оставляет это до реализации.
Для gcc значение по умолчанию подписано, но вы можете изменить это с помощью -funsigned-char. примечание: для gcc в Android NDK по умолчанию используется без знака . Вы также можете явно запросить подписанные символы с -fsigned-char.
На MSVC значение по умолчанию подписано, но вы можете изменить его с помощью /J.
Интересно, что описание Шильдта не соответствует поведению MSVC, так как его книги обычно ориентированы на пользователей MSVC. Интересно, изменил ли MS по умолчанию в какой-то момент?
Майкл Берр
1
Я думал, что это зависит не от компилятора, а от платформы. Я думал, что char был оставлен как третий тип «символьного типа данных», чтобы соответствовать тому, что системы в то время использовали как печатные символы.
Spidey
10
НКА документы говорят , что машинно-зависимый: « Каждый вид машины имеет значение по умолчанию для того, что символ должен быть Это либо как неподписанный символ по умолчанию или как подписанный полукокс по умолчанию.. »
Deduplicator
1
Можете ли вы предоставить источник для вашей заметки, что на Android по умолчанию является unsigned char?
Phlipsy
1
@Spidey Стандарт C не проводит различий между компиляторами, платформами и архитектурами ЦП. Это просто смешивает их все вместе под «реализацией».
Реализация должна определять символ, чтобы иметь тот же диапазон, представление и поведение, что и подписанный символ или неподписанный символ.
и в сноске:
CHAR_MIN, определенный в <limits.h>, будет иметь одно из значений 0или SCHAR_MIN, и это может быть использовано для различения двух вариантов. Независимо от сделанного выбора, он charявляется отдельным типом от двух других и не совместим ни с одним из них.
В соответствии с книгой языка программирования C Дениса Ритчи, которая является де-факто стандартной книгой для ANSI C, простые символы, подписанные или неподписанные, зависят от машины, но печатные символы всегда положительны.
Это не обязательно тот случай, когда печатные символы всегда положительны. Стандарт C гарантирует, что все члены базового набора символов выполнения имеют неотрицательные значения.
Кит Томпсон
7
В соответствии со стандартом C подпись простого char - это «определение реализации».
В общем, разработчики выбирали тот, который был бы более эффективен для реализации на их архитектуре. На системах x86 char обычно подписывается. На системах arm это вообще без знака (Apple iOS - исключение).
@plugwash Ваш ответ, вероятно, был отклонен, потому что Тим Пост потерял свои ключи . Если серьезно, вам не следует беспокоиться об одном понижении, если вы уверены, что ваш ответ правильный (что в данном случае так и есть). Несколько раз со мной случалось, что мои посты были отклонены без уважительной причины. Не беспокойтесь об этом, иногда люди просто делают странные вещи.
Дональд Дак,
1
Почему подписанный char более эффективен на x86? Есть источники?
Мартинкунев
2
Согласно «Языку программирования C ++» Бьярна Страуструпа, char«определяется реализацией». Это может быть signed charили в unsigned charзависимости от реализации. Вы можете проверить, charподписано или нет, используя std::numeric_limits<char>::is_signed.
char
могут быть без знака, как правило, использоватьint
для чтения значения с использованиемgetchar()
, которое может вернутьEOF
.EOF
обычно определяется как-1
или другое отрицательное значение, сохранениеunsigned
которого не является тем, что вы хотите. Вот декларация:extern int getchar();
Кстати, эта рекомендация также взята из книги "C: Справочное руководство".char
случая вам придется использоватьint
для хранения возвращаемого значения.Ответы:
Книга не права. Стандарт не определяет, является ли обычный
char
подписанным или неподписанным.На самом деле, стандарт определяет три различных типа:
char
,signed char
, иunsigned char
. Если вы,#include <limits.h>
а затем посмотритеCHAR_MIN
, вы можете узнать,char
является ли значение равнымsigned
илиunsigned
(еслиCHAR_MIN
оно меньше 0 или равно 0), но даже тогда эти три типа различны. в отношении стандарта.Обратите внимание, что
char
это особенный способ. Если вы объявляете переменную, так какint
она на 100% эквивалентна объявлению ее какsigned int
. Это всегда верно для всех компиляторов и архитектур.источник
int
означаетsigned int
всегда, верно? Кромеchar
каких других типов данных есть такая же путаницаC
?char
это единственный тип, который может быть подписан или не подписан.int
эквивалентно,signed int
например.int
или без знака.Как указывает Алок , стандарт оставляет это до реализации.
Для gcc значение по умолчанию подписано, но вы можете изменить это с помощью
-funsigned-char
. примечание: для gcc в Android NDK по умолчанию используется без знака . Вы также можете явно запросить подписанные символы с-fsigned-char
.На MSVC значение по умолчанию подписано, но вы можете изменить его с помощью
/J
.источник
C99 N1256 черновик 6.2.5 / 15 «Типы» говорит о подписи типа
char
:и в сноске:
источник
В соответствии с книгой языка программирования C Дениса Ритчи, которая является де-факто стандартной книгой для ANSI C, простые символы, подписанные или неподписанные, зависят от машины, но печатные символы всегда положительны.
источник
В соответствии со стандартом C подпись простого char - это «определение реализации».
В общем, разработчики выбирали тот, который был бы более эффективен для реализации на их архитектуре. На системах x86 char обычно подписывается. На системах arm это вообще без знака (Apple iOS - исключение).
источник
Согласно «Языку программирования C ++» Бьярна Страуструпа,
char
«определяется реализацией». Это может бытьsigned char
или вunsigned char
зависимости от реализации. Вы можете проверить,char
подписано или нет, используяstd::numeric_limits<char>::is_signed
.источник
Теперь мы знаем, что стандарт оставляет это до реализации.
Но как проверить тип есть
signed
илиunsigned
, напримерchar
?Я написал макрос для этого:
#define IS_UNSIGNED(t) ((t)~1 > 0)
и проверить его
gcc
,clang
иcl
. Но я не уверен, что это всегда безопасно для других случаев.источник