Biblioteca estándar de C |
---|
Temas generales |
Encabezados varios |
En el lenguaje de programación C , los tipos de datos constituyen la semántica y las características del almacenamiento de elementos de datos. Se expresan en la sintaxis del lenguaje en forma de declaraciones para ubicaciones de memoria o variables . Los tipos de datos también determinan los tipos de operaciones o métodos de procesamiento de elementos de datos.
El lenguaje C proporciona tipos aritméticos básicos, como tipos de números enteros y reales , y sintaxis para construir tipos compuestos y matrices. Los encabezados de la biblioteca estándar de C , que se utilizarán mediante directivas include , contienen definiciones de tipos de soporte que tienen propiedades adicionales, como proporcionar almacenamiento con un tamaño exacto, independientemente de la implementación del lenguaje en plataformas de hardware específicas. [1] [2]
El lenguaje C proporciona los cuatro especificadores de tipo aritmético básicos char , int , float y double , y los modificadores con signo , sin signo , corto y largo . La siguiente tabla enumera las combinaciones permitidas al especificar un gran conjunto de declaraciones específicas del tamaño de almacenamiento.
Escribe | Explicación | Tamaño mínimo (bits) | Especificador de formato |
---|---|---|---|
char | La unidad direccionable más pequeña de la máquina que puede contener un juego de caracteres básico. Es un tipo entero . El tipo real puede estar firmado o sin firmar. Contiene bits CHAR_BIT. [3] | 8 | %c |
signed char | Del mismo tamaño que el char , pero con la garantía de estar firmado. Capaz de contener al menos el rango [−127, +127]. [3] [a] | 8 | %c (o %hhi para salida numérica) |
unsigned char | Del mismo tamaño que char , pero sin firmar. Contiene al menos el rango [0, 255]. [5] | 8 | %c (o %hhu para salida numérica) |
short short int signed short signed short int | Tipo entero corto con signo. Capaz de contener al menos el rango [−32,767, +32,767]. [3] [a] | dieciséis | %hi o %hd |
unsigned short unsigned short int | Tipo entero corto sin signo. Contiene al menos el rango [0, 65,535]. [3] | dieciséis | %hu |
int signed signed int | Tipo de entero con signo básico. Capaz de contener al menos el rango [−32,767, +32,767]. [3] [a] | dieciséis | %i o %d |
unsigned unsigned int | Tipo de entero sin signo básico. Contiene al menos el rango [0, 65,535]. [3] | dieciséis | %u |
long long int signed long signed long int | Tipo de entero con signo largo . Capaz de contener al menos el rango [−2,147,483,647, +2,147,483,647]. [3] [a] | 32 | %li o %ld |
unsigned long unsigned long int | Tipo entero largo sin signo. Capaz de contener al menos el intervalo [0, 4,294,967,295]. [3] | 32 | %lu |
long long long long int signed long long signed long long int | Tipo entero largo con signo. Capaz de contener al menos el intervalo [-9,223,372,036,854,775,807, +9,223,372,036,854,775,807]. [3] [a] Especificado desde la versión C99 de la norma. | 64 | %lli o %lld |
unsigned long long unsigned long long int | Tipo entero largo sin signo. Contiene al menos el rango [0, +18,446,744,073,709,551,615]. [3] Especificado desde la versión C99 del estándar. | 64 | %llu |
float | Tipo de punto flotante real, generalmente denominado tipo de punto flotante de precisión simple. Propiedades reales no especificadas (excepto límites mínimos); sin embargo, en la mayoría de los sistemas, este es el formato de punto flotante binario de precisión simple IEEE 754 (32 bits). Este formato es requerido por el anexo F opcional "Aritmética de coma flotante IEC 60559". | Conversión de texto: [b]
| |
double | Tipo de punto flotante real, generalmente denominado tipo de punto flotante de doble precisión. Propiedades reales no especificadas (excepto límites mínimos); sin embargo, en la mayoría de los sistemas, este es el formato de punto flotante binario de doble precisión IEEE 754 (64 bits). Este formato es requerido por el anexo F opcional "Aritmética de coma flotante IEC 60559". |
| |
long double | Tipo de punto flotante real, generalmente asignado a un formato de número de punto flotante de precisión extendido . Propiedades reales sin especificar. Puede ser formato de coma flotante de precisión extendida x86 (80 bits, pero normalmente 96 bits o 128 bits en la memoria con bytes de relleno ), el formato " doble-doble " no IEEE (128 bits), flotante de precisión cuádruple IEEE 754 -formato de punto (128 bits), o lo mismo que doble. Consulte el artículo sobre el doble largo para obtener más detalles. | %Lf %LF %Lg %LG %Le %LE %La %LA [C] |
El tamaño real de los tipos de enteros varía según la implementación. El estándar solo requiere relaciones de tamaño entre los tipos de datos y tamaños mínimos para cada tipo de datos:
Los requisitos de relación son que long long
no sea menor que long
, que no sea menor que int
, que no sea menor que short
. Como char
el tamaño es siempre el tipo de datos mínimo admitido, ningún otro tipo de datos (excepto los campos de bits ) puede ser más pequeño.
El tamaño mínimo para char
es de 8 bits, el tamaño mínimo para short
y int
es de 16 bits, ya long
que es de 32 bits y long long
debe contener al menos 64 bits.
El tipo int
debe ser el tipo entero con el que el procesador de destino esté trabajando de manera más eficiente. Esto permite una gran flexibilidad: por ejemplo, todos los tipos pueden ser de 64 bits. Sin embargo, son populares varios esquemas de ancho de enteros diferentes (modelos de datos). Debido a que el modelo de datos define cómo se comunican los diferentes programas, se utiliza un modelo de datos uniforme dentro de una interfaz de aplicación de sistema operativo dada. [6]
En la práctica, char
suele tener un tamaño de 8 bits y short
suele tener un tamaño de 16 bits (al igual que sus homólogos sin firmar). Esto es válido para plataformas tan diversas como SunOS 4 Unix de la década de 1990 , Microsoft MS-DOS , Linux moderno y Microchip MCC18 para microcontroladores PIC integrados de 8 bits . POSIX requiere char
tener un tamaño exacto de 8 bits.
Varias reglas en el estándar C hacen que unsigned char
el tipo básico usado para arreglos sea adecuado para almacenar objetos arbitrarios que no son de campo de bits: su falta de bits de relleno y representaciones de trampa, la definición de representación de objeto , [5] y la posibilidad de alias. [7]
El tamaño real y el comportamiento de los tipos de punto flotante también varían según la implementación. La única garantía es que long double
no sea menor que double
, que no sea menor que float
. Por lo general, se utilizan los formatos de coma flotante binarios IEEE 754 de 32 y 64 bits .
El estándar C99 incluye nuevos tipos de coma flotante reales float_t
y double_t
, definido en <math.h>
. Corresponden a los tipos utilizados para los resultados intermedios de expresiones de punto flotante cuando FLT_EVAL_METHOD
es 0, 1 o 2. Estos tipos pueden ser más anchos que long double
.
C99 también agregó complejos tipos: float _Complex
, double _Complex
, long double _Complex
.
C99 agregó un tipo booleano (verdadero / falso) _Bool
. Además, el <stdbool.h>
encabezado se define bool
como un alias conveniente para este tipo y también proporciona macros para true
y false
. _Bool
funciona de manera similar a un tipo entero normal, con una excepción: cualquier asignación a a _Bool
que no sea 0 (falso) se almacena como 1 (verdadero). Este comportamiento existe para evitar desbordamientos de enteros en conversiones de restricción implícitas. Por ejemplo, en el siguiente código:
carácter sin firmar b = 256 ; si ( b ) { /* hacer algo */}
La variable se b
evalúa como falsa si unsigned char
tiene un tamaño de 8 bits. Esto se debe a que el valor 256 no encaja en el tipo de datos, lo que da como resultado que se utilicen los 8 bits inferiores, lo que da como resultado un valor cero. Sin embargo, cambiar el tipo hace que el código anterior se comporte normalmente:
_Bool b = 256 ; si ( b ) { /* hacer algo */}
El tipo _Bool también garantiza que los valores verdaderos siempre se comparen iguales entre sí:
_Bool a = 1 , b = 2 ;si ( a == b ) { / * hacer algo * / }
La especificación del lenguaje C incluye el typedef s y para representar cantidades de memoria relacionada. Su tamaño se define de acuerdo con las capacidades aritméticas del procesador de destino, no las capacidades de memoria, como el espacio de direcciones disponible. Ambos tipos se definen en el encabezado ( en C ++).size_t
ptrdiff_t
<stddef.h>
cstddef
size_t
es un tipo entero sin signo que se utiliza para representar el tamaño de cualquier objeto (incluidas las matrices) en la implementación particular. El operador sizeof produce un valor del tipo . El tamaño máximo de se proporciona mediante una macro constante que se define en el encabezado ( encabezado en C ++). se garantiza que tenga al menos 16 bits de ancho. Además, POSIX incluye , que es un tipo entero con signo del mismo ancho que .size_t
size_t
SIZE_MAX
<stdint.h>
cstdint
size_t
ssize_t
size_t
ptrdiff_t
es un tipo de entero con signo que se utiliza para representar la diferencia entre punteros. Se garantiza que es válido solo contra punteros del mismo tipo; la sustracción de punteros que constan de diferentes tipos está definida por la implementación.
La información sobre las propiedades reales, como el tamaño, de los tipos aritméticos básicos, se proporciona a través de macro constantes en dos encabezados: <limits.h>
encabezado ( climits
encabezado en C ++) define macros para tipos enteros y <float.h>
encabezado ( cfloat
encabezado en C ++) define macros para tipos de punto flotante . Los valores reales dependen de la implementación.
CHAR_BIT
- tamaño del tipo char en bits (al menos 8 bits)SCHAR_MIN
, SHRT_MIN
, INT_MIN
, LONG_MIN
, LLONG_MIN
(C99) - valor mínimo posible de tipos de signo integrado: signed char, short, int firmado firmado, firmado larga, firmó largo, largoSCHAR_MAX
, SHRT_MAX
, INT_MAX
, LONG_MAX
, LLONG_MAX
(C99) - valor máximo posible de tipos entero de: char firmado, firmado corto, int firmado, firmado de largo, firmó largo largoUCHAR_MAX
, USHRT_MAX
, UINT_MAX
, ULONG_MAX
, ULLONG_MAX
(C99) - valor máximo posible de tipos de entero sin signo: unsigned char, corto sin signo, unsigned int, unsigned long, unsigned long longCHAR_MIN
- valor mínimo posible de charCHAR_MAX
- valor máximo posible de charMB_LEN_MAX
- número máximo de bytes en un carácter multibyteFLT_MIN
, DBL_MIN
, LDBL_MIN
- mínimo normalizó valor positivo de flotador, doble, doble largo respectivamenteFLT_TRUE_MIN
, DBL_TRUE_MIN
, LDBL_TRUE_MIN
(C11) - valor positivo mínimo de flotador, doble, doble largo respectivamenteFLT_MAX
, DBL_MAX
, LDBL_MAX
- valor máximo finito de flotador, doble, doble largo, respectivamenteFLT_ROUNDS
- modo de redondeo para operaciones de punto flotanteFLT_EVAL_METHOD
(C99) - método de evaluación de expresiones que involucran diferentes tipos de punto flotanteFLT_RADIX
- raíz del exponente en los tipos de punto flotanteFLT_DIG
, DBL_DIG
, LDBL_DIG
- número de dígitos decimales que se pueden representar sin perder precisión al flotador, doble, doble de largo, respectivamenteFLT_EPSILON
, DBL_EPSILON
, LDBL_EPSILON
- diferencia entre 1.0 y el siguiente valor representable de flotador, doble, doble largo, respectivamenteFLT_MANT_DIG
, DBL_MANT_DIG
, LDBL_MANT_DIG
- número de FLT_RADIX
dígitos -Base en la mantisa de coma flotante para este tipo de flotador, doble, doble largo, respectivamenteFLT_MIN_EXP
, DBL_MIN_EXP
, LDBL_MIN_EXP
- negativo mínimo número entero tal que FLT_RADIX
eleva a una potencia menor que el número es un flotador normalizada, doble, doble largo, respectivamenteFLT_MIN_10_EXP
, DBL_MIN_10_EXP
, LDBL_MIN_10_EXP
- negativo mínimo número entero tal que 10 elevado a que el poder es un flotador normalizada, doble, doble largo, respectivamenteFLT_MAX_EXP
, DBL_MAX_EXP
, LDBL_MAX_EXP
- positivo máximo número entero tal que FLT_RADIX
eleva a una potencia menor que el número es un flotador normalizada, doble, doble largo, respectivamenteFLT_MAX_10_EXP
, DBL_MAX_10_EXP
, LDBL_MAX_10_EXP
- positivo máximo número entero tal que 10 elevado a que el poder es un flotador normalizada, doble, doble largo, respectivamenteDECIMAL_DIG
(C99): número mínimo de dígitos decimales, de modo que cualquier número del tipo de punto flotante más amplio admitido se pueda representar en decimal con una precisión de DECIMAL_DIG
dígitos y leerse en el tipo de punto flotante original sin cambiar su valor. DECIMAL_DIG
es al menos 10.El estándar C99 incluye definiciones de varios tipos nuevos de enteros para mejorar la portabilidad de los programas. [2] Los tipos de enteros básicos ya disponibles se consideraron insuficientes, porque sus tamaños reales están definidos por la implementación y pueden variar entre diferentes sistemas. Los nuevos tipos son especialmente útiles en entornos integrados donde el hardware generalmente admite solo varios tipos y ese soporte varía entre diferentes entornos. Todos los tipos nuevos se definen en el <inttypes.h>
encabezado ( cinttypes
encabezado en C ++) y también están disponibles en el <stdint.h>
encabezado ( cstdint
encabezado en C ++). Los tipos se pueden agrupar en las siguientes categorías:
La siguiente tabla resume los tipos y la interfaz para adquirir los detalles de implementación ( n se refiere al número de bits):
Categoría de tipo | Tipos firmados | Tipos sin firmar | ||||
---|---|---|---|---|---|---|
Escribe | Valor mínimo | Valor máximo | Escribe | Valor mínimo | Valor máximo | |
Ancho exacto | intn_t | INTn_MIN | INTn_MAX | uintn_t | 0 | UINTn_MAX |
Ancho mínimo | int_leastn_t | INT_LEASTn_MIN | INT_LEASTn_MAX | uint_leastn_t | 0 | UINT_LEASTn_MAX |
Lo más rápido | int_fastn_t | INT_FASTn_MIN | INT_FASTn_MAX | uint_fastn_t | 0 | UINT_FASTn_MAX |
Puntero | intptr_t | INTPTR_MIN | INTPTR_MAX | uintptr_t | 0 | UINTPTR_MAX |
Ancho máximo | intmax_t | INTMAX_MIN | INTMAX_MAX | uintmax_t | 0 | UINTMAX_MAX |
El <inttypes.h>
encabezado ( cinttypes
en C ++) proporciona características que mejoran la funcionalidad de los tipos definidos en el <stdint.h>
encabezado. Define macros para especificadores de cadena de formato printf y cadena de formato scanf correspondientes a los tipos definidos en <stdint.h>
y varias funciones para trabajar con los tipos intmax_t
y uintmax_t
. Este encabezado se agregó en C99 .
Las macros están en formato . Aquí {fmt} define el formato de salida y es uno de (decimal), (hexadecimal), (octal), (sin signo) y (entero). {tipo} define el tipo del argumento y es uno de , , , , , donde corresponde al número de bits en el argumento.PRI{fmt}{type}
d
x
o
u
i
n
FASTn
LEASTn
PTR
MAX
n
Las macros están en formato . Aquí {fmt} define el formato de salida y es uno de (decimal), (hexadecimal), (octal), (sin signo) y (entero). {tipo} define el tipo del argumento y es uno de , , , , , donde corresponde al número de bits en el argumento.SCN{fmt}{type}
d
x
o
u
i
n
FASTn
LEASTn
PTR
MAX
n
Esta sección necesita expansión . Puedes ayudar agregando más . ( Octubre de 2011 ) |
De manera similar a los tipos enteros de ancho fijo, ISO / IEC TS 18661 especifica tipos de punto flotante para el intercambio IEEE 754 y formatos extendidos en binario y decimal:
_FloatN
para formatos de intercambio binario;_DecimalN
para formatos de intercambio decimal;_FloatNx
para formatos binarios extendidos;_DecimalNx
para formatos decimales extendidos.Las estructuras agregan el almacenamiento de múltiples elementos de datos, de tipos de datos potencialmente diferentes, en un bloque de memoria referenciado por una sola variable. El siguiente ejemplo declara el tipo de datos struct birthday
que contiene el nombre y la fecha de nacimiento de una persona. La definición de la estructura va seguida de una declaración de la variable John
que asigna el almacenamiento necesario.
estructura cumpleaños { nombre de char [ 20 ]; int dia ; int mes ; int año ; }; cumpleaños de la estructura John ;
El diseño de memoria de una estructura es un problema de implementación del lenguaje para cada plataforma, con algunas restricciones. La dirección de memoria del primer miembro debe ser la misma que la dirección de la estructura misma. Las estructuras se pueden inicializar o asignar para usar literales compuestos. Una función puede devolver directamente una estructura, aunque a menudo esto no es eficiente en tiempo de ejecución. Desde C99 , una estructura también puede terminar con un miembro de matriz flexible .
Una estructura que contiene un puntero a una estructura de su propio tipo se usa comúnmente para construir estructuras de datos vinculadas :
struct nodo { int val ; nodo de estructura * siguiente ; };
Para cada tipo T
, excepto los tipos de función y vacío , existen los tipos "matriz de N
elementos de tipo T
" . Una matriz es una colección de valores, todos del mismo tipo, almacenados de forma contigua en la memoria. Una matriz de tamaño N
está indexada por números enteros desde 0
hasta e inclusive N−1
. A continuación, se muestra un breve ejemplo:
int cat [ 10 ]; // matriz de 10 elementos, cada uno de tipo int
Las matrices se pueden inicializar con un inicializador compuesto, pero no se pueden asignar. Las matrices se pasan a las funciones pasando un puntero al primer elemento. Las matrices multidimensionales se definen como "matriz de matriz ..." , y todas, excepto la dimensión más externa, deben tener un tamaño constante en tiempo de compilación:
int a [ 10 ] [ 8 ]; // matriz de 10 elementos, cada uno de tipo 'matriz de 8 elementos int'
Cada tipo de datos T
tiene un puntero deT
tipo correspondiente . Un puntero es un tipo de datos que contiene la dirección de una ubicación de almacenamiento de una variable de un tipo particular. Se declaran con el declarador de *
tipo asterisco ( ) que sigue al tipo de almacenamiento básico y precede al nombre de la variable. Los espacios en blanco antes o después del asterisco son opcionales.
char * cuadrado ; círculo largo * ; int * ovalado ;
Los punteros también se pueden declarar para tipos de datos de puntero, creando así múltiples punteros indirectos, como char ** e int *** , incluidos punteros a tipos de matriz. Estos últimos son menos comunes que una matriz de punteros y su sintaxis puede ser confusa:
char * pc [ 10 ]; // matriz de 10 elementos de 'puntero a char' char ( * pa ) [ 10 ]; // puntero a una matriz de 10 elementos de char
El elemento pc
requiere diez bloques de memoria del tamaño de un puntero achar
(generalmente 40 u 80 bytes en plataformas comunes), pero el elemento pa
es solo un puntero (tamaño 4 u 8 bytes), y los datos a los que hace referencia son una matriz de diez bytes. ( ).sizeof *pa == 10
Un tipo de unión es una construcción especial que permite el acceso al mismo bloque de memoria mediante una selección de descripciones de tipos diferentes. Por ejemplo, se puede declarar una unión de tipos de datos para permitir la lectura de los mismos datos como un entero, un flotante o cualquier otro tipo declarado por el usuario:
union {int i ; flotar f ; estructura {unsigned int u ; doble d ; } s ; } u ;
El tamaño total de u
es el tamaño de u.s
, que resulta ser la suma de los tamaños de u.s.u
y u.s.d
, ya que s
es mayor que ambos i
y f
. Al asignar algo a u.i
, u.f
se pueden conservar algunas partes de si u.i
es menor que u.f
.
Leer de un miembro del sindicato no es lo mismo que emitir, ya que el valor del miembro no se convierte, sino que simplemente se lee.
Los punteros de función permiten hacer referencia a funciones con una firma particular. Por ejemplo, para almacenar la dirección de la función estándar abs
en la variable my_int_f
:
int ( * my_int_f ) ( int ) = & abs ; // el operador & se puede omitir, pero deja en claro que aquí se usa la "dirección de" abs
Los punteros de función se invocan por su nombre al igual que las llamadas de función normales. Los punteros de función están separados de los punteros y de los punteros vacíos .
Los tipos mencionados anteriormente se pueden caracterizar además por calificadores de tipo , produciendo un tipo calificado . A partir de 2014 [actualizar]y C11 , hay cuatro calificadores de tipo en el estándar C: const
( C89 ), volatile
( C89 ), restrict
( C99 ) y _Atomic
( C11 ); este último tiene un nombre privado para evitar chocar con los nombres de usuario, [8] pero más atomic
Se puede utilizar un nombre ordinario si <stdatomic.h>
se incluye el encabezado. De estos, const
es , con mucho, el más conocido y el más utilizado, aparece en la biblioteca estándar y se encuentra en cualquier uso significativo del lenguaje C, que debe satisfacerconst-corrección . Los otros calificadores se usan para programación de bajo nivel y, aunque se usan ampliamente allí, los programadores típicos rara vez los usan. [ cita requerida ]
La Programación en C de Wikibook tiene una página sobre el tema: Programación en C |