¿Cuál es la diferencia entre c89 y c99? ¿Qué compiladores admiten c89?
Las diferencias entre C99 y C89:
1. Agregar un puntero de restricción
C99 agrega un modificador de tipo de restricción que generalmente se aplica a los punteros, que es el acceso inicial La única forma de acceder al objeto señalado por el puntero, por lo que solo se puede acceder al objeto con la ayuda de expresiones de puntero restringido. El puntero de restricción se utiliza principalmente como variable de función o apunta a una variable de memoria asignada por la función malloc()
. El tipo de datos restringido no cambia la semántica del programa.
Si una función define dos variables de puntero de restricción, el compilador asume que apuntan a dos objetos diferentes. La función memcpy() es una aplicación típica del ejemplo de puntero de restricción. El prototipo de la función memcpy() en C89 es el siguiente:
Código:
void *memcpy (void *s1, const void *s2, size_t size); por superposición s1 y s2,
La operación no está definida. La función memcpy() solo se puede utilizar con objetos que no se superpongan. El prototipo de la función memcpy() en C99 es el siguiente:
Código:
void *memcpy(void *restrict s1, const void *restrict s2,size_t size);
Modifique las variables s1 y s2 para asegurarse de que apunten a diferentes objetos en el prototipo.
2. Palabra clave en línea (en línea)
Además de mantener una definición estructurada y funcional, las funciones en línea también pueden permitir a los programadores escribir código eficiente en cada llamada y
<. p>el retorno de una función consume considerables recursos del sistema, especialmente cuando la llamada a la función ocurre en una declaración de bucle con muchas repeticiones. Generalmente, cuando se emite la funciónCuando ocurre una llamada a la función, es necesario enviar variables. en la pila, y es necesario guardar varias memorias de registros. Cuando la función regresa, es necesario restaurar el contenido de los registros. Si la función
se expande en línea dentro del código, estas operaciones de guardar y restaurar se producirán nuevamente cuando se ejecute el código y la velocidad de ejecución de la llamada a la función aumentará considerablemente. La expansión en línea de funciones produce código más largo, por lo que solo se deben incluir funciones que tengan un impacto significativo en el rendimiento de la aplicación y funciones que sean cortas.
3. Nuevo tipo de datos
_Bool
El valor es 0 o 1. La carpeta de encabezado
_Complex e _Imaginary
Los tipos de números complejos definidos en el estándar C99 son los siguientes: float_Complex; float_Imaginary; double_Complex;
double_Imaginary; .
Por lo tanto, al escribir una nueva aplicación, debes usar
long long int
El estándar C99 introdujo long long int (-(2e63 - 1) a 2e63 - 1) y unsigned long long int (0 - 2e64
-1). La longitud entera que long long int puede admitir es de 64 bits.
4. Mejoras a los arreglos
Arrays de longitud variable
En C99, cuando el programador declara un arreglo, la dimensión del arreglo puede ser determinada por cualquier valor válido. Se determinan expresiones enteras, incluidas expresiones cuyos valores solo se pueden determinar en tiempo de ejecución
Este tipo de matriz se denomina matriz de longitud variable, pero solo las matrices locales pueden tener longitud variable.
Las dimensiones de una matriz de longitud variable no cambian durante la vida útil de la matriz, es decir, la matriz de longitud variable no es dinámica. Lo que puede cambiar es solo el tamaño de la matriz.
Puede utilizar * para definir una matriz de longitud variable de longitud indefinida.
Escriba modificadores en la declaración de matriz
En C99, si necesita usar una matriz como argumento de función, puede usar la palabra clave estática entre corchetes de la declaración de matriz, que es
Esencialmente le dice al compilador que la matriz a la que apunta la variable contendrá al menos el número especificado de elementos. También puede utilizar las palabras clave restrict, volatile y const entre corchetes en una declaración de matriz, pero solo para variables de función. Si se utiliza restringir, el puntero es la única forma de acceder inicialmente al objeto
. Si usa constante, el puntero siempre apunta a la misma matriz. Usar volátil no tiene ningún sentido.
5. Comentarios de una sola línea
Se introdujo la marca de comentario de una sola línea "//", que se puede usar como C++.
6. Código disperso y declaraciones
7. Modificación del preprocesador
a. Lista de argumentos
Las macros pueden traer variables. Se representan elementos. por elipses (...) en definiciones de macros. El identificador interno del preprocesador __VA_ARGS__ determina dónde se reemplazarán las variables. Ejemplo: #define MySum(...) sum(__VA_ARGS__) La declaración MySum(k,m,n);
se convertirá en: sum(k, m, n); contener variables. Ejemplo: #define compare(compf, ...)
compf(__VA_ARGS__) donde compare(strcmp,"small", "large" se reemplazará con:
strcmp); ("small", "large");
b. Operador _Pragma
C99 introdujo otra forma de definir instrucciones de compilación en el programa: el operador _Pragma. El formato es el siguiente:
_Pragma("directive")
Donde directiva es una instrucción de compilación que debe calcularse completamente. El operador _Pragma permite que las directivas de compilación participen en la sustitución de macros.
c.Instrucciones de compilación interna
STDCFP_CONTRACT ON/OFF/DEFAULT Si está activado, las expresiones de punto flotante se tratan como unidades
independientes según el procesamiento del hardware. . El valor predeterminado es la herramienta definida.
STDCFEVN_ACCESS ON/OFF/DEFAULT le dice al compilador que se puede acceder al entorno de punto flotante. El valor predeterminado es la herramienta definida.
STDC CX_LIMITED_RANGE ON/OFF/DEFAULT Si el valor está ON, equivale a decirle al compilador que ciertas fórmulas que contienen números complejos en un determinado programa son confiables. El valor predeterminado es APAGADO.
d.Nueva macro interna
__STDC_HOSTED__ Si el sistema operativo existe, es 1
__STDC_VERSION__ 199991L o superior.
Representa la versión C
__STDC_IEC_599__ Si admite operaciones de punto flotante IEC 60559, es 1
__STDC_IEC_599_COMPLEX__ Si admite operaciones complejas IEC 60599, es 1
__STDC_ISO_10646__ Por soporte del compilador, utilizado para ilustrar el formato de año y mes del estándar ISO/IEC 10646:
yyymmmL
8. >En C99, el programador puede definir una o más variables en la parte de inicialización de la declaración for. El alcance de estas variables está solo dentro del cuerpo del bucle controlado por esta declaración for.
Por ejemplo:
Código:
for(int i=0; i<10; i++){
// haz algo...
}
9. Asignación compuesta
En C99, en la asignación compuesta, puede especificar una matriz, estructura o expresión de unión del tipo de objeto. Cuando se utiliza la asignación compuesta, el tipo debe especificarse entre paréntesis
, seguido de una lista de inicialización encerrada entre llaves; si el tipo es una matriz, no se puede especificar el tamaño de la matriz. El objeto construido
no tiene nombre.
Ejemplo: double *fp = (double[]) {1.1, 2.2, 3.3};
Esta declaración se utiliza para crear un puntero fp que apunta a double, y el puntero apunta a esto El primer elemento de la matriz de 3 elementos. Las asignaciones compuestas creadas dentro del dominio del archivo
son válidas sólo durante toda la vida útil del programa. Las asignaciones compuestas creadas dentro de un módulo son objetos locales que ya no existen después de salir del módulo.
10. Miembros de estructura de matriz flexible
En C99, se permite que el último elemento de la estructura sea una matriz de tamaño desconocido. Esto se denomina miembro de matriz flexible, pero es flexible. número en la estructura
Un miembro del grupo debe estar precedido por al menos otro miembro. Los miembros de matriz flexibles permiten que una estructura contenga una matriz de tamaño variable. El tamaño de la estructura devuelta por sizeof no incluye la memoria de la matriz flexible. Las estructuras que contienen miembros de matriz flexible utilizan la función malloc() para asignar memoria dinámicamente, y
la memoria asignada debe ser mayor que el tamaño de la estructura para adaptarse al tamaño esperado de la matriz flexible.
11. Inicializador especificado
En C99, esta característica es muy útil para los programadores que suelen utilizar matrices dispersas. Los inicializadores designados generalmente se usan de dos maneras: para matrices y para estructuras y uniones. Formato utilizado para matrices: [índice] = vol; donde índice representa el subíndice de la matriz y vol representa el valor de inicialización del elemento de esta matriz
.
Por ejemplo: int x[10] = {[0] = 10, [5] = 30}; solo se inicializan x[0] y x[5]. El formato utilizado para estructuras o uniones
es el siguiente:
nombre-miembro (nombre del miembro)
Al especificar la inicialización de una estructura, un método simple inicializa los miembros especificados en la estructura.
Por ejemplo: struct example{ int k, m, n } object = {m = 10,n = 200};
Entre ellos, k no está inicializado. No hay ninguna restricción en el orden en que se inicializan los miembros de la estructura.
12. Mejoras en las series de funciones printf() y scanf()
Las series de funciones printf() y scanf() en C99 introdujeron el procesamiento de long long int y unsigned long. long int data Características del tipo
. El modificador de formato de tipo long long int es ll. En las funciones printf() y scanf(), ll se aplica a los especificadores de formato d, i, o, u y x. Además, C99 también introdujo el modificador hh.
hh se utiliza para especificar argumentos de tipo char
cuando se utilizan los especificadores de formato d, i, o, u y x. Tanto el modificador ll como el hh se pueden utilizar con el especificador n.
Cuando se utilizan los modificadores de formato a y A en la función printf(), el resultado será un número de punto flotante hexadecimal. El formato es el siguiente: [-]0xh, hhhhp
+ d Cuando se utiliza el modificador de formato A, x y p deben estar en mayúsculas. Los modificadores de formato A y a también se pueden usar en la función scanf() para leer
números de coma flotante. Al llamar a la función printf(), se permite agregar el modificador l, es decir, %lf, antes del especificador %f, pero no tiene ningún efecto.
13. Nuevas bibliotecas en C99
Archivos de encabezado estándar en C89
<. h> Define varios valores límite relacionados con la implementación
Nuevas bibliotecas y archivos de encabezado C99
14. Identificador predefinido __func__ Se utiliza para señalar el nombre de la función almacenada en __func__, similar a la asignación de cadenas. 15. Cambios en otras funciones Restricciones de conversión relajadas Estándar C89 estándar C99 limitado El número de niveles de anidamiento de bloques de datos 15 127 Número de niveles de anidamiento de declaraciones condicionales 8 63 Número de caracteres válidos en identificadores internos 31 63 Caracteres válidos en identificadores externos Número 6 31 Número de miembros en estructura o unión 127 1023 Número de parámetros en llamada de función 31 127 Ya no se admiten expresiones implícitas La regla int Elimina declaraciones de funciones implícitas Restricciones en los valores de retorno En C99, las funciones de tipo no nulo deben usar return con una declaración de valor de retorno. Extendido tipo entero Significado de tipo extendido int16_t La longitud del entero es exactamente 16 bits int_least16_t La longitud del entero es al menos 16 bits int_fast32_t El tipo entero más robusto con una longitud de al menos 32 bits intmax_t El tipo entero más grande uintmax_t El tipo entero sin signo más grande Mejoras al tipo entero reglas de promoción En C89, los valores de tipo char, short int o int en expresiones se pueden promover a tipos int o int sin signo. En C99, cada tipo de entero tiene un nivel Por ejemplo: long long int tiene un nivel superior a int, int tiene un nivel superior a char, etc. En una expresión, cualquier tipo de entero cuyo nivel sea inferior a int o unsigned int se puede reemplazar por int o unsigned int. .