Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Proyecto Final: C
Generalidades
C es el lenguaje de programacin ideado por Kernighan y Ritchie. El lenguaje C
recibi este nombre por considerarse una evolucin del lenguaje B.
Este resumen presenta las principales caractersticas de C que hay que
implementar para el Proyecto de la asignatura de Compiladores. No es
necesario considerar los elementos de C no mencionados en este resumen.
Entre corchetes se dan indicaciones sobre la obligatoriedad u opcionalidad de
algunas partes del lenguaje. Con el fin de facilitar la implementacin del
compilador, las caractersticas mostradas en esta pgina pueden no coincidir al
100% con el estndar del lenguaje, por lo que, en caso de duda, se deber
implementar el comportamiento aqu descrito.
C es un lenguaje en el que se diferencian las minsculas y las maysculas (es
case sensitive). Tambin es un lenguaje de formato libre, es decir, que se
admiten espacios, tabuladores, saltos de lnea y comentarios en cualquier parte
del cdigo. Cada instruccin puede ocupar una o varias lneas. Las sentencias
y declaraciones terminan siempre en un punto y coma ( ;)
Las palabras clave que tiene el lenguaje son reservadas, aunque cada grupo
de alumnos slo ha de tener en cuenta las palabras asignadas a su grupo.
C es un lenguaje con estructura de bloques que se definen mediante la
utilizacin de las llaves { } y, por tanto, maneja los conceptos de nombres
globales y locales. Los nombres declarados fuera de cualquier funcin son
globales y pueden ser utilizados desde cualquier funcin. Los declarados en el
interior de una funcin son locales a dicha funcin.
En C es necesario declarar los identificadores antes de que se utilicen.
Adems, hay que implementar el Compilador de C considerando que es un
lenguaje con recursividad, por lo que cualquier funcin puede ser recursiva.
No se permite la definicin de funciones anidadas. El paso de parmetros es
por valor, salvo para cadenas y vectores, que es por referencia.
Estructura de un Programa
Para el Proyecto de Compiladores debe considerarse que un programa en C
estar compuesto por un nico fichero que ha de tener una serie de funciones,
Programa Principal
El programa principal (el que se ejecutar al arrancar el programa) ser una
funcin especial que recibe el nombre de main, que no puede llevar argumentos
y tiene que ser de tipo void:
void main (void)
{
implementacin_de_la_funcin_principal;
}
Comentarios
En C los comentarios se indican con los caracteres /* para abrir el comentario,
y con los caracteres */ para cerrarlo. No se admiten comentarios anidados. Los
comentarios pueden ocupar ms de una lnea y pueden ir colocados en
cualquier parte del cdigo donde pueda ir un espacio:
/* Comentario con apertura y cierre */
Constantes
El lenguaje dispone de varios tipos de constantes, de las cuales solamente
habr que tener en cuenta las siguientes:
Enteros
Las constantes enteras se escribirn en notacin decimal sin signo (por
ejemplo, 159, 0). El ensamblador que se utilizar dispone de nmeros enteros
de 2 bytes (con signo), por lo que el mximo entero ser el 32767.
El lenguaje tambin dispone de constantes enteras en notacin octal (usando
como prefijo un cero: 052) y en notacin hexadecimal (usando como prefijo un
cero y una equis: 0x1E4). [La implementacin de la notacin octal y hexadecimal
es opcional.]
Cadenas de Caracteres
Las constantes de cadena consisten en una secuencia de caracteres
encerrados entre comillas ("Hola, mundo!"). Las cadenas utilizan el carcter nulo
(cuyo cdigo ASCII es 0) como carcter de fin de cadena. Puede aparecer
cualquier carcter imprimible en la cadena. Para representar caracteres
especiales se utiliza una secuencia de escape, que comienza mediante el
carcter barra inversa y va seguido de un carcter. Algunos de estos caracteres
especiales son el salto de lnea ( \n), el tabulador (\t), el carcter nulo (\0), las
comillas dobles (\") o el carcter de barra inversa ( \\). Por ejemplo, la constante
Lgicas
En C no hay constantes lgicas propiamente dichas. Cualquier expresin que
se evale como 0 se considera como falso, y cualquier expresin que se evale
con un valor distinto a 0 se considera verdadera.
Operadores
Este lenguaje presenta un conjunto de operadores con los que escribir distintas
expresiones. Adems, se pueden utilizar los parntesis para agrupar
subexpresiones.
Operadores Aritmticos
Son los operadores que permiten realizar la suma, resta, producto, divisin y
mdulo: +, -, *, / y % [obligatorio implementar al menos uno]. Se aplican sobre
datos enteros, proporcionando un resultado entero.
Tambin existen los operadores ms y menos unarios: +, - [implementacin
opcional].
Operadores de Relacin
Son los operadores que permiten realizar las comparaciones de igual, distinto,
menor, mayor, menor o igual, mayor o igual: ==, !=, <, >, <= y >= [obligatorio
implementar todos los operadores]. Se aplican sobre datos enteros y
proporcionan un resultado lgico (0 si es falso, 1 si es verdadero).
Operadores Lgicos
Representan las operaciones de conjuncin, disyuncin y negacin: &&, || y !
[obligatorio implementar los operadores]. Se aplican sobre datos lgicos y
devuelven un resultado lgico (0 si es falso, 1 si es verdadero).
Operadores de asignacin
/* es equivalente a n = n + m; */
Operador Condicional
Permiten obtener un valor basndose en una condicin: condicin ? exp1: exp2
[implementacin obligatoria]. Si la condicin es cierta, devuelve exp1, en caso
contrario, devuelve exp2. Ejemplo:
max = (a > b) ? a : b;
Precedencia de Operadores
En la tabla siguiente se muestra la precedencia de los operadores con el
siguiente significado: los operadores del mismo grupo tienen la misma
precedencia y, conforme se desciende por la tabla, la precedencia disminuye.
En cualquier caso, el uso de parntesis permite alterar el orden de evaluacin
de las expresiones [es obligatorio para todos los grupos implementar el uso de
parntesis y tener en cuenta las precedencias de sus operadores].
Precedencias de los Operadores
Operadores Significado
Asociatividad
Referencia
a
campo
de
estructura
.
()
Llamada
a
funcin Izquierda a derecha
[]
Referencia a elemento de vector
Negacin
lgica
!
Autoincremento
++
-Autodecremento
Derecha a izquierda
+
Ms
unario
Menos unario
*
Producto
Izquierda a derecha
/
Asociatividad
Izquierda a derecha
Izquierda a derecha
Izquierda a derecha
Izquierda a derecha
Izquierda a derecha
Derecha a izquierda
Derecha a izquierda
Identificadores
Los nombres de identificadores estn formados por cualquier cantidad de
letras, dgitos y subrayados ( _), siendo el primero siempre una letra o un
subrayado. Ejemplos: a, a3, A3, Sueldo_de_Trabajador, _9_9__...
Como ya se ha dicho, el lenguaje es dependiente de minsculas o maysculas,
por lo que los nombres a3 y A3 referencian a identificadores distintos.
Declaraciones
En el lenguaje C se exige la declaracin de variables antes de poder usarlas.
No se admite la redeclaracin de nombres en un mismo mbito. La declaracin
de variables se realiza fuera de las funciones (variables globales) o en las
funciones (variables locales).
Para realizar una declaracin de una variable, se escribe el nombre del tipo
seguido del nombre de la variable, finalizando en un punto y coma ( ;).
Se puede poner una lista de variables separadas por comas [esta declaracin
mltiple es opcional].
Tipo var0;
Tipo var1, var2, var3; /*se declaran tres variables*/
Tipos de Datos
El lenguaje dispone de distintos tipos de datos, que pueden ser clasificados en
Tipos Bsicos (o elementales) y Tipos Compuestos (que se forman a partir de
tipos bsicos).
Tipos Bsicos
Se deben considerar slo los siguientes tipos de datos bsicos: entero, lgico y
vaco.
El tipo entero (que se representa con la palabra int) se refiere a un entero que
debe representarse con un tamao de 16 bits.
El tipo lgico (que no tiene representacin en C) permite representar valores
lgicos. Las expresiones relacionales y lgicas devuelven un valor lgico,
aunque no existen variables de tipo lgico. Cualquier tipo se puede usar con
dicho fin: al evaluarse como 0 se considera falso y, en caso contrario,
verdadero.
El tipo vaco (que se representa con la palabra void) indica la inexistencia de un
tipo propiamente dicho (se usa para funciones que no devuelven ningn valor y
cuando las funciones no reciben argumentos).
El lenguaje permite conversiones entre tipos: de entero a lgico y viceversa.
int dia, mes, fin;
fin= dia == 31 && mes == 12; /* el 31 de diciembre, fin valdr 1 (cierto) */
Tipos Compuestos
Cada grupo tendr que implementar uno de estos tipos compuestos,
basndose en la opcin que le corresponda. En los ejemplos se va a hacer uso
de elementos del lenguaje que se explicarn posteriormente.
Vectores
Para usar un vector es obligatorio declarar una variable de tipo vector. Su
declaracin es de la siguiente forma [implementacin obligatoria]:
int nombre_var [tamao];
El valor tamao debe ser un valor entero constante que especifica la dimensin
del vector. Los ndices del vector van desde 0 hasta tamao - 1, ambos incluidos.
Los elementos del vector son enteros [no hay que implementar vectores de
tipos compuestos].
Para acceder a un elemento del vector se usan los operadores corchete ( [ y ])
con el ndice en su interior. El ndice del vector puede ser cualquier expresin
entera vlida:
int v[31], w[31];
/* Se han declarado los vectores v y w de 31 elementos enteros */
/* Los ndices irn desde 0 hasta 30 */
int x[24];
/* Se ha declarado el vector x de 24 elementos enteros */
/* Los ndices irn desde 0 hasta 23 */
v[26]= 2;
/* se almacena un 2 en la posicin 26 */
x[3]= 13;
/* se almacena un 13 en la posicin 3 */
w[1]= v[x[3] * 2]; /* se almacena un 2 en la posicin 1 */
Cadenas
C dispone de una forma especfica para declarar cadenas basndose en el
tipo carcter: char *. La sintaxis para declarar o definir una variable cadena es
[implementacin obligatoria]:
char * variableCadena;
int campo2;
...
int campon;
};
Cada campo solo puede ser de tipo entero [no hay que implementar campos de
tipos compuestos]. Para usar una estructura hay que declarar primero el tipo
estructura y despus es necesario declarar una variable de dicho tipo para
acceder a los campos mediante el operador punto. El siguiente ejemplo
muestra la declaracin de una estructura y su uso:
struct Persona
{
int edad;
int mujer, jubilado;
int sueldo;
};
struct Persona yo;
yo.edad= 20;
yo.mujer= 0;
yo.jubilado= yo.edad > 65;
yo.sueldo= 300;
yo.sueldo= 300;
tu.mujer= !yo.mujer;
Q (yo, tu);
if (tu.mujer)
puts ("Hola, seora");
else
puts ("Hola, seor");
puts ("\nHas nacido en ");
putw (2007 - yo.edad);
if (!tu.jubilado)
{
puts ("Tu sueldo es "); putw (tu.sueldo);
puts (" euros al mes\n");
}
}
Instrucciones de Entrada/Salida
La funcin putw (expresin_entera) evala la expresin e imprime en pantalla su
resultado. Por ejemplo:
a= 50; putw (a * 2 + 16); /* imprime: 116 */
La funcin puts (cadena) imprime en pantalla la cadena. La cadena puede ser una
constante de tipo cadena [obligatorio para todos los grupos] o una variable de
tipo cadena [obligatorio para todos los grupos]. Por ejemplo:
a= "Adis"; puts ("Hola"); puts (a); /* imprime HolaAdis */
La funcin getw () lee un nmero entero del teclado y devuelve su valor. Por
ejemplo:
a= getw (); putw (a * a); /* imprime el cuadrado del nmero ledo */
La funcin gets (variable_cadena) lee una cadena del teclado, asignndose el valor
ledo a la variable recibida como parmetro [obligatoria para todos los grupos].
Por ejemplo:
gets (a); puts (a); /* imprime la cadena leda */
Sentencias
De todo el grupo de sentencias del lenguaje C, se han seleccionado para ser
implementadas en el Proyecto las que aparecen a continuacin [opcional u
obligatoriamente, segn se indique en cada caso]:
Sentencias de Asignacin
Sentencia Condicional
Selecciona la ejecucin de una de las secuencias de sentencias que encierra,
dependiendo del valor correspondiente de una condicin de tipo lgico. Tiene
dos formatos [implementacin obligatoria]:
if (condicin) sentencias1
if (condicin) sentencias1 else sentencias2
Sentencia Repetitiva
while
Sentencia Repetitiva
do while
Esta sentencia permite repetir la ejecucin de las sentencias del bucle mientras
se cumpla una condicin [implementacin obligatoria para algunos grupos]. La
sintaxis es: do sentencias while (condicin);. En esta instruccin se puede colocar
una nica sentencia o bien un bloque de sentencias encerradas entre llaves.
Se ejecutan las sentencias de forma repetitiva; seguidamente se evala la
condicin y, si resulta ser cierta (distinto de 0), se ejecutan de nuevo las
sentencias. Este proceso se repite hasta que la condicin sea falsa (se evale
como 0):
do {a++; c *= b;} while (a < b);
Sentencia Repetitiva
for
Esta sentencia for permite ejecutar un bucle segn una condicin compleja
[implementacin obligatoria]. La sintaxis es: for (inicializacin; condicin; actualizacin)
sentencias. La inicializacin debe ser una sentencia de asignacin o nada; la
condicin debe ser una expresin lgica; y la actualizacin puede ser una
asignacin, un autoincremento o autodecremento [para los grupos que tengan
esta opcin] o estar vaca. Las sentencias pueden estar formadas por un
bloque delimitado por llaves o por una nica sentencia.
El funcionamiento de este bucle es como sigue:
1.
2.
Se ejecuta la inicializacin
Se evala la condicin
3.
4.
5.
Se ejecuta la actualizacin
6.
Se vuelve al paso 2.
Sentencia break
Esta sentencia aborta la ejecucin de un bucle o un switch [implementacin
obligatoria]:
switch (dia)
{
case 1: puts ("lunes"); break;
case 2: puts ("martes");
case 3: puts ("mircoles"); break;
case 4: puts ("jueves"); break;
case 5: puts ("viernes"); break;
default: puts ("fiesta");
} /* si dia == 4, se imprimir: jueves */
Funciones
Es necesario definir cada funcin antes de poder utilizarla. La definicin de una
funcin se realiza indicando el tipo, el nombre y, entre parntesis, los tipos y
nombres de los argumentos (si existen). Tras esta cabecera va un bloque
(delimitado por llaves) que comienza con las declaraciones de variables locales
a la funcin (si existen) y, a continuacin, se tiene el cuerpo de la funcin:
Tipo nombreFun (lista de argumentos)
{
declaraciones
sentencias
}
Las funciones pueden recibir como parmetros cualquiera de los tipos bsicos
del lenguaje (entero), as como el tipo compuesto que le haya correspondido a
cada grupo.
Las funciones pueden devolver cualquiera de los tipos bsicos del lenguaje
(entero o vaco). Una funcin del tipo void indica que dicha funcin no retorna
ningn valor.
C admite recursividad. Cualquier funcin puede ser recursiva, es decir,
puede llamarse a s misma.
El lenguaje C no permite la definicin de funciones anidadas. Esto implica que
dentro de una funcin no se puede definir otra funcin.
Dentro de una funcin se tiene acceso a las variables locales que se declaren
en dicha funcin, a sus argumentos y a las variables globales. Si en una
funcin se declara una variable local o un argumento con el mismo nombre que
una variable global, sta ltima no es accesible desde dicha funcin.
factorial (int x)
/* se define la funcin recursiva entera con un parmetro entero */
{
if (x > 1)
return x * factorial (x - 1);
else
return 1;
}
void Suma (int aux [], int fin)
/* se define el procedimiento Suma que recibe un vector
por referencia y un entero por valor */
{
for (i= 1; i < fin; i= i + 2)
aux [i]= factorial (aux [i - 1]);
}
return factorial;
}
int FactorialWhile (int n)
{
int factorial = 1, i = 0;
while (i < n)
factorial *= ++i;
return factorial;
}
/*variable global*/