Pregunta

El Artículo de Wikipedia sobre ANSI C dice:

Uno de los objetivos del proceso de estandarización de ANSI C fue producir un superconjunto de K&R C (el primer estándar publicado), incorporando muchas de las características no oficiales introducidas posteriormente.Sin embargo, el comité de estándares también incluyó varias características nuevas, como prototipos de funciones (tomado del lenguaje de programación C++) y un preprocesador más capaz.La sintaxis de las declaraciones de parámetros también se cambió para reflejar el estilo C++.

Eso me hace pensar que hay diferencias.Sin embargo, no vi una comparación entre K&R C y ANSI C.¿Existe tal documento?Si no, ¿cuáles son las principales diferencias?

EDITAR:Creo que el libro de K&R dice "ANSI C" en la portada.Al menos eso creo que sí lo hace la versión que tengo en casa.Entonces, ¿tal vez ya no haya diferencia?

¿Fue útil?

Solución

Puede haber cierta confusión aquí acerca de qué es "K&R C".El término se refiere al lenguaje como se documenta en la primera edición de "El lenguaje de programación C". Mas o menos:el lenguaje de entrada del compilador C de Bell Labs alrededor de 1978.

Kernighan y Ritchie participaron en el proceso de estandarización de ANSI.El dialecto "ANSI C" reemplazó a "K&R C" y las ediciones posteriores de "El lenguaje de programación C" adoptan las convenciones ANSI."K&R C" es un "lenguaje muerto", excepto en la medida en que algunos compiladores todavía aceptan código heredado.

Otros consejos

Los prototipos de funciones fueron el cambio más obvio entre K&R C y C89, pero hubo muchos otros.También se realizó un trabajo importante para estandarizar la biblioteca C.Aunque la biblioteca C estándar era una codificación de la práctica existente, codificaba múltiple prácticas existentes, lo que lo hacía más difícil.P.J.El libro de Plauger, La biblioteca C estándar, es una gran referencia y también cuenta algunos de los detalles detrás de escena de por qué La biblioteca terminó como terminó.

El estándar C ANSI/ISO es muy similar al K&R C en muchos aspectos.Se pretendía que la mayor parte del código C existente se basara en compiladores ANSI sin muchos cambios.Sin embargo, lo más importante es que en la era anterior al estándar, la semántica del lenguaje estaba abierta a la interpretación de cada proveedor de compiladores.ANSI C introdujo una descripción común de la semántica del lenguaje que puso a todos los compiladores en pie de igualdad.Es fácil dar esto por sentado ahora, unos 20 años después, pero fue un logro significativo.

En su mayor parte, si no tiene un código base C preestándar que mantener, debería alegrarse de no tener que preocuparse por eso.Si lo hace, o peor aún, si está intentando llevar un programa antiguo a estándares más modernos, entonces cuenta con mi más sentido pésame.

Hay algunas diferencias menores, pero creo que las ediciones posteriores de K&R son para ANSI C, por lo que ya no hay una diferencia real.
"C Classic", a falta de mejores términos, tenía una forma ligeramente diferente de definir funciones, es decir.

int f( p, q, r )  
int p, float q, double r;  
{  
    // Code goes here  
}

Creo que la otra diferencia fueron los prototipos de funciones.Los prototipos no tenían que (de hecho, no podían) tomar una lista de argumentos o tipos.En ANSI C lo hacen.

  1. prototipo de función.
  2. Calificadores constantes y volátiles.
  3. Amplio soporte de carácter e internacionalización.
  4. permitir que el puntero de función se utilice sin desreferenciar.

Otra diferencia es que no era necesario definir los tipos de retorno de funciones y los tipos de parámetros.Se supondría que son enteros.

f(x)
{
    return x + 1;
}

y

int f(x)
int x;
{
    return x + 1;
}

Son identicos.

  • PROTOTIPO DE FUNCIONES: ANSI C adopta la técnica de prototipo de función C++ donde la definición y declaración de funciones incluyen nombres de funciones, argumentos, tipos de datos y tipos de datos de valor de retorno. El prototipo de función permite a los compiladores ANSI verificar si hay llamadas a funciones en el programa de usuario que pasan un número no válido de argumentos. o tipos de datos de argumentos incompatibles. Estos solucionan una debilidad importante de los compiladores de K&R C: las llamadas no válidas en el programa del usuario a menudo pasan la compilación pero hacen que el programa se bloquee cuando se ejecutan.

La diferencia es:

  1. Prototipo
  2. Amplio soporte de carácter e internacionalización.
  3. Soporte para palabras clave constantes y volátiles
  4. permitir que los punteros de función se utilicen como desreferenciación

