Buscar..


Observaciones

  • Aunque se requiere que char sea ​​de 1 byte, no se requiere que 1 byte sea de 8 bits (a menudo también se denomina octeto ), aunque la mayoría de las plataformas de computadoras modernas lo definen como 8 bits. El número de bits de la implementación por char lo proporciona la macro CHAR_BIT , definida en <limits.h> . POSIX requiere 1 byte para ser de 8 bits.
  • Los tipos de enteros de ancho fijo deben usarse de forma dispersa, los tipos incorporados de C están diseñados para ser naturales en cada arquitectura, los tipos de ancho fijo solo deben usarse si necesita explícitamente un entero de tamaño específico (por ejemplo, para redes).

Tipos enteros y constantes

Los enteros con signo pueden ser de estos tipos ( int después de short o long es opcional):

signed char c = 127; /* required to be 1 byte, see remarks for further information. */
signed short int si = 32767; /* required to be at least 16 bits. */
signed int i = 32767; /* required to be at least 16 bits */
signed long int li = 2147483647; /* required to be at least 32 bits. */
C99
signed long long int li = 2147483647; /* required to be at least 64 bits */

Cada uno de estos tipos de enteros con signo tiene una versión sin firmar.

unsigned int i = 65535;
unsigned short = 2767;
unsigned char = 255;

Para todos los tipos, excepto char se asume la versión signed si se omite la parte signed o unsigned . El tipo char constituye un tercer tipo de carácter, diferente del signed char y unsigned char y la firma (o no) depende de la plataforma.

Se pueden escribir diferentes tipos de constantes enteras (llamadas literales en la jerga C) en diferentes bases y diferentes anchos, según su prefijo o sufijo.

/* the following variables are initialized to the same value: */
int d = 42;   /* decimal constant (base10) */
int o = 052;  /* octal constant (base8) */
int x = 0xaf; /* hexadecimal constants (base16) */
int X = 0XAf; /* (letters 'a' through 'f' (case insensitive) represent 10 through 15) */

Las constantes decimales siempre están signed . Las constantes hexadecimales comienzan con 0x o 0X y las constantes octales comienzan con 0 . Los dos últimos están signed o unsigned según si el valor se ajusta al tipo firmado o no.

/* suffixes to describe width and signedness : */
long int i = 0x32; /* no suffix represent int, or long int */
unsigned int ui = 65535u; /* u or U represent unsigned int, or long int */
long int li = 65536l; /* l or L represent long int */

Sin un sufijo, la constante tiene el primer tipo que se ajusta a su valor, es decir, una constante decimal que es más grande que INT_MAX es de tipo long si es posible, o long long contrario.

El archivo de encabezado <limits.h> describe los límites de los enteros de la siguiente manera. Sus valores definidos por la implementación serán iguales o mayores en magnitud (valor absoluto) a los que se muestran a continuación, con el mismo signo.

Macro Tipo Valor
CHAR_BIT Objeto más pequeño que no es un campo de bits (byte) 8
SCHAR_MIN signed char -127 / - (2 7 - 1)
SCHAR_MAX signed char +127 / 2 7 - 1
UCHAR_MAX unsigned char 255/2 8 - 1
CHAR_MIN char vea abajo
CHAR_MAX char vea abajo
SHRT_MIN short int -32767 / - (2 15 - 1)
SHRT_MAX short int +32767 / 2 15 - 1
USHRT_MAX unsigned short int 65535/2 16 - 1
INT_MIN int -32767 / - (2 15 - 1)
INT_MAX int +32767 / 2 15 - 1
UINT_MAX unsigned int 65535/2 16 - 1
LONG_MIN long int -2147483647 / - (2 31 - 1)
LONG_MAX long int +2147483647 / 2 31 - 1
ULONG_MAX unsigned long int 4294967295/2 32 - 1
C99
Macro Tipo Valor
LLONG_MIN long long int -9223372036854775807 / - (2 63 - 1)
LLONG_MAX long long int +9223372036854775807 / 2 63 - 1
ULLONG_MAX unsigned long long int 18446744073709551615/2 64 - 1

