![Contenido Checked](../../checked-content.png)
C (lenguaje de programación)
Antecedentes de las escuelas de Wikipedia
SOS Children hizo esta selección Wikipedia junto a otros recursos de escuelas . Antes de decidir sobre el patrocinio de un niño, ¿por qué no aprender sobre diferentes obras de caridad de patrocinio primero ?
![]() El lenguaje de programación C (también conocido como "K & R"), el libro seminal sobre C | |
Paradigma (s) | Imperativo ( procedimental), estructurado |
---|---|
Apareció en | 1972 |
Diseñado por | Dennis Ritchie |
Revelador | Dennis Ritchie y Laboratorios Bell (creadores); ANSI X3J11 ( ANSI C); ISO / IEC JTC 1 / SC22 / WG14 (ISO C) |
Última versión estable | C11 (diciembre de 2011) |
Disciplina Typing | Estática, débil, manifiesto, nominal |
Las principales implementaciones | Clang, GCC, Intel C, MSVC, Pelles C, Watcom C |
Dialectos | Cyclone, Unified Parallel C, Split-C, Cilk, C * |
Influenciado por | B ( BCPL, CPL), ALGOL 68, Asamblea, PL / I, FORTRAN |
Influenciado | Numerosos: AMPL, AWK, csh, C ++ , C-, C #, Objective-C, BITC, D, Vaya, Java , JavaScript Limbo, LPC, Perl , PHP, Pike, Procesamiento, Seed7 |
OS | Cruz-plataforma (multiplataforma) |
Usual extensiones de archivos | .c .h |
|
En informática, C ( / s yo /, Como en la letra C) es una de propósito general lenguaje de programación desarrollado inicialmente por Dennis Ritchie entre 1969 y 1973 en AT & T Bell Labs. Me gusta más idiomas imperiosas de Tradición ALGOL, C cuenta con instalaciones para programación estructurada y permite léxica alcance variable y recursión, mientras que una sistema de tipo estático impide que muchas operaciones no deseadas. Su diseño proporciona construcciones que se asignan eficientemente al típico instrucciones de la máquina, y el uso duradero por lo que ha encontrado en las aplicaciones que anteriormente había sido codificados en lenguaje ensamblador, sobre todo software de sistema como el Unix ordenador sistema operativo.
C es uno de los idiomas más utilizados de programación de todos los tiempos, y los compiladores de C están disponibles para la mayoría de los disponibles arquitecturas de computadora y sistemas operativos.
Muchos lenguajes posteriores han prestado directa o indirectamente de C, incluyendo C #, D, Vaya, Java , JavaScript Limbo, LPC, Perl , PHP, Python , y es Unix C shell. La influencia más penetrante en idiomas (con exclusión de Python) ha sido sintáctica, y tienden a combinar la expresión reconocible y declaración sintaxis de C con los sistemas subyacentes de tipos, modelos de datos, y la semántica que pueden ser radicalmente diferentes. C ++ comenzó como un preprocesador de C y actualmente casi un superconjunto de C.
Antes de que hubiera una norma oficial para C, muchos usuarios y los ejecutores se basó en una especificación informal contenida en un libro de Dennis Ritchie y Brian Kernighan; esa versión se denomina generalmente como "K & R" C. En 1989 la American National Standards Institute publicó un estándar para C (generalmente llamado " ANSI C "o" C89 "). Al año siguiente, la misma especificación fue aprobado por el Organización Internacional de Normalización como un estándar internacional (generalmente llamado "C90"). ISO posteriormente puesto en libertad una extensión de la apoyo a la internacionalización de la norma en 1995, y un estándar revisado (conocido como " C99 ") en 1999. La versión actual de la norma (ahora conocido como" C11 ") fue aprobado en diciembre de 2011.
Diseño
C es una imperativo ( lengua de procedimiento). Fue diseñado para ser compilado utilizando una relativamente sencilla compilador, para proveer de bajo nivel de acceso a la memoria, para proporcionar construcciones del lenguaje que se asignan de manera eficiente a las instrucciones de la máquina, y que requiere una mínima tiempo de ejecución de la ayuda. C era por lo tanto útiles para muchas aplicaciones que anteriormente había sido codificados en lenguaje ensamblador, tal como en la programación del sistema.
A pesar de sus capacidades de bajo nivel, la lengua fue diseñado para fomentar programación multiplataforma. A compatible con los estándares y programa en C portable escrita puede ser compilado para una amplia variedad de plataformas informáticas y sistemas operativos con algunos cambios en su código fuente. El lenguaje se ha convertido en disponible en una amplia gama de plataformas, desde embebido microcontroladores a supercomputadoras.
Características
Como la mayoría de los lenguajes imperativos en la Tradición ALGOL, C cuenta con instalaciones para programación estructurada y permite léxica alcance variable y recursión, mientras que un estático sistema tipo impide que muchas operaciones no deseadas. En C, todo el código ejecutable está contenida dentro de subrutinas, que se llaman "funciones" (aunque no en el sentido estricto de programación funcional). Función parámetros siempre se pasan por valor. Pasar por referencia se simula en C pasando explícitamente valores de puntero. Texto fuente del programa C es formato libre, utilizando el punto y coma como una terminador de sentencia y llaves para agrupar bloques de sentencias.
El lenguaje C también presenta las siguientes características:
- Hay un pequeño número, fijo de palabras clave, que incluye un conjunto completo de flujo de primitivas de control:
for
,if/else
,while
,switch
, ydo/while
. Hay una espacio de nombres y nombres definidos por el usuario no se distinguen de las palabras clave por cualquier tipo de sigilo. - Hay un gran número de operadores aritméticos y lógicos, tales como
+
,+=
,++
,&
,~
, etc. - Más de uno asignación se puede realizar en una sola sentencia.
- Valores de retorno de funciones pueden ser ignorados cuando no se necesita.
- Escribir es estático, sino débilmente forzada: todos los datos tiene un tipo, pero las conversiones implícitas se puede realizar; por ejemplo, los personajes pueden ser usados como números enteros.
- Declaración imita sintaxis contexto de uso. C no tiene palabra "definir"; En cambio, un estado que comience con el nombre de un tipo se toma como una declaración. No hay palabra "función"; en cambio, una función es indicada por los paréntesis de una lista de argumentos.
- Definidas por el usuario (
typedef
tipos) y compuestas son posibles.- Tipos de datos agregados heterogéneos (
struct
) permitir que los elementos de datos relacionados que se accede y se asignan como una unidad. - Indización de matriz es una idea secundaria, definida en términos de la aritmética de punteros. A diferencia de estructuras, las matrices no son objetos de primera clase; no pueden ser cedidos o compararon mediante operadores integrados individuales. No hay palabras clave "matriz", en uso o definición; en cambio, los corchetes indican matrices sintácticamente, por ejemplo,
month[11]
. - Los tipos enumerados son posibles con la
enum
de palabras clave. Ellos no están etiquetados, y son de libre interconvertibles con números enteros. - Las cadenas no son un tipo de datos por separado, pero no se aplican de forma convencional como arrays terminadas en nulo de caracteres.
- Tipos de datos agregados heterogéneos (
- Acceso de bajo nivel a la memoria del ordenador es posible mediante la conversión de direcciones de la máquina para tecleó punteros.
- Procedimientos (subrutinas no regresan valores) son un caso especial de la función, con un sin tipo tipo de retorno
void
. - Las funciones no pueden ser definidos dentro del ámbito léxico de otras funciones.
- Función y datos punteros permiten ad hoc tiempo de ejecución de polimorfismo.
- La realiza preprocesador definición de la macro, código fuente de inclusión de archivo, y la compilación condicional.
- Hay una forma básica de modularidad: archivos pueden ser compilados por separado y unidos entre sí, con control sobre qué funciones y objetos de datos son visibles para otros archivos a través de
static
yextern
atributos. - Funcionalidad compleja como I / O, funciones de manipulación de cadenas, y matemáticos se delegan sistemáticamente a rutinas de biblioteca.
C no incluye algunas de las características que se encuentra en nuevos idiomas, más modernos de alto nivel, incluyendo la orientación a objetos y recoleccion de basura.
Historia
Los primeros desarrollos
![](../../images/3195/319540.jpg)
![](../../images/2882/288224.png)
El desarrollo inicial de C se produjo en AT & T Bell Labs, entre 1969 y 1973; según Ritchie, el período más creativo ocurrió en 1972. Fue nombrado "C", ya que sus características se derivan de un lenguaje anterior llamado " B ", que según Ken Thompson era una versión reducida de la Lenguaje de programación BCPL.
El origen de C está estrechamente ligada al desarrollo del Unix el sistema operativo, implementado originalmente en lenguaje ensamblador en un PDP-7 por Ritchie y Thompson, que incorpora varias ideas de sus colegas. Finalmente decidieron portar el sistema operativo a un PDP-11. La incapacidad de B para tomar ventaja de algunas de las características del PDP-11, en particular direccionamiento de byte, llevó al desarrollo de una versión temprana de C.
La versión original PDP-11 del sistema Unix fue desarrollado en lenguaje ensamblador. En 1973, con la adición de struct
tipos, el lenguaje C se había vuelto lo suficientemente poderoso que la mayoría de los Unix kernel fue reescrito en C. Este fue uno de los primeros núcleos del sistema operativo implementado en un idioma que no sea el montaje. (Casos anteriores se incluyen las Sistema Multics (escrito en PL / I), y MCP ( Master Control Program) para el Burroughs B5000 escrito en ALGOL en 1961.) Circa 1977, más cambios en el lenguaje fueron hechas por Ritchie y Stephen C. Johnson para facilitar la portabilidad del sistema operativo Unix. Johnson Portable C Compiler sirvió de base para varias implementaciones de C en las nuevas plataformas.
K & R C
En 1978, Brian Kernighan y Dennis Ritchie publicó la primera edición de El lenguaje de programación C. Este libro, conocido por los programadores de C como "K & R", sirvió durante muchos años como informal especificación de la lengua. La versión de C que se describe que comúnmente se conoce como K & R C. La segunda edición del libro cubre la tarde ANSI C estándar.
K & R introdujeron varias características del lenguaje:
- biblioteca de E / S estándar
-
long int
tipo de datos -
unsigned int
tipo de datos - operadores de asignación compuestos de la forma
=
op (como=-
) se cambiaron a la forma op=
para eliminar la ambigüedad semántica creado por dichas construcciones comoi=-10
, que había sido interpretado comoi =- 10
(decremento i por 10 ) en lugar de la posiblemente destinadoi = -10
(Sea I -10)
Incluso después de la publicación de la norma C 1989, durante muchos años K & R C todavía era considerado el "mínimo común denominador" para que los programadores de C sí restringidas cuando se desea la máxima portabilidad, ya que muchos compiladores mayores estaban todavía en uso, y porque cuidadosamente escrito K & R código C puede ser legal Standard C también.
En las primeras versiones de C, únicas funciones que devuelven un no- int
valor necesario para ser declarado si se usa antes de la definición de la función; una función que se utiliza sin ninguna declaración anterior se supuso volver tipo int
, si se ha utilizado su valor.
Por ejemplo:
some_function largo (); / * Int * / other_function (); / * Int * / calling_function () { test1 largo; registrarse / * int * / test2; test1 = some_function (); si (prueba1> 0) test2 = 0; más test2 = other_function (); volver test2; }
Los int
especificadores de tipo que se comentan a cabo podrían omitirse en K & R C, pero se requieren en las normas posteriores.
Desde K & R declaraciones de funciones no incluían ninguna información acerca de los argumentos de la función, el parámetro de función controles de tipo no se realizaron, aunque algunos compiladores se emitirá un mensaje de advertencia si una función local fue llamado con el número incorrecto de argumentos, o si varias llamadas a una función externa utilizan diferentes números o tipos de argumentos. Tiene herramientas tales como Unix utilidad pelusa fueron desarrollados que (entre otras cosas) podría comprobar la consistencia de utilización función a través de múltiples archivos de origen.
En los años siguientes a la publicación de K & R C, se añadieron varias características no oficiales a la lengua, con el apoyo de los compiladores de AT & T y otros proveedores. Estos incluyen:
-
void
funciones (es decir, funciones que no tienen valor de retorno) - funciones que regresan
struct
ounion
tipos (en lugar de punteros) - asignación para
struct
tipos de datos - tipos enumerados
El gran número de extensiones y la falta de acuerdo sobre un biblioteca estándar, junto con la popularidad de idiomas y el hecho de que ni siquiera el Unix compiladores implementó precisamente la especificación K & R, llevó a la necesidad de la normalización.
ANSI C e ISO C
A finales de los años 1970 y 1980, las versiones de C se implementaron para una amplia variedad de ordenadores centrales, minicomputadoras, y microordenadores, incluyendo el IBM PC, ya que su popularidad comenzó a aumentar de manera significativa.
En 1983, la American National Standards Institute (ANSI) formó un comité, X3J11, para establecer una especificación estándar de C. X3J11 basado el estándar C sobre la implementación de Unix; Sin embargo, la porción no portátil de la biblioteca Unix C se traspasa a la IEEE grupo de trabajo 1003 para convertirse en la base para el 1988 Estándar POSIX. En 1989, el estándar C fue ratificado como ANSI X3.159-1989 "Lenguaje de Programación C". Esta versión de la lengua se refiere a menudo como ANSI C, C estándar, o, a veces C89.
En 1990, el estándar ANSI C (con cambios de formato) fue adoptada por la Organización Internacional de Normalización (ISO) como la norma ISO / IEC 9899: 1990, que a veces se llama C90. Por lo tanto, los términos "C89" y "C90" se refieren al mismo lenguaje de programación.
ANSI, al igual que otros organismos nacionales de normalización, ya no se desarrolla el estándar C de forma independiente, pero se remite a la norma internacional C, mantenido por el grupo de trabajo ISO / IEC JTC 1 / SC22 / WG14. La adopción nacional de una actualización de la norma internacional se produce normalmente dentro de un año de la publicación de la ISO.
Uno de los objetivos del proceso de normalización C era producir un superconjunto de K & R C, que incorpora muchas de las características no oficiales introducidas posteriormente. El comité de estándares también incluye varias características adicionales, tales como prototipos de funciones (tomado de C ++), void
punteros, apoyo a organizaciones internacionales juegos de caracteres y locales, y mejoras del preprocesador. Aunque el sintaxis de las declaraciones de parámetros se amplió para incluir el estilo utilizado en C ++, la interfaz R K & continuaron siendo permitido, por compatibilidad con código fuente existente.
C89 es apoyado por los compiladores de C actuales, y la mayoría del código C se escribe hoy se basa en él. Cualquier programa escrito sólo en C estándar y sin ningún tipo de suposiciones dependientes del hardware funcionará correctamente en cualquier plataforma con una aplicación C conformes, dentro de sus límites de recursos. Sin tales precauciones, los programas pueden compilar sólo en una determinada plataforma o con un compilador en particular, debido, por ejemplo, para el uso de bibliotecas no estándar, tales como Las bibliotecas GUI, oa una dependencia de los atributos específicos de la plataforma compiler- o tales como el tamaño exacto de los tipos de datos y bytes endianness.
En los casos en que el código debe ser compilable por cualquiera de los compiladores estándar conformes o basado en C K & R, el __STDC__
macro se puede utilizar para dividir el código en secciones estándar y K & R para evitar el uso de un compilador basado en C K & R de funciones disponibles sólo en Norma C.
C99
Después de que el proceso de normalización ANSI / ISO, la especificación del lenguaje C se mantuvo relativamente estática durante varios años. En 1995 Normativa Enmienda 1 de la norma C 1990 (ISO / IEC 9899 / AMD1: 1995, conocida informalmente como C95) se publicó, para corregir algunos detalles y para añadir más amplio soporte para los juegos de caracteres internacionales. El estándar de C fue revisado más a finales de 1990, dando lugar a la publicación de la norma ISO / IEC 9899: 1999 en el año 1999, que se conoce comúnmente como " C99 ". Desde entonces se ha modificado en tres ocasiones por Corrección de errores técnicos.
C99 introduce varias características nuevas, incluyendo funciones en línea, varios de los nuevos tipos de datos (incluyendo long long int
y un complex
tipo para representar los números complejos ), arrays de longitud variable, soporte mejorado para IEEE 754 de coma flotante, el apoyo a la macros variadic (macros de variables aridad), y el apoyo a una sola línea de comentarios que comienzan con //
, como en BCPL o C ++. Muchos de ellos ya han sido aplicadas como extensiones en varios compiladores C.
C99 es en su mayor parte compatible hacia atrás con C90, pero es más estricta en algunos aspectos; en particular, una declaración que carece de un especificador de tipo ya no ha int
asumido implícitamente. Una macro estándar __STDC_VERSION__
se define con valor 199901L
para indicar que el apoyo C99 está disponible. GCC, Solaris Studio y otros compiladores de C ahora soportan muchas o todas las nuevas características de C99.
C11
En 2007, se comenzó a trabajar en otra revisión de la norma C, informalmente llamado "C1X" hasta su publicación oficial en 2011-12-08. El comité de estándares de C aprobó directrices para limitar la adopción de nuevas características que no habían sido probados por las implementaciones existentes.
El estándar C11 añade numerosas nuevas características a C y la biblioteca, incluyendo macros genéricos tipo, estructuras anónimas, mejorado el soporte Unicode, operaciones atómicas, multi-threading y funciones grada-controladas. También hace que algunas porciones de la biblioteca C99 existente opcional y mejora la compatibilidad con C ++.
Embedded C
Históricamente, la programación C es necesario tener extensiones no estándar en el lenguaje C con el fin de apoyar las características exóticas como aritmética de punto fijo, varios bancos de memoria diferentes, y las operaciones básicas de E / S.
En 2008, el Comité de Normas C publicó un informe técnico que se extiende el lenguaje C para abordar estas cuestiones, proporcionando un estándar común para todas las implementaciones se adhieran a. Incluye una serie de características que no están disponibles en la normalidad C, tales como aritmética de punto fijo, espacios de direcciones con nombre, y el hardware básico de E / S de direccionamiento.
Sintaxis
C tiene una gramática formal especificado por la norma C. A diferencia de lenguajes como FORTRAN 77, código fuente C es de forma libre, que permite el uso arbitrario de espacios en blanco para formatear código, en lugar de las restricciones basadas en texto de una línea basada en columnas o. Comentarios pueden aparecer ya sea entre los delimitadores /*
y */
o (desde C99) siguiente //
hasta el final de la línea. Comentarios delimitada por /*
y */
no anidan, y estas secuencias de caracteres no se interpretan como delimitadores de comentarios si aparecen en el interior caracteres o frases literales.
Fuentes C contienen declaraciones y definiciones de funciones. Las definiciones de funciones, a su vez, contienen declaraciones y declaraciones. Declaraciones o bien definir nuevos tipos utilizando palabras clave como struct
, union
y enum
, o asignar tipos de y quizás de almacenamiento de reserva para nuevas variables, generalmente por escrito el tipo seguido por el nombre de la variable. Palabras clave tales como char
y int
edificadas en tipos. Las secciones de código se incluyen entre llaves ( {
y }
, a veces llamado "llaves") para limitar el alcance de las declaraciones y de actuar como una sola declaración para estructuras de control.
Como un lenguaje imperativo, C utiliza los estados para especificar acciones. La declaración más común es una declaración de la expresión, que consta de una expresión a ser evaluado, seguido por un punto y coma; como un efecto secundario de la evaluación, las funciones pueden ser llamaron y variables pueden ser asignados nuevos valores. Para modificar la ejecución secuencial normal de declaraciones, C proporciona varios estados de flujo de control identificadas por palabras clave reservadas. La programación estructurada se apoya en if
(- else
) ejecución condicional y por do
- while
, while
, y for
la ejecución iterativa (looping). El for
declaración tiene inicialización separada, las pruebas y las expresiones de reinicialización, cualquiera o todos los que se puede omitir. break
y continue
se puede utilizar para salir de la sentencia de bucle más interno o saltar a su reinicialización. También es un no-estructurada goto
declaración que se ramifica directamente al designado la etiqueta dentro de la función. switch
selecciona un case
para ser ejecutado sobre la base del valor de una expresión entera.
Las expresiones pueden utilizar una variedad de operadores integrados y pueden contener llamadas a funciones. El orden en que se evalúan los argumentos de funciones y operandos a la mayoría de los operadores no se especifica. Las evaluaciones pueden incluso estar intercalada. Sin embargo, todos los efectos secundarios (incluido el almacenamiento de variables) se producirá antes de la próxima " punto secuencia "; puntos de secuencia incluye al final de cada declaración de la expresión, y la entrada y retorno de cada llamada a la función también puntos de secuencia se producen durante la evaluación de expresiones que contienen determinados operadores (. &&
, ||
, ?:
y la operador de coma). Esto permite un alto grado de optimización de código objeto por el compilador, pero requiere de programadores de C que tener más cuidado para obtener resultados fiables que se necesita para otros lenguajes de programación.
Kernighan y Ritchie decir en la introducción del lenguaje de programación C: "C, al igual que cualquier otro idioma, tiene sus manchas Algunos de los operadores tienen la precedencia mal, algunas partes de la sintaxis podría ser mejor.". El estándar de C no trató de corregir muchos de estos defectos, debido al impacto de dichos cambios en el software ya existente.
Conjunto de caracteres
El conjunto de caracteres fuente básica C incluye los siguientes caracteres:
- Cartas:
a
-z
,A
-Z
,_
- Dígitos:
0
-9
- Puntuacion:
~ ! @ # % ^ & * ( ) - + = : ; " ' < > , . ? | / \ { } [ ]
~! @ #% ^ & * () - + =:; " ' < > , . ? | / \ { } [ ]
- Espacios en blanco: espacio, tabulador horizontal, pestaña vertical, avance de página, nueva línea
Nueva línea indica el final de una línea de texto; no es necesario que corresponde a un solo carácter real, aunque por conveniencia C trata como uno.
Caracteres adicionales de varios bytes codificados se pueden usar, pero no son portátil. El estándar más reciente C ( C11) permite multinacional Caracteres Unicode para incrustar portable dentro del texto fuente en C utilizando un \u DDDD
codificación (donde DDDD
denota un código de caracteres Unicode), aunque esta característica no está todavía ampliamente implementado.
El conjunto de caracteres de ejecución básico C contiene los mismos personajes, junto con representaciones de alerta, retroceso, y retorno de carro. Apoyo en tiempo de ejecución para los conjuntos de caracteres extendidos se ha incrementado con cada revisión de la norma C.
Palabras clave
C89 tiene 32 palabras clave (palabras reservadas con significado especial):
|
|
|
|
C99 añade cinco palabras clave:
|
|
|
C11 añade siete palabras clave:
|
|
|
|
La mayoría de las palabras clave se han incorporado recientemente a comenzar con un guión bajo seguido de una letra mayúscula, porque los identificadores de forma que antes estaban reservadas por la norma C para uso exclusivo de las implementaciones. Desde código fuente del programa existente no debería haber sido el uso de estos identificadores, no se vería afectada cuando C implementaciones comenzaron apoyar estas extensiones al lenguaje de programación. Algunas cabeceras estándar hacen definir sinónimos más convenientes para los identificadores subrayados. El lenguaje utilizado para incluir una palabra clave reservada llamada entry
, pero esto nunca se llevó a cabo y ahora se ha eliminado como una palabra reservada.
Operadores
C es compatible con un amplio conjunto de operadores, que son símbolos utilizados dentro de una expresión para especificar las manipulaciones a realizar mientras se evalúa la expresión. C tiene operadores para:
- aritmética :
+
,-
,*
,/
,%
- asignación:
=
- asignación aumentada:
+=
,-=
,*=
,/=
,%=
,&=
,|=
,^=
,<<=
,>>=
- bit a bit lógica:
~
,&
,|
,^
- cambios a nivel de bits:
<<
,>>
- lógica booleana:
!
,&&
,||
- Evaluación condicional:
? :
- pruebas de la igualdad:
==
,!=
- funciones llamando al:
( )
- incremento y decremento:
++
,--
- selección de miembros:
.
,->
- tamaño del objeto:
tamaño de
- relaciones de orden:
<
,<=
,>
,>=
- referencia y eliminar la referencia:
&
,*
,[ ]
- secuenciación:
,
- subexpresión agrupación:
( )
- conversión de tipo:
( typename )
C utiliza el =
operador, reservada en las matemáticas para expresar la igualdad, para indicar la asignación, siguiendo el precedente de Fortran y PL / I, pero a diferencia de ALGOL y sus derivados. La similitud entre el operador de C para la asignación y el de igualdad ( ==
) ha sido criticada, ya que hace que sea fácil de sustituir accidentalmente uno para el otro. En muchos casos, cada uno puede ser utilizado en el contexto de la otra sin un error de compilación (aunque algunos compiladores producen advertencias). Por ejemplo, la expresión condicional en if(a=b+1)
es verdadero si a
no es cero después de la asignación. Adicionalmente, C de precedencia de los operadores no es intuitivo, como ==
vinculante con más fuerza que &
y |
en expresiones como x & 1 == 0
, que tendrían que ser por escrito (x & 1) == 0
para ser evaluados correctamente.
"Hola, mundo" ejemplo
El " hola ", ejemplo del mundo, que apareció en la primera edición de K & R, se ha convertido en el modelo para un programa de introducción en la mayoría de los libros de texto de programación, independientemente del lenguaje de programación. El programa imprime "hola, mundo" a la salida estándar, que normalmente es una pantalla del terminal o de la pantalla.
La versión original fue:
main () { printf ("hola, mundo \ n"); }
A que sigan los estándares "hola, mundo" programa es:
#includeint main (void) { printf ("hola, mundo \ n"); }
La primera línea del programa contiene una directiva de preprocesamiento, indicado por #include
. Esto hace que el compilador para reemplazar esa línea con el texto completo de la stdio.h
encabezado estándar, que contiene las declaraciones de funciones de entrada y salida estándar como printf
. Las escuadras que rodean stdio.h
indican que stdio.h
se encuentra utilizando una estrategia de búsqueda que prefiere cabeceras estándar a otras cabeceras que tienen el mismo nombre. (Las comillas dobles se utilizan para incluir archivos de cabecera locales o específicos del proyecto.)
La siguiente línea indica que una función llamada main
se está definiendo. La main
función sirve un propósito especial en los programas de C; el entorno de tiempo de ejecución llama a la main
función para iniciar la ejecución del programa. El especificador de tipo int
indica que el valor que se devuelve al invocador (en este caso el entorno de tiempo de ejecución) como resultado de la evaluación de la main
función, es un número entero. La palabra clave void
como una lista de parámetros indica que esta función no tiene argumentos.
La llave de apertura indica el comienzo de la definición de la main
función.
La siguiente línea llama (desvía ejecución a) una función llamada printf
, que se suministra desde un sistema de biblioteca. En esta convocatoria, el printf
se pasa la función (siempre con) un solo argumento, la dirección del primer carácter de la cadena literal "hello, world\n"
. La cadena literal es un anónimo matriz con elementos de tipo char
, creado automáticamente por el compilador con un carácter final 0 valorada para marcar el final de la matriz ( printf
necesita saber esto). El \n
es una secuencia de escape que C se traduce en una carácter de nueva línea, que en la salida significa el final de la línea actual. El valor de retorno de la printf
función es de tipo int
, pero se Silenciosamente descartado ya que no se utiliza. (Un programa más prudente podría probar el valor de retorno para determinar si es o no el printf
función tuvo éxito.) El punto y coma ;
termina el comunicado.
La llave de cierre indica el final del código de la main
función. De acuerdo con la especificación C99 y más reciente, main
volverá implícitamente un estado de 0 al alcanzar el} que termina la función. Esto es interpretado por el sistema de tiempo de ejecución como un código de salida que indica una ejecución exitosa.
Los tipos de datos
C tiene un estático tipificación débil el tipo de sistema que comparte algunas similitudes con la de otra Descendientes ALGOL tales como Pascal. Hay tipos incorporados para números enteros de varios tamaños, ambos firmados y sin firmar, números de punto flotante, personajes y tipos enumerados ( enum
). C99 añadió una un tipo booleano. También hay tipos derivados incluidos matrices, punteros, registros ( struct
), y sin etiquetar sindicatos ( union
).
C se utiliza a menudo en los sistemas de programación de bajo nivel, donde se escapa del sistema de tipos puede ser necesario. El compilador intenta asegurar tipo de corrección de la mayoría de las expresiones, pero el programador puede invalidar los controles de diversas maneras, ya sea mediante el uso de una escriba fundido para convertir explícitamente un valor de un tipo a otro, o por el uso de punteros o uniones de reinterpretar los bits subyacentes de un objeto de datos de alguna otra manera.
Algunos encuentran sintaxis de declaración de C poco intuitivo, en particular para punteros de función. (La idea de Ritchie fue declarar identificadores en contextos parecidos a su uso: " declaración refleja su uso ".)
Conversiones aritméticas habituales de C permiten un código eficiente que se genere, pero a veces pueden producir resultados inesperados. Por ejemplo, una comparación de números enteros con y sin signo de igual anchura requiere una conversión del valor con signo a signo. Esto puede generar resultados inesperados si el valor con signo es negativo.
Punteros
C apoya el uso de punteros, un tipo de referencia que registra la dirección o ubicación de un objeto o función en la memoria. Los punteros se pueden conviertan a acceder a los datos almacenados en la dirección apuntada, o para invocar un punta-a-función. Los punteros se pueden manipular mediante cesión o aritmética de punteros. La representación de tiempo de ejecución de un valor de puntero es típicamente una dirección de memoria en bruto (tal vez aumentada por un campo de desplazamiento-dentro-palabra), pero ya que el tipo de un puntero incluye el tipo de la cosa señaló, expresiones incluyendo punteros pueden ser de tipo a cuadros en tiempo de compilación. La aritmética de punteros se escala automáticamente por el tamaño de la punta de tipo de datos. Los punteros se utilizan para muchos propósitos diferentes en C. Las cadenas de texto son manipulados habitualmente el uso de punteros en arrays de caracteres. Asignación dinámica de memoria se realiza utilizando punteros. Muchos tipos de datos, tales como árboles, se implementan comúnmente como asignados dinámicamente struct
objetos vinculados entre sí mediante punteros. Punteros a funciones son útiles para pasar funciones como argumentos para funciones de orden superior (por ejemplo, qsort o bsearch) o como devoluciones de llamada para ser invocadas por los controladores de eventos.
La valor de puntero nulo señala explícitamente a ninguna ubicación válida. Dereferencing un valor de puntero nulo no está definido, a menudo resultando en una fallo de segmentación. Valores punteros nulos son útiles para indicar casos especiales como no "siguiente" puntero en el nodo final de una lista enlazada, o como una indicación de error de funciones que devuelven punteros. En contextos apropiados en el código fuente, como para asignar a una variable puntero, una constante de puntero nulo puede ser escrito como 0
, con o sin conversión explícita a un tipo de puntero, o como el NULL
macro definida por varias cabeceras estándar. En contextos condicionales, valores de puntero nulo resultado false, mientras que todos los demás valores de puntero como resultado true.
Punteros void ( void *
) apuntan a objetos de tipo no especificado, y por lo tanto se pueden utilizar como punteros de datos "genéricos". Dado que el tamaño y el tipo de la aritmética de punteros puntas de oponerse no se conoce, punteros void no pueden ser desreferenciados, ni es en ellos permitió, aunque pueden ser fácilmente (y en muchos contextos implícitamente son) convertida desde y hacia cualquier otro objeto puntero escriba.
El uso descuidado de los punteros es potencialmente peligroso. Debido a que son típicamente no se controla, una variable de puntero se puede hacer para que apunte a cualquier lugar arbitrario, que puede causar efectos no deseados. Aunque los punteros usados adecuadamente señalan a lugares seguros, que se pueden hacer para que apunte a lugares inseguros mediante el uso no válido aritmética de punteros; los objetos a los que apuntan pueden cancelar la asignación y reutilizados ( punteros colgantes); pueden ser utilizados sin haber sido inicializado ( punteros silvestres); o pueden ser directamente asignado un valor seguro usando un yeso, unión, o por medio de otro puntero corrupto. En general, C es permisiva en que permite la manipulación de y conversión entre tipos de puntero, aunque los compiladores suelen ofrecer opciones para los distintos niveles de cheques. Algunos otros lenguajes de programación frente a estos problemas mediante el uso más restrictivo los tipos de referencia.
Arrays
Tipos de matriz en C son tradicionalmente de un tamaño fijo, estático especificado en tiempo de compilación. (La norma más reciente C99 también permite una forma de matrices de longitud variable.) Sin embargo, también es posible asignar un bloque de memoria (de tamaño arbitrario) en tiempo de ejecución, utilizando de la biblioteca estándar malloc
función, y tratarlo como una matriz. Unificación de C de Arrays y punteros medios que declaró matrices y estas matrices simulados asignados dinámicamente son prácticamente intercambiables.
Desde arrays siempre se accede (en efecto) a través de punteros, los accesos de matriz no son típicamente controlados con respecto al tamaño de la matriz subyacente, aunque algunos compiladores pueden proporcionar comprobación de los límites como una opción. Matriz limita violaciónes son, por tanto, posible y bastante común en código escrito de forma descuidada, y pueden dar lugar a diversas consecuencias, incluyendo la memoria ilegal accesos, la corrupción de los datos, desbordamientos de búfer, y las excepciones de tiempo de ejecución. Si se desea la comprobación de los límites, hay que hacerlo de forma manual.
C no tiene una disposición especial para declarar matrices multidimensionales, sino que se basa en la recursividad en el sistema de tipos de declarar matrices de matrices, que lleva a cabo efectivamente la misma cosa. Los valores del índice de la "matriz multidimensional" resultante puede ser pensado como el aumento en de las filas orden.
Las matrices multidimensionales se utilizan comúnmente en algoritmos numéricos (principalmente de aplicada álgebra lineal ) para almacenar matrices. La estructura de la matriz C es muy adecuado para esta tarea particular. Sin embargo, como los arrays se pasan únicamente como punteros, los límites de la matriz se deben conocer los valores fijos o de lo contrario pasa explícitamente a cualquier subrutina que les obliga, y arrays dinámicamente tamaño de las matrices no se pueden acceder mediante doble indexación.(Una solución para esto es para asignar la matriz con un "vector fila" adicional de punteros a las columnas.)
C99 introdujo "arrays de longitud variable" que se refieren a algunos, pero no todos, de los problemas con las matrices C ordinarios.
Intercambiabilidad matriz triple
El subíndice notación x [i]
(donde X
designa un puntero) es un azúcar sintáctico para * (X + i)
. Aprovechando el conocimiento del compilador del tipo de puntero, la dirección que x + i
señala es que no la dirección base (apuntado por X
) incrementa en yo
bytes, sino más bien se define como la dirección base incrementado en yo
multiplicado por el tamaño de un elemento que X
puntos a.
Además, en la mayoría de los contextos de expresión (una excepción notable es como operando de tamaño de
), el nombre de una matriz se convierte automáticamente en un puntero al primer elemento de la matriz; Así, para una matriz declarado con el nombre LA
, A [i]
designa el i + 1
º elemento de la matriz. Esto también implica que una matriz no se copia en su conjunto cuando se nombró como argumento de una función, pero se pasa más bien sólo la dirección de su primer elemento. Por lo tanto, a pesar de las llamadas a funciones en el uso de C pasan por valor semántico, las matrices son , en efecto, aprobada por referencia.
El tamaño de un elemento se puede determinar aplicando el operador tamaño de
a cualquier elemento de desreferenciado X
, como en n = sizeof * x
o n = sizeof x [0]
, y el número de elementos en un array declarado LA
se puede determinar como sizeof A / sizeof A [0]
. Este último sólo se aplica a los nombres de matriz: variables declaradas con subíndices ( int A [20]
). Debido a la semántica de C, no es posible determinar el tamaño completo de matrices a través de punteros a las matrices o los creados por la asignación dinámica ( malloc
); código como sizeof arr / sizeof arr [0]
(donde arr = A
designa un puntero) no funcionará ya que el compilador asume el tamaño del puntero en sí se solicita. Desde argumentos de nombre de matriz a tamaño de
no se convierten a los punteros, que no presentan tal ambigüedad. Sin embargo, las matrices creadas por la asignación dinámica se inicializan a los punteros en lugar de variables de matriz verdaderos, por lo que sufren de los mismos tamaño de
problemas como punteros de matriz.
Por lo tanto, a pesar de esta aparente equivalencia entre variables de matriz y el puntero, todavía hay una distinción que debe hacerse entre ellos. A pesar de que el nombre de una matriz es, en la mayoría de los contextos de expresión, convertida en un puntero (a su primer elemento), este puntero no en sí ocupa ningún almacenamiento; el nombre de la matriz no es un valor izquierdo, y su dirección es una constante , a diferencia de una variable puntero. En consecuencia, lo que es un array "apunta a" no se puede cambiar, y es imposible asignar una nueva dirección a un nombre de la matriz. Contenido de la matriz puede ser copiado, sin embargo, mediante el uso de la memcpy
función, o accediendo a los elementos individuales.
Gestión de la memoria
Una de las funciones más importantes de un lenguaje de programación es proporcionar instalaciones para la gestión de la memoria y los objetos que se almacenan en la memoria. C proporciona tres formas distintas para asignar memoria para los objetos:
- Asignación de memoria estática: espacio para el objeto se proporciona en el binario en tiempo de compilación; estos objetos tienen una medida (o de por vida) siempre y cuando el binario que los contiene se carga en memoria.
- Asignación de memoria automática: objetos temporales se pueden almacenar en lapila, y este espacio se libera y reutilizable automáticamente después de que el bloque en el que se declaran se sale.
- Asignación de memoria dinámica: bloques de memoria de tamaño arbitrario se pueden solicitar en tiempo de ejecución utilizando funciones de biblioteca como
malloc
de una región de la memoria llamado el montón; estos bloques persisten hasta que posteriormente liberados para su reutilización llamando a la función de la bibliotecarealloc
ogratis
Estos tres enfoques son adecuados en diferentes situaciones y tienen diferentes ventajas y desventajas. Por ejemplo, la asignación de memoria estática tiene poca sobrecarga de asignación, asignación automática puede implicar un poco más arriba, y la asignación de memoria dinámica potencialmente pueden tener una gran cantidad de gastos generales tanto para la asignación y desasignación. La naturaleza persistente de objetos estáticos es útil para mantener información de estado a través de llamadas a funciones, asignación automática es fácil de usar, pero el espacio de pila es típicamente mucho más limitada y transitoria que cualquiera de memoria estática o espacio de montón, y la asignación de memoria dinámica permite la asignación adecuada de objetos cuya tamaño sólo se conoce en tiempo de ejecución. La mayoría de los programas en C hacen un amplio uso de los tres.
Siempre que sea posible la asignación, automática o estática suele ser más simple, porque el almacenamiento se gestiona por el compilador, liberando al programador de la tarea potencialmente propenso a errores de asignación y liberación de almacenamiento de forma manual. Sin embargo, muchas de las estructuras de datos pueden cambiar de tamaño en tiempo de ejecución, y puesto que las asignaciones estáticas (y las asignaciones automáticas antes C99) deben tener un tamaño fijo en tiempo de compilación, hay muchas situaciones en las que la asignación dinámica es necesario. Antes de la norma C99, arrays de tamaño variable eran un ejemplo común de esto. (Ver el artículo sobre malloc
un ejemplo de matrices asignados dinámicamente.) A diferencia de la asignación automática, que puede fallar en tiempo de ejecución con consecuencias no controladas, las funciones de asignación dinámica devuelven una indicación (en forma de un valor de puntero nulo) cuando el almacenamiento requerido no puede asignar. (Asignación estática que es demasiado grande generalmente es detectado por el enlazador o cargador, antes de que el programa puede incluso comenzar la ejecución.)
A menos que se especifique lo contrario, los objetos estáticos contienen cero o nulos valores de puntero sobre el arranque del programa. Se inicializan los objetos de forma automática y dinámicamente asignados sólo si se especifica explícitamente un valor inicial; de lo contrario, inicialmente tienen valores indeterminados (típicamente, cualquiera que sea patrón de bits pasa a estar presente en el almacenamiento, que ni siquiera podría representar un valor válido para ese tipo). Si el programa intenta acceder a un valor no inicializado, los resultados no están definidos. Muchos compiladores modernos tratan de detectar y advertir acerca de este problema, pero tanto los falsos positivos y falsos negativos pueden ocurrir.
Otra cuestión es que la asignación de memoria heap tiene que ser sincronizado con su uso real en cualquier programa con el fin de que pueda ser reutilizado tanto como sea posible. Por ejemplo, si el único puntero a una asignación de memoria heap sale del ámbito o ha su valor sobrescrito antes libre ()
se llama, pues, que la memoria no se puede recuperar para su reutilización posterior y se pierde la esencia del programa, un fenómeno conocido como pérdida de memoria. A la inversa, es posible para la memoria para ser liberado pero sigue haciendo referencia, dando lugar a resultados impredecibles. Por lo general, van a aparecer los síntomas en una parte del programa alejado del error real, por lo que es difícil de rastrear el problema. (Estas cuestiones se mejoran en idiomas con la recolección de basura automática.)
Bibliotecas
El lenguaje de programación C utiliza las bibliotecas como su principal método de extensión. En C, una biblioteca es un conjunto de funciones contenidas dentro de un solo archivo "archivo". Cada biblioteca tiene típicamente un archivo de cabecera, que contiene los prototipos de las funciones contenidas dentro de la biblioteca que pueden ser utilizados por un programa, y declaraciones de tipos de datos especiales y símbolos macro utilizados con estas funciones. Para que un programa para utilizar una biblioteca, debe incluir el archivo de cabecera de la biblioteca, y la biblioteca debe estar vinculada con el programa, que en muchos casos requiere opciones del compilador (por ejemplo, -lm
, abreviatura de "biblioteca matemática").
La biblioteca C más común es la biblioteca estándar de C, que se especifica por las ISO y las normas ANSI C y viene con cada aplicación C. (Implementaciones que se dirigen a entornos limitados, tales como sistemas integrados pueden ofrecer sólo un subconjunto de la biblioteca estándar.) Esta biblioteca soporta valores de tiempo de entrada de corriente y la salida, asignación de memoria, matemáticas, cadenas de caracteres, y. Varias cabeceras estándar separadas (por ejemplo, stdio.h
) especifican las interfaces para estas y otras instalaciones de la biblioteca estándar.
Otro conjunto común de funciones de la biblioteca C son los utilizados por las aplicaciones dirigidas específicamente para Unix y sistemas tipo Unix, especialmente las funciones que proporcionan una interfaz para el kernel. Estas funciones se detallan en diversas normas tales como POSIX y la Single UNIX Specification.
Dado que muchos programas se han escrito en C, hay una amplia variedad de otras bibliotecas disponibles. Las bibliotecas son a menudo escritos en C porque los compiladores de C generan eficiente código objeto; programadores luego crean interfaces a la biblioteca para que las rutinas se pueden usar de lenguajes de alto nivel como Java , Perl y Python .
Herramientas del idioma
Herramientas se han creado para ayudar a los programadores de C evitar algunos de los problemas inherentes a la lengua, como las declaraciones con un comportamiento indefinido o declaraciones que no son una buena práctica, ya que son propensos a provocar un comportamiento no deseado o en tiempo de ejecución errores.
Comprobación de código fuente automatizada y la auditoría son beneficiosos en cualquier idioma, y para C existen muchas de estas herramientas, como la pelusa. Una práctica común es utilizar la pelusa para detectar código cuestionable cuando un programa está escrito primero. Una vez que un programa pasa Lint, se compila con el compilador C. También, muchos compiladores opcionalmente pueden advertir sobre construcciones sintácticamente válidos que puedan ser en realidad errores. MISRA C es un conjunto exclusivo de directrices para evitar dicho código cuestionable, desarrollado para sistemas embebidos.
También hay compiladores, bibliotecas, y los mecanismos a nivel de sistema operativo para la realización de acciones que no son una parte estándar de C, tales como límites de la matriz de cheques,la detección de desbordamiento de búfer,la serialización, yla recolección de basura automática.
Herramientas comoPurify oValgrind y enlazan con las bibliotecas que contienen versiones especiales de lasfunciones de asignación de memoria puede ayudar a descubrir los errores de ejecución en el uso de la memoria.
Usos
C se utiliza a menudo para " programación del sistema ", incluyendo la implementación de sistemas operativos y aplicaciones de sistemas embebidos, debido a una combinación de características deseables tales como la portabilidad de código y la eficiencia, la capacidad de acceder a direcciones de hardware específicos, capacidad de juego de palabras para que coincida con los tipos de acceso a datos impuesta externamente requisitos y bajo demanda en tiempo de ejecución de los recursos del sistema. C también se puede utilizar para la programación web usando CGI como una "puerta de entrada" para obtener información entre la aplicación Web, el servidor y el navegador. Algunas de las razones para la elección de C en lenguajes interpretados son su velocidad, la estabilidad y la disponibilidad casi universal.
Una consecuencia de la amplia disponibilidad y la eficiencia de C es que compiladores, bibliotecas, e intérpretes deotroslenguajes de programación se implementan a menudo en C. Las implementaciones principales dePython(CPython),Perl5 yPHP están escritos en C.
Debido a su fina capa de abstracción y bajo costo operativo, C permite implementaciones eficientes de algoritmos y estructuras de datos, que es útil para los programas que llevan a cabo una gran cantidad de cálculos. Por ejemplo, el GNU Multi-Precision Biblioteca, elGNU Scientific Library,Mathematica yMATLAB son completamente o parcialmente escrito en C.
C se utiliza a veces como un lenguaje intermedio por las implementaciones de otros idiomas. Este enfoque puede ser utilizado para la portabilidad o conveniencia; mediante el uso de C como un lenguaje intermedio, no es necesario el desarrollo de generadores de código específicos de la máquina. C tiene algunas características, como la línea de números directivas de preprocesador y comas superfluos opcionales al final de las listas de inicializadores, que apoyan la compilación del código generado. Sin embargo, algunos de los defectos de C han impulsado el desarrollo de otros idiomas basados en C diseñados específicamente para su uso como lenguas intermedias, como C--.
C también ha sido ampliamente utilizado para implementaraplicaciones de usuario final, pero gran parte de que el desarrollo se ha desplazado a nuevos idiomas.
Idiomas relacionados
C ha influido directa o indirectamente muchos idiomas posteriores como C #, D, Vaya, Java , JavaScript Limbo, LPC, Perl , PHP, Python , y es Unix C Shell. La influencia más generalizada ha sido sintáctica: todas las lenguas mencionadas combinan la declaración y (más o menos reconocible) la expresión de sintaxis de C con sistemas de tipos, modelos de datos y / o estructuras de programas a gran escala que se diferencian de los de C, a veces radicalmente .
Existen varios intérpretes C o cerca-C, incluyendoCh yCINT, que también se puede utilizar para scripting.
Cuando lenguajes orientados a objetos se hizo popular, C ++ y Objective-C fueron dos extensiones diferentes de C que proporciona capacidades orientadas a objetos. Ambas lenguas se implementaron originalmente como compiladores de código-fuente; código fuente fue traducido a C, y luego se compila con un compilador C.
El C ++ lenguaje de programación fue ideado por Bjarne Stroustrup como un enfoque para proporcionar funcionalidad orientada a objetos con una sintaxis similar a C. C ++ añade una mayor fuerza de mecanografía, de alcance, y otras herramientas útiles en la programación orientada a objetos y permite la programación genérica a través de plantillas. Casi un superconjunto de C, C ++ es ahora compatible con la mayor parte de C, con algunas excepciones (véase Compatibilidad de C y C ++).
Objective-C fue originalmente una capa muy "fina" en la parte superior de C, y sigue siendo un superconjunto estricto de C que permite la programación orientada a objetos utilizando un paradigma híbrido dinámico / estático a escribir. Objective-C deriva su sintaxis de C y tanto Smalltalk: sintaxis que involucra procesamiento previo, expresiones, declaraciones de funciones, y la función llamadas se hereda de C, mientras que la sintaxis de características orientadas a objetos fue tomada originalmente de Smalltalk.
Además deC ++y Objective-C, Ch,Cilk yUnified Parallel C son casi superseries de C.