Las principales diferencias entre ANSI C y K&R C son las siguientes:

  • creación de prototipos de funciones
  • soporte de los calificadores de tipos de datos constantes y volátiles
  • Soporta personajes amplios e internacionalización.
  • permitir el uso de punteros de función sin desreferenciar

ANSI C adopta la técnica de prototipo de función C++ donde la definición y declaración de funciones incluyen nombres de funciones, tipos de datos de argumentos y tipos de datos de valor de retorno.El prototipo de función permite al compilador ANSI C verificar si hay llamadas a funciones en programas de usuario que pasan números de argumentos no válidos o tipos de datos de argumentos incompatibles.Estos corrigen una debilidad importante del compilador K&R C.

Ejemplo:declara una función foo y requiere que foo tome dos argumentos

 unsigned long foo (char* fmt, double data)
 {
      /*body of foo */
 }

Creo que la mayor diferencia es la creación de prototipos de funciones y la sintaxis para describir los tipos de argumentos de funciones.

Una diferencia importante que nadie ha mencionado todavía es que antes de ANSI, C se definía en gran medida por precedentes más que por especificaciones;en los casos en que ciertas operaciones tendrían consecuencias predecibles en algunas plataformas pero no en otras (p. ej.utilizando operadores relacionales en dos punteros no relacionados), el precedente favoreció fuertemente poner garantías de plataforma a disposición del programador.Por ejemplo:

  1. En plataformas que definen una clasificación natural entre todos los punteros a todos los objetos, se podría confiar en que la aplicación de operadores relacionales a punteros arbitrarios produciría esa clasificación.

  2. En plataformas donde el medio natural para probar si un puntero es "mayor que" otro nunca tiene ningún efecto secundario más que producir un valor verdadero o falso, también se podría confiar en que la aplicación de operadores relacionales a punteros arbitrarios nunca tendrá ningún efecto secundario. -efectos distintos de producir un valor verdadero o falso.

  3. En plataformas donde dos o más tipos de enteros compartían el mismo tamaño y representación, se podía confiar en un puntero a cualquier tipo de entero para leer o escribir información de cualquier otro tipo con la misma representación.

  4. En plataformas en complemento a dos donde los desbordamientos de enteros se ajustan naturalmente de forma silenciosa, se podría confiar en que una operación que involucre valores sin signo menores que "int" se comportaría como si el valor no estuviera firmado en los casos en que el resultado estaría entre INT_MAX+1u y UINT_MAX y no fue promovido a un tipo más grande, ni utilizado como operando izquierdo de >>, ni ninguno de los operandos de /, %, o cualquier operador de comparación. Por cierto, la justificación del Estándar presenta esta como una de las razones por las que los tipos pequeños sin firmar se promocionan a firmados..

Antes del C89, no estaba claro hasta qué punto se podía esperar que los compiladores para plataformas en las que los supuestos anteriores no se cumplieran naturalmente mantuvieran esos supuestos de todos modos, pero había pocas dudas de que los compiladores para plataformas que podían mantener tales supuestos de manera fácil y económica debería hacerlo.Los autores del Estándar C89 no se molestaron en decir eso expresamente porque:

  1. Los compiladores cuyos escritores no fueran deliberadamente obtusos continuarían haciendo esas cosas cuando fuera práctico sin tener que decírselo (la justificación dada para promover valores pequeños sin firmar a valores firmados refuerza fuertemente este punto de vista).

  2. El estándar solo requería que las implementaciones fueran capaces de ejecutar un programa posiblemente ideado sin un desbordamiento de pila, y reconocía que, si bien una implementación obtusa podría tratar a cualquier otro programa como si invocara un comportamiento indefinido, no creía que valiera la pena preocuparse por los escritores de compiladores obtusos que escribieran. implementaciones que eran "conformes" pero inútiles.

Aunque "C89" se interpretó contemporáneamente como "el lenguaje definido por C89, más cualquier característica y garantía adicional que proporcione la plataforma", los autores de gcc han estado impulsando una interpretación que excluye cualquier característica y garantía más allá de las exigidas por C89.

A pesar de todas las afirmaciones en sentido contrario, K&R era y es bastante capaz de proporcionar cualquier tipo de material desde abajo, cerca del hardware, hacia arriba.El problema ahora es encontrar un compilador (preferiblemente gratuito) que pueda proporcionar una compilación limpia en un par de millones de líneas de K&R C sin tener que alterarlo y ejecutarlo en algo así como un procesador multinúcleo AMD.

Por lo que puedo ver, después de haber examinado el código fuente de la serie GCC 4.x.x, no existe un truco simple para reactivar la funcionalidad de retraso tradicional y cpp tradicional a su estado de funcionamiento anterior sin más esfuerzo del que estoy preparado para meter en.Y es más sencillo crear un compilador pre-ansi de K&R desde cero.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top