Si el valor de un objeto de tipo char -se extiende cuando se usa en una expresión, el valor de CHAR_MIN será el mismo que el de SCHAR_MIN y el valor de CHAR_MAX será el mismo que el de SCHAR_MAX . Si el valor de un objeto de tipo char no se extiende al signo cuando se usa en una expresión, el valor de CHAR_MIN será 0 y el valor de CHAR_MAX será el mismo que el de UCHAR_MAX .

C99

El estándar C99 agregó un nuevo encabezado, <stdint.h> , que contiene definiciones para enteros de ancho fijo. Consulte el ejemplo de entero de ancho fijo para obtener una explicación más detallada.

Literales de cuerda

Un literal de cadena en C es una secuencia de caracteres, terminada por un cero literal.

char* str = "hello, world"; /* string literal */

/* string literals can be used to initialize arrays */
char a1[] = "abc"; /* a1 is char[4] holding {'a','b','c','\0'} */
char a2[4] = "abc"; /* same as a1 */
char a3[3] = "abc"; /* a1 is char[3] holding {'a','b','c'}, missing the '\0' */

Los literales de cadena no son modificables (y, de hecho, se pueden colocar en la memoria de solo lectura, como .rodata). Intentar alterar sus valores resulta en un comportamiento indefinido.

char* s = "foobar";
s[0] = 'F'; /* undefined behaviour */

/* it's good practice to denote string literals as such, by using `const` */
char const* s1 = "foobar";
s1[0] = 'F'; /* compiler error! */

Varios literales de cadena se concatenan en tiempo de compilación, lo que significa que puede escribir construcciones como éstas.

C99
/* only two narrow or two wide string literals may be concatenated */
char* s = "Hello, " "World";
C99
/* since C99, more than two can be concatenated */
/* concatenation is implementation defined */
char* s1 = "Hello" ", " "World";

/* common usages are concatenations of format strings */
char* fmt = "%" PRId16; /* PRId16 macro since C99 */

Los literales de cadena, al igual que las constantes de caracteres, admiten diferentes conjuntos de caracteres.

/* normal string literal, of type char[] */
char* s1 = "abc";

/* wide character string literal, of type wchar_t[] */
wchar_t* s2 = L"abc";
C11
/* UTF-8 string literal, of type char[] */
char* s3 = u8"abc";

/* 16-bit wide string literal, of type char16_t[] */
char16_t* s4 = u"abc";

/* 32-bit wide string literal, of type char32_t[] */
char32_t* s5 = U"abc";

Tipos de enteros de ancho fijo (desde C99)

C99

El encabezado <stdint.h> proporciona varias definiciones de tipo entero de ancho fijo. Estos tipos son opcionales y solo se proporcionan si la plataforma tiene un tipo de entero del ancho correspondiente, y si el tipo con signo correspondiente tiene una representación complementaria de dos valores negativos.

Consulte la sección de comentarios para obtener sugerencias de uso de tipos de ancho fijo.

/* commonly used types include */
uint32_t u32 = 32; /* exactly 32-bits wide */

uint8_t u8 = 255;  /* exactly 8-bits wide */

int64_t i64 = -65  /* exactly 64 bit in two's complement representation */

Constantes de punto flotante

El lenguaje C tiene tres tipos obligatorios de punto flotante real, float , double y long double .

float f = 0.314f;        /* suffix f or F denotes type float */
double d = 0.314;        /* no suffix denotes double */
long double ld = 0.314l; /* suffix l or L denotes long double */

/* the different parts of a floating point definition are optional */
double x = 1.; /* valid, fractional part is optional */
double y = .1; /* valid, whole-number part is optional */

/* they can also defined in scientific notation */
double sd = 1.2e3; /* decimal fraction 1.2 is scaled by 10^3, that is 1200.0 */

El encabezado <float.h> define varios límites para las operaciones de punto flotante.

Aritmética de punto flotante es la implementación definida. Sin embargo, la mayoría de las plataformas modernas (brazo, x86, x86_64, MIPS) usan operaciones de punto flotante IEEE 754 .

C también tiene tres tipos de puntos flotantes complejos opcionales que se derivan de lo anterior.

