Sistema tipo C

La versión actual de la página aún no ha sido revisada por colaboradores experimentados y puede diferir significativamente de la versión revisada el 24 de marzo de 2019; las comprobaciones requieren 22 ediciones .

El sistema de tipo C es una implementación del concepto de tipo de datos en el lenguaje de programación C. El propio lenguaje proporciona tipos aritméticos básicos, así como una sintaxis para crear matrices y tipos compuestos. Algunos archivos de encabezado de la biblioteca estándar de C contienen definiciones de tipo con propiedades adicionales [1] [2] .

Tipos base

El lenguaje C proporciona muchos tipos básicos. La mayoría de ellos se forman utilizando uno de los cuatro especificadores de tipo aritmético, ( char, y ) int, y especificadores opcionales ( , y ). Aunque el estándar especifica un rango calculado a partir de la fórmula de −(2 n−1 −1) a 2 n−1 −1 , todos los compiladores conocidos ( gcc , clang y el compilador de Microsoft ) permiten el rango de −(2 n−1 ) a 2 n −1 −1 , donde n es el ancho de bit del tipo. floatdoublesignedunsignedshortlong

La siguiente tabla asume que 1 byte = 8 bits.

En la gran mayoría de las plataformas modernas, esto es cierto, pero es posible que 1 byte sea igual a 16 bits o algún otro número, generalmente una potencia de dos.

Tipo de Explicación Especificador de formato
char Entero, el tipo direccionable más pequeño posible. Puede contener el juego de caracteres base. Puede ser firmado o no firmado, dependiendo de la implementación. Contiene CHAR_BIT(generalmente 8) bits. [3] %c
signed char Mismo tamaño que char, pero garantizado para ser firmado. Puede tomar valores de al menos el rango [−127, +127][3] , generalmente en implementaciones [4][−128, +127] %c (también %do %hhi( %hhx, %hho) para salida numérica)
unsigned char Mismo tamaño que char, pero se garantiza que no estará firmado. Rango: [3] . Normalmente,[0, 2CHAR_BIT − 1][0, 255] %c (o %hhupara salida numérica)
short
short int
signed short
signed short int
El tipo de un entero corto con signo. Puede contener números de al menos el rango [−32767, +32767][3] , típicamente en implementaciones [4] . Por lo tanto, es al menos 16 bits (2 bytes).[−32768, +32767] %hi
unsigned short
unsigned short int
Igual que shortpero sin firmar. Rango:[0, +65535] %hu
int
signed
signed int
El tipo básico de un entero con signo. Puede contener números de al menos el rango [−32767, +32767][3] . Por lo tanto, es al menos 16 bits (2 bytes). Normalmente, 4 bytes de tamaño y rango en compiladores modernos para plataformas de 32 bits y superiores [−2 147 483 648, +2 147 483 647], pero normalmente 2 bytes de rango en plataformas de 16 y 8 bits [−32768, +32767], lo que a menudo causa confusión y conduce a incompatibilidades Código mal escrito %io%d
unsigned
unsigned int
Igual que intpero sin firmar. Rango:[0, +4 294 967 295] %u
long
long int
signed long
signed long int
Tipo entero largo con signo. Puede contener números al menos en el rango [−2 147 483 647, +2 147 483 647]. [3] [4] [5] Así que son al menos 32 bits (4 bytes). %lio%ld
unsigned long
unsigned long int
Igual que longpero sin firmar. Rango:[0, +4 294 967 295] %lu
long long
long long int
signed long long
signed long long int
El tipo de entero con signo largo largo ( doble largo ). Puede contener números al menos en el rango
[−9 223 372 036 854 775 808, +9 223 372 036 854 775 807]. [3] [4] Así que son al menos 64 bits. Aprobado en la norma C99 .
%llio%lld
unsigned long long
unsigned long long int
Similar a long longpero sin firmar. Rango : [0, 18 446 744 073 709 551 615]. %llu
float Un tipo de número de punto flotante real, comúnmente denominado tipo de número de punto flotante de precisión simple. Las propiedades detalladas no se especifican en el estándar (excepto los límites mínimos); sin embargo, en la mayoría de los sistemas es el formato binario de punto flotante de precisión simple IEEE 754 . Este formato es necesario para la aritmética de coma flotante "IEC 60559" opcional del Anexo F. %f (convertido automáticamente a doublepara printf())
double Un tipo de punto flotante real, comúnmente denominado tipo de número de punto flotante de precisión doble. En la mayoría de los sistemas, cumple con el formato de punto flotante binario de doble precisión IEEE 754 . %f( %F)

( %lf( %lF) para scanf())
%g %G
%e %E (para notación científica ) [6]

long double Un tipo de número de punto flotante real, generalmente asignado al formato de número de punto flotante de alta precisión A diferencia de y , puede ser de punto flotante de 80 bits, "doble-doble" no IEEE o "punto flotante binario de precisión cuádruple IEEE 754". Si no se proporciona un formato más preciso, es equivalente a . Vea el artículo sobre el doble largo para más detalles.floatdoubledouble %Lf %LF
%Lg %LG
%Le %LE[6]

Tampoco se mencionaron los siguientes especificadores de tipo: ( %spara cadenas, %ppara punteros, %x( %X) para representación hexadecimal, %opara octal.

El tamaño real de los tipos enteros depende de la implementación. La norma solo estipula la relación de tamaño entre tipos y el marco mínimo para cada tipo:

Así long longque no debe ser menos long, que a su vez no debe ser menos int, que a su vez no debe ser menos short. Dado que char es el tipo direccionable más pequeño posible, ningún otro tipo puede ser más pequeño que él.

El tamaño mínimo para char es de 8 bits, para shorty int es de 16 bits, para long es de 32 bits y para long long es de 64 bits.

Es deseable que el tipo intsea un tipo entero con el que el procesador trabaje de manera más eficiente. Esto permite una gran flexibilidad, por ejemplo, todos los tipos pueden ser de 64 bits. Sin embargo, existen esquemas populares que describen los tamaños de los tipos enteros. [7]

En la práctica, esto significa que charrequiere 8 bits en lugar shortde 16 bits (al igual que sus contrapartes sin firmar). inten la mayoría de las plataformas modernas se necesitan 32 bits en lugar long longde 64 bits. La longitud longvaría: para Windows es de 32 bits, para sistemas tipo UNIX es de 64 bits.

El estándar C99 incluye nuevos tipos reales: float_ty double_t, definidos en <math.h>. También incluye tipos complejosfloat _Complex : , double _Complex, long double _Complex.

Tipo booleano

El tipo booleano se agregó en C99_Bool . Además, un archivo de encabezado adicional <stdbool.h>define un alias para él bool, así como macros true(verdadero) y false(falso). _Boolse comporta como un tipo incorporado normal, con una excepción: cualquier asignación no nula (no falsa) _Boolse almacena como uno. Este comportamiento protege contra el desbordamiento. Por ejemplo:

carácter sin signo b = 256 ; si ( b ) { /* hacer algo */ }

bse considera falso si unsigned charocupa 8 bits. Sin embargo, cambiar el tipo hace que la variable sea verdadera:

_Bool b = 256 ; si ( b ) { /* hacer algo */ }

Tamaño del puntero y tipos de sangría

La especificación del lenguaje C incluye designaciones de tipo (typedef) size_ty ptrdiff_t. Su tamaño se determina en relación con las capacidades aritméticas del procesador. Ambos tipos se definen en <stddef.h>( cstddefpara C++).

size_t es un tipo entero sin signo diseñado para representar el tamaño de cualquier objeto en la memoria (incluidas las matrices) en una implementación particular. El operador sizeofdevuelve un valor de tipo size_t. El tamaño máximo size_tse escribe en una macro constante SIZE_MAXdefinida en <stdint.h>( cstdintpara C++). size_tdebe tener al menos 16 bits. Además, POSIX incluye ssize_t, que es un tipo de tamaño firmado incorporado size_t.

ptrdiff_t es un tipo con signo integrado que define la diferencia entre los punteros. Se garantiza que actúa sobre punteros del mismo tipo. La aritmética entre punteros de diferentes tipos depende de la implementación.

Interfaz a las propiedades de los tipos base

La información sobre las propiedades reales, como el tamaño, de los tipos integrados básicos se proporciona mediante constantes macro en dos encabezados: un encabezado <limits.h>( climitsen C++) define macros para tipos enteros, un encabezado <float.h>( cfloaten C++) define macros para tipos reales. Los valores específicos dependen de la implementación.

Propiedades de los tipos enteros
  • CHAR_BIT - tamaño en bits (mínimo 8 bits)char
  • SCHAR_MIN, SHRT_MIN, INT_MIN, LONG_MIN, LLONG_MIN(C99)  — valores mínimos posibles de tipos enteros con signo: , , , ,signed charsigned shortsigned intsigned longsigned long long
  • SCHAR_MAX, SHRT_MAX, INT_MAX, LONG_MAX, LLONG_MAX(C99)  — valores máximos posibles de tipos enteros con signo: , , , ,signed charsigned shortsigned intsigned longsigned long long
  • UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX, ULLONG_MAX(C99)  — valores máximos posibles de tipos enteros sin signo: , , , ,unsigned charunsigned shortunsigned intunsigned longunsigned long long
  • CHAR_MIN es el valor mínimo posiblechar
  • CHAR_MAX es el valor máximo posiblechar
  • MB_LEN_MAX es el número máximo de bytes en tipos de caracteres multibyte.
Propiedades de los tipos reales
  • FLT_MIN, DBL_MIN, LDBL_MIN es el valor positivo mínimo normalizado para , , respectivamentefloatdoublelong double
  • FLT_TRUE_MIN, DBL_TRUE_MIN, LDBL_TRUE_MIN(C11) es el valor mínimo positivo para , , respectivamentefloatdoublelong double
  • FLT_MAX, DBL_MAX, LDBL_MAX es el valor final máximo para , , respectivamentefloatdoublelong double
  • FLT_ROUNDS — método de redondeo para operaciones enteras
  • FLT_EVAL_METHOD(C99) - Método para evaluar expresiones que involucran varios tipos de punto flotante
  • FLT_RADIX es la base del exponente de los tipos reales.
  • FLT_DIG, DBL_DIG, LDBL_DIG es el número de dígitos decimales que se pueden representar sin perder precisión para , , respectivamentefloatdoublelong double
  • FLT_EPSILON, DBL_EPSILON, LDBL_EPSILON es la diferencia entre 1.0 y el siguiente número para , , respectivamentefloatdoublelong double
  • FLT_MANT_DIG, DBL_MANT_DIG, LDBL_MANT_DIG es el número de dígitos en la mantisa para , , respectivamentefloatdoublelong double
  • FLT_MIN_EXP, DBL_MIN_EXP, LDBL_MIN_EXP es el mínimo entero negativo tal que FLT_RADIX, elevado a una potencia es uno menos que el normalizado , , respectivamentefloatdoublelong double
  • FLT_MIN_10_EXP, DBL_MIN_10_EXP, LDBL_MIN_10_EXP es el entero negativo mínimo tal que 10 elevado a esa potencia es el , , respectivamente normalizadofloatdoublelong double
  • FLT_MAX_EXP, DBL_MAX_EXP, LDBL_MAX_EXP es el entero positivo máximo tal que FLT_RADIXla potencia elevada es uno menos que el número normalizado , , respectivamentefloatdoublelong double
  • FLT_MAX_10_EXP, DBL_MAX_10_EXP, LDBL_MAX_10_EXP es el entero negativo máximo tal que 10 elevado a esa potencia es el normalizado , , respectivamentefloatdoublelong double
  • DECIMAL_DIG(C99) - El número mínimo de dígitos decimales tal que cualquier número del tipo real más grande puede representarse en forma decimal con DECIMAL_DIGprecisión de dígito y volver a convertirse al tipo real original sin cambiar el valor. DECIMAL_DIGes igual a por lo menos 10.

Tipos enteros de longitud fija

El estándar C99 incluye definiciones para varios tipos de enteros nuevos para mejorar la portabilidad del programa. [2] Los tipos base de enteros ya disponibles se consideraron insatisfactorios porque su tamaño dependía de la implementación. Los nuevos tipos son ampliamente utilizados en sistemas integrados. Todos los tipos nuevos se definen en un archivo de encabezado <inttypes.h>( cinttypesen C++) y también están disponibles en <stdint.h>( cstdinten C++). Los tipos se pueden dividir en las siguientes categorías:

  • Enteros con exactamente el tamaño especificado de N bits en cualquier implementación. Incluido solo si está disponible en la implementación/plataforma.
  • Los enteros más pequeños cuyo tamaño es el mínimo en la implementación constan de al menos N bits. Se garantiza que los tipos están definidos para N=8,16,32,64.
  • Los tipos enteros más rápidos, que se garantiza que serán los más rápidos en una implementación particular, tienen al menos N bits de longitud. Se garantiza que los tipos están definidos para N=8,16,32,64.
  • Tipos enteros para punteros que garantizan poder almacenar una dirección en la memoria. Incluido solo si está disponible en una plataforma específica.
  • Los enteros más grandes cuyo tamaño es el más grande en la implementación.

La siguiente tabla muestra estos tipos ( N representa el número de bits):

Categoría de tipo Tipos firmados tipos sin firmar
Tipo de Valor mínimo Valor máximo Tipo de Valor mínimo Valor máximo
Tamaño exacto intN_t INTN_MIN INTN_MAX uintN_t 0 UINTN_MAX
Talla minima 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
Talla máxima intmax_t INTMAX_MIN INTMAX_MAX uintmax_t 0 UINTMAX_MAX

Especificadores de formato para printf y scanf

El archivo de encabezado <inttypes.h>( cinttypesen C++) amplía las capacidades de los tipos definidos en <stdint.h>. Incluyen macros que definen especificadores de tipo para la cadena de formato printf y scanf, y varias funciones que operan en los tipos intmax_ty uintmax_t. Este archivo de encabezado se agregó en C99 .

cadena de formato printf

Las macros se definen en el formato . Aquí {fmt} significa el formato de salida y pertenece a (decimal), (hexadecimal), (octal), (sin signo) o (entero). {tipo} especifica el tipo del argumento y pertenece a , , o , donde es el número de bits. PRI{fmt}{type}dxouiNFASTNLEASTNPTRMAXN

cadena de formato scanf

Las macros se definen en el formato . Aquí {fmt} significa el formato de salida y pertenece a (decimal), (hexadecimal), (octal), (sin signo) o (entero). {tipo} especifica el tipo del argumento y pertenece a , , o , donde es el número de bits. SCN{fmt}{type}dxouiNFASTNLEASTNPTRMAXN

Funciones

Estructuras

Las estructuras en C le permiten almacenar múltiples campos en una sola variable. Pueden llamarse registros o tuplas en otros idiomas. Por ejemplo, esta estructura almacena el nombre y la fecha de nacimiento de una persona:

estructura de cumpleaños { nombre del personaje [ 20 ]; día internacional ; mes int ; año int ; };

Las declaraciones de estructura en el cuerpo de un programa siempre deben comenzar con la estructura clave (opcional en C++). Se accede a los miembros de la estructura mediante el operador . o -> , si estamos trabajando con un puntero a una estructura. Las estructuras pueden contener punteros a sí mismas, lo que hace posible implementar muchas estructuras de datos basadas en listas enlazadas. Esta posibilidad puede parecer contradictoria, pero todos los punteros ocupan el mismo número de bytes, por lo que el tamaño de este campo no cambiará con el número de campos de estructura.

Las estructuras no siempre ocupan el número de bytes igual a la suma de los bytes de sus elementos. El compilador normalmente alinea los elementos en bloques de 4 bytes. También es posible limitar la cantidad de bits asignados a un campo en particular, para esto debe especificar el tamaño del campo en bits después del nombre del campo, separados por dos puntos. Esta función le permite crear campos de bits .

Algunas características de las estructuras:

  1. La dirección de memoria del primer campo de la estructura es igual a la dirección de la estructura misma
  2. Las estructuras se pueden inicializar o convertir a algún valor usando literales compuestos
  3. Las funciones personalizadas pueden devolver una estructura, aunque a menudo no son muy eficientes en tiempo de ejecución. Desde C99 , una estructura puede terminar en una matriz de tamaño variable.

Matrices

Para cada tipo T , a excepción de los tipos de función y vacío, hay un tipo de "matriz de N elementos de tipo T ". Una matriz es una colección de valores del mismo tipo almacenados secuencialmente en la memoria. Una matriz de tamaño N está indexada por un número entero de 0 a N-1 . Las matrices también son posibles, con un tamaño desconocido para el compilador. El tamaño de una matriz debe ser una constante. Ejemplos

gato int [ 10 ] = { 5 , 7 , 2 }; // matriz de 10 elementos, cada uno de tipo int int bob []; // matriz con un número desconocido de elementos de tipo 'int'.

Los arreglos se pueden inicializar con una lista de inicialización, pero no se pueden asignar entre sí. Los arreglos se pasan a las funciones usando un puntero al primer elemento (el nombre del arreglo es la dirección del primer elemento). Los arreglos multidimensionales son arreglos de arreglos. Ejemplos:

int a [ 10 ][ 8 ]; // arreglo de 10 elementos, cada uno de tipo 'arreglo de 8 elementos int' float f [][ 32 ] = {{ 0 },{ 4 , 5 , 6 }};

Tipos de punteros

Para cualquier tipo T existe un tipo "puntero a T ".

Las variables se pueden declarar como punteros a valores de varios tipos utilizando la extensión *. Para definir el tipo de una variable como un puntero, debe preceder su nombre con un asterisco.

char letra C = 'C' ; char * letra = & letra C ; //tomando la dirección de la letraC y asignándola a la letra printf ( "Este código está escrito en %c." , * letra ); //"Este código está escrito en C."

Además de los tipos estándar, puede declarar punteros a estructuras y uniones:

Punto de estructura { int x , y ; } Un ; A._ _ x = 12 ; A._ _ y = 34 _ punto de estructura * p = & A ; printf ( "X: %d, Y: %d" , ( * p ). x , ( * p ). y ); //"X: 12, Y: 34"

Para acceder a los campos de una estructura por puntero, existe un operador de flecha ->, sinónimo de la entrada anterior: (*p).x - lo mismo que p->x.

Dado que un puntero también es un tipo de variable, la regla "para cualquier tipo T " también es válida para ellos: puede declarar punteros a punteros. Por ejemplo, puedes usar int***:

intw = 100 ; _ int * x = & w ; int ** y = & x ; int *** z = & y ; printf ( "w contiene %d." , *** z ); //"w contiene 100".

También hay punteros a arreglos ya funciones. Los punteros de matriz tienen la siguiente sintaxis:

char * pc [ 10 ]; // array de 10 punteros a char char ( * pa )[ 10 ]; // puntero a una matriz de 10 variables char

pc - una matriz de punteros que ocupa un 10 * sizeof(char*)byte (en plataformas comunes, generalmente 40 u 80 bytes), y pa - este es un puntero; suele ocupar 4 u 8 bytes, sin embargo, te permite acceder a un array que ocupa 10 bytes: sizeof(pa) == sizeof(int*)pero sizeof(*pa) == 10 * sizeof(char). Los punteros a matrices difieren de los punteros al primer elemento en aritmética. Por ejemplo, si los punteros paapuntan a la dirección 2000, entonces el puntero pa+1apuntará a la dirección 2010.

char ( * pa )[ 10 ]; matriz de caracteres [ 10 ] = "Wikipedia" ; pa = & matriz ; printf ( "Un ejemplo para %s. \n " , * pa ); //"Un ejemplo para Wikipedia". printf ( "%c %c %c" , ( * pa )[ 1 ], ( * pa )[ 3 ], ( * pa )[ 7 ]); //"ii yo"

Asociaciones

Las uniones son estructuras especiales que permiten que diferentes campos compartan una memoria común. Por lo tanto, solo uno de los campos se puede almacenar en la unión. El tamaño de la unión es igual al tamaño del campo más grande. Ejemplo:

unión { ent i ; flotante f ; estructura { sin firmar en tu ; doble d ; } s ; } tu ;

En el ejemplo anterior u, el tamaño es u.s(cuyo tamaño es la suma de u.s.uy u.s.d), ya que s es mayor que iy f. La lectura de una unión no implica conversiones de tipos.

Enumeraciones

Las enumeraciones le permiten definir tipos personalizados en su código. Ejemplo:

enumeración { rojo , verde = 3 _ azul } color ;

Las enumeraciones mejoran la legibilidad del código, pero no son seguras (por ejemplo, para el sistema 3 y verde son lo mismo. En C ++, las clases de enumeración se introdujeron para corregir esta deficiencia), ya que son números enteros. En este ejemplo, el valor del rojo es cero y el valor del azul es cuatro.

Punteros de función

Los punteros de función le permiten pasar una función a otra e implementar un mecanismo de devolución de llamada . Los punteros de función le permiten hacer referencia a funciones con una firma específica. Un ejemplo de creación de un puntero a una función absque toma un int y devuelve un int llamado my_int_f:

int ( * my_int_f )( int ) = & abs ; // el operador & es opcional, pero lo aclara mostrando explícitamente que estamos pasando una dirección

Los punteros de función se llaman por su nombre como llamadas de función normales. Los punteros de función están separados de los punteros regulares y de los punteros a void.

Ejemplo más complejo:

char ret_a ( int x ) { devuelve 'a' + x ; } typedef char ( * fptr )( int ); fptr otra_func ( flotador a ) { volver & ret_a ; }

Aquí, por comodidad, hemos creado un alias llamado fptr para un puntero a una función que devuelve un carácter y toma un int. Sin el typedef, la sintaxis sería más difícil de leer:

char ret_a ( int x ) { devuelve 'a' + x ; } char ( * func ( float a , int b ))( int ) { char ( * fp )( int ) = & ret_a ; volver fp ; } char ( * ( * superfunción ( doble a ))( float , int ))( int ) { char ( * ( * fpp )( float , int ))( int ) =& func ; devolver fpp ; }

La función func no devuelve un char, como podría parecer, sino un puntero a una función que devuelve un char y acepta un int. Y acepta float e int.

Calificadores de tipo

Los tipos anteriores pueden tener diferentes calificadores de tipo. Según el estándar C11 , existen cuatro calificadores de tipo:

  • const( C89 ) - significa que el tipo dado es inmutable después de la inicialización. (constante)
  • volatile( C89 ) - significa que el valor de esta variable a menudo está sujeto a cambios.
  • restrict( C99 ).
  • _Atomic(desde C11 ). [8] También se puede llamar atomic, si se conecta stdatomic.h.

Además, desde el estándar 99 , se ha agregado un calificador de función inline, que es una sugerencia para que el compilador incluya código del cuerpo de la función, en lugar de llamar a la función en sí.

Una variable puede tener múltiples calificadores. Ejemplo:

const volátil int a = 5 ; constante int volátil * b = &a ; //puntero a const volatile int int * const c = NULL ; // const puntero a int

Clases de almacenamiento

También hay cuatro clases de almacenamiento en C:

  • auto - por defecto para todas las variables.
  • register - una sugerencia para que el compilador almacene variables en los registros del procesador. Para tales variables no hay operación de toma de direcciones.
  • static son variables estáticas. Tener alcance de archivo.
  • extern - variables declaradas fuera del archivo.

Véase también

  • sintaxis C
  • Variable no inicializada

Notas

  1. Barr, Michael Portable Fixed-Width Integers in C (2 de diciembre de 2007). Consultado el 8 de noviembre de 2011. Archivado desde el original el 9 de octubre de 2010.
  2. 1 2 Especificación ISO/IEC 9899:1999  (sin definir) . — S. 264, § 7.18 Tipos enteros . Archivado el 15 de agosto de 2011 en Wayback Machine .
  3. 1 2 3 4 5 6 7 Especificación ISO/IEC 9899:1999, TC3  (sin definir) . — S. 22, § 5.2.4.2.1 Tamaños de tipos enteros <limits.h>. Archivado el 11 de enero de 2018 en Wayback Machine .
  4. 1 2 3 4 Aunque el estándar especifica un rango de −(2 n−1 −1) a 2 n−1 −1 , todos los compiladores conocidos ( gcc , clang y compilador de Microsoft ) Archivado el 12 de enero de 2016 en Wayback Machine ) permita el rango de −(2 n−1 ) a 2 n−1 −1 , donde n es la longitud en bits del tipo.
  5. c - ¿Por qué necesitamos un tipo largo cuando hay un int? . Desbordamiento de pila en ruso. Consultado el 11 de marzo de 2020. Archivado desde el original el 27 de febrero de 2021.
  6. 1 2 El caso del formato afecta el caso de la salida. Por ejemplo, mayúsculas %E, %F, %G generarán datos no numéricos en mayúsculas: INF, NANy E(exponente). Lo mismo ocurre con %x y %X
  7. Modelos de programación de 64 bits: ¿Por qué LP64? . El Grupo Abierto. Consultado el 9 de noviembre de 2011. Archivado desde el original el 25 de diciembre de 2008.
  8. C11: The New C Standard Archivado el 12 de julio de 2018 en Wayback Machine por Thomas Plum