El único libro de referencia C en el que confío es "C: A Reference Manual" de Harbison & Steele ( careferencemanual.com ). Por supuesto, el estándar es la última palabra, pero no es muy legible y solo brinda la más mínima información sobre usos pre-estándar y comunes (es decir, POSIX) que están fuera del estándar. Harbison & Steele es bastante legible, detallado y probablemente más correcto que la mayoría de las referencias. Sin embargo, tampoco es un tutorial, por lo que si estás en las etapas iniciales de aprendizaje, probablemente no sea una gran cosa para saltar.
Michael Burr el
15
Creo que el libro que estás leyendo es C: The Complete Reference , de Herbert Schildt. De una revisión de este libro ( accu.informika.ru/accu/bookreviews/public/reviews/c/c002173.htm ): No voy a recomendar este libro (muchos de ustedes dan demasiado peso a mis opiniones) pero No creo que merezca el mismo oprobio que se ha arrojado legítimamente a algunos de sus otros trabajos. Como dice Michael, una referencia mucho mejor es Harbison & Steele .
Alok Singhal el
Mis dos centavos aquí: porque charpuede ser sin signo, como regla general, use un intpara leer un valor usando getchar(), lo que podría devolver EOF. EOFgeneralmente se define como -1u otro valor negativo, que almacenar en un unsignedno es lo que desea. Aquí está la declaración: extern int getchar();Por cierto, esta recomendación también proviene del libro "C: A Reference Manual".
Maxim Chetrusca
66
La única referencia C en la que confío es ISO / IEC 9899: 2011 :-)
Jeff
3
@MaxChetrusca buenos consejos pero mala lógica: incluso en el charcaso firmado , tendría que usar intpara almacenar el valor de retorno.
Antti Haapala
Respuestas:
204
El libro esta equivocado. El estándar no especifica si plain charestá firmado o no.
De hecho, la norma define tres tipos distintos: char, signed char, y unsigned char. Si usted #include <limits.h>y luego mira CHAR_MIN, puede averiguar si chares simple signedo unsigned(si CHAR_MINes menor que 0 o igual a 0), pero aun así, los tres tipos son distintos en lo que respecta al estándar.
Tenga en cuenta que chares especial de esta manera. Si declara una variable ya intque es 100% equivalente a declararla como signed int. Esto siempre es cierto para todos los compiladores y arquitecturas.
@Alok: lo mismo no es cierto para algunos otros tipos de datos, por ejemplo, intsignifica signed intsiempre, ¿verdad? Además de char, ¿en qué otros tipos de datos tienen la misma confusión C?
Lazer
8
@eSKay: sí, chares el único tipo que se puede firmar o no. intes equivalente a signed intpor ejemplo.
Alok Singhal
28
Hay una razón histérica, er, histórica para esto: al principio de la vida de C, el "estándar" se volcó al menos dos veces, y algunos compiladores tempranos populares terminaron de una manera y otros de otra.
Hot Licks
9
@AlokSinghal: También está definido por la implementación si un campo de tipo de bit intestá firmado o no.
Keith Thompson
@KeithThompson gracias por la corrección. Tiendo a olvidar algunos detalles sobre los tipos de campo de bits ya que no los uso mucho.
Alok Singhal
67
Como señala Alok , el estándar lo deja a la implementación.
Para gcc, el valor predeterminado está firmado, pero puede modificarlo con -funsigned-char. nota: para gcc en Android NDK, el valor predeterminado es sin signo . También puede solicitar explícitamente caracteres firmados con -fsigned-char.
En MSVC, el valor predeterminado está firmado pero puede modificarlo con /J.
Es interesante que la descripción de Schildt no coincida con el comportamiento de MSVC ya que sus libros generalmente están dirigidos a usuarios de MSVC. Me pregunto si MS cambió el valor predeterminado en algún momento?
Michael Burr el
1
Pensé que no dependía del compilador, sino de la plataforma. Pensé que char se dejó como un tercer tipo de "tipo de datos de caracteres" para ajustarse a lo que los sistemas en ese momento usaban como caracteres imprimibles.
Spidey
10
Los documentos de GCC dicen que depende de la máquina: " Cada tipo de máquina tiene un valor predeterminado para lo que debería ser. Es como un carácter sin signo por defecto o como un carácter firmado por defecto " .
Deduplicador
1
¿Puede proporcionar una fuente para su nota de que en Android el valor predeterminado es char sin firmar?
phlipsy
1
@Spidey, el estándar C no hace una distinción real entre compiladores, plataformas y arquitecturas de CPU. Simplemente los agrupa a todos bajo "implementación".
lavado el
35
C99 N1256 draft 6.2.5 / 15 "Tipos" tiene esto que decir sobre la firma del tipo char:
La implementación definirá char para que tenga el mismo rango, representación y comportamiento que el char con signo o el sin signo.
y en una nota al pie:
CHAR_MIN, definido en <limits.h>, tendrá uno de los valores 0o SCHAR_MIN, y esto puede usarse para distinguir las dos opciones. Independientemente de la elección realizada, chares un tipo separado de los otros dos y no es compatible con ninguno.
De acuerdo con el libro The C Programming Language de Dennis Ritchie, que es el libro estándar de facto para ANSI C, los caracteres simples con o sin signo dependen de la máquina, pero los caracteres imprimibles siempre son positivos.
No es necesariamente el caso de que los caracteres imprimibles sean siempre positivos. El estándar C garantiza que todos los miembros del juego de caracteres de ejecución básica tengan valores no negativos.
Keith Thompson
7
De acuerdo con el estándar C, la firma de char simple es "implementación definida".
En general, los implementadores eligieron el que fuera más eficiente para implementar en su arquitectura. En los sistemas x86, char generalmente está firmado. En los sistemas de brazo generalmente no está firmado (Apple iOS es una excepción).
@plugwash Su respuesta probablemente fue rechazada porque Tim Post perdió sus llaves . Sin embargo, en serio, no debe preocuparse por un solo voto negativo siempre y cuando esté seguro de que su respuesta es correcta (que es en este caso). Me han sucedido varias veces que mis publicaciones fueron rechazadas sin ningún motivo válido. No te preocupes por eso, a veces las personas simplemente hacen cosas extrañas.
Pato Donald
1
¿Por qué es firmado char más eficiente en x86? Alguna fuente?
martinkunev
2
De acuerdo con "El lenguaje de programación C ++" de Bjarne Stroustrup, chares "implementación definida". Puede ser signed charo unsigned chardepende de la implementación. Puede verificar si charestá firmado o no mediante el uso std::numeric_limits<char>::is_signed.
char
puede ser sin signo, como regla general, use unint
para leer un valor usandogetchar()
, lo que podría devolverEOF
.EOF
generalmente se define como-1
u otro valor negativo, que almacenar en ununsigned
no es lo que desea. Aquí está la declaración:extern int getchar();
Por cierto, esta recomendación también proviene del libro "C: A Reference Manual".char
caso firmado , tendría que usarint
para almacenar el valor de retorno.Respuestas:
El libro esta equivocado. El estándar no especifica si plain
char
está firmado o no.De hecho, la norma define tres tipos distintos:
char
,signed char
, yunsigned char
. Si usted#include <limits.h>
y luego miraCHAR_MIN
, puede averiguar sichar
es simplesigned
ounsigned
(siCHAR_MIN
es menor que 0 o igual a 0), pero aun así, los tres tipos son distintos en lo que respecta al estándar.Tenga en cuenta que
char
es especial de esta manera. Si declara una variable yaint
que es 100% equivalente a declararla comosigned int
. Esto siempre es cierto para todos los compiladores y arquitecturas.fuente
int
significasigned int
siempre, ¿verdad? Además dechar
, ¿en qué otros tipos de datos tienen la misma confusiónC
?char
es el único tipo que se puede firmar o no.int
es equivalente asigned int
por ejemplo.int
está firmado o no.Como señala Alok , el estándar lo deja a la implementación.
Para gcc, el valor predeterminado está firmado, pero puede modificarlo con
-funsigned-char
. nota: para gcc en Android NDK, el valor predeterminado es sin signo . También puede solicitar explícitamente caracteres firmados con-fsigned-char
.En MSVC, el valor predeterminado está firmado pero puede modificarlo con
/J
.fuente
C99 N1256 draft 6.2.5 / 15 "Tipos" tiene esto que decir sobre la firma del tipo
char
:y en una nota al pie:
fuente
De acuerdo con el libro The C Programming Language de Dennis Ritchie, que es el libro estándar de facto para ANSI C, los caracteres simples con o sin signo dependen de la máquina, pero los caracteres imprimibles siempre son positivos.
fuente
De acuerdo con el estándar C, la firma de char simple es "implementación definida".
En general, los implementadores eligieron el que fuera más eficiente para implementar en su arquitectura. En los sistemas x86, char generalmente está firmado. En los sistemas de brazo generalmente no está firmado (Apple iOS es una excepción).
fuente
De acuerdo con "El lenguaje de programación C ++" de Bjarne Stroustrup,
char
es "implementación definida". Puede sersigned char
ounsigned char
depende de la implementación. Puede verificar sichar
está firmado o no mediante el usostd::numeric_limits<char>::is_signed
.fuente
Ahora, sabemos que el estándar deja eso a la implementación.
Pero, ¿cómo verificar un tipo es
signed
ounsigned
, comochar
?Escribí una macro para hacer esto:
#define IS_UNSIGNED(t) ((t)~1 > 0)
y probarlo con
gcc
,clang
ycl
. Pero no estoy seguro de que siempre sea seguro para otros casos.fuente