Interpretando declaraciones

Una peculiaridad sintáctica distintiva de C es que las declaraciones reflejan el uso del objeto declarado como sería en una expresión normal.

El siguiente conjunto de operadores con precedencia y asociatividad idénticos se reutilizan en los declaradores, a saber:

  • el operador de "desreferencia" unaria * que denota un puntero;
  • el operador binario [] "suscripción de matriz" que denota una matriz;
  • el operador (1 + n) -ary () "llamada de función" que denota una función;
  • los () paréntesis de agrupación que anulan la precedencia y la asociatividad del resto de los operadores listados.

Los tres operadores anteriores tienen la siguiente prioridad y asociatividad:

Operador Precedencia relativa Asociatividad
[] (suscripción de matriz) 1 De izquierda a derecha
() (llamada de función) 1 De izquierda a derecha
* (desreferencia) 2 De derecha a izquierda

Al interpretar declaraciones, uno tiene que comenzar desde el identificador hacia afuera y aplicar los operadores adyacentes en el orden correcto según la tabla anterior. Cada solicitud de un operador puede ser sustituida por las siguientes palabras en inglés:

Expresión Interpretación
thing[X] una matriz de tamaño X de ...
thing(t1, t2, t3) una función que toma t1 , t2 , t3 y regresa ...
*thing un puntero a ...

De ello se deduce que el comienzo de la interpretación en inglés siempre comenzará con el identificador y terminará con el tipo que se encuentra en el lado izquierdo de la declaración.

Ejemplos

char *names[20];

[] tiene prioridad sobre * , por lo que la interpretación es: names es una matriz del tamaño 20 de un puntero a char .

char (*place)[10];

En caso de usar paréntesis para anular la precedencia, el * se aplica primero: place es un puntero a una matriz de tamaño 10 de char .

int fn(long, short);

No hay ninguna prioridad de qué preocuparse aquí: fn es una función que tarda long , short y devuelve int .

int *fn(void);

Primero se aplica () : fn es una función que void y devuelve un puntero a int .

int (*fp)(void);

Anular la prioridad de () : fp es un puntero a una función que void y devuelve int .

int arr[5][8];

Las matrices multidimensionales no son una excepción a la regla; los operadores [] se aplican en orden de izquierda a derecha según la asociatividad en la tabla: arr es una matriz de tamaño 5 de una matriz de tamaño 8 de int .

int **ptr;

Los dos operadores de referencia tienen la misma prioridad, por lo que la asociatividad surte efecto. Los operadores se aplican en el orden de derecha a izquierda: ptr es un puntero a un puntero a un int .

Declaraciones multiples

La coma se puede usar como separador (* no * actuando como el operador de coma) para delimitar múltiples declaraciones dentro de una sola declaración. La siguiente declaración contiene cinco declaraciones:
int fn(void), *ptr, (*fp)(int), arr[10][20], num;

Los objetos declarados en el ejemplo anterior son:

  • fn : una función que void y devuelve int ;
  • ptr : un puntero a un int ;
  • fp : un puntero a una función que toma int y devuelve int ;
  • arr : una matriz de tamaño 10 de una matriz de tamaño 20 de int ;
  • num : int .

Interpretación alternativa

Debido a que las declaraciones reflejan el uso, una declaración también puede interpretarse en términos de los operadores que podrían aplicarse sobre el objeto y el tipo resultante final de esa expresión. El tipo que se encuentra en el lado izquierdo es el resultado final que se obtiene después de aplicar todos los operadores.

/*
 * Subscripting "arr" and dereferencing it yields a "char" result.
 * Particularly: *arr[5] is of type "char".
 */
char *arr[20];

/*
 * Calling "fn" yields an "int" result.
 * Particularly: fn('b') is of type "int".
 */
int fn(char);

/*
 * Dereferencing "fp" and then calling it yields an "int" result.
 * Particularly: (*fp)() is of type "int".
 */
int (*fp)(void);

/*
 * Subscripting "strings" twice and dereferencing it yields a "char" result.
 * Particularly: *strings[5][15] is of type "char"
 */
char *strings[10][20];


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow