curso de lenguaje c - programacion estructurada · pdf filees un lenguaje de bajo-medio nivel,...

30
Curso de Lenguaje C Alexis Olvany torres

Upload: votruc

Post on 14-Feb-2018

215 views

Category:

Documents


1 download

TRANSCRIPT

Curso de Lenguaje C

Alexis Olvany torres

Índice

Índice..........................................................................................................................3

1. Introducción...........................................................................................................1

2. Estructura de un programa en C.............................................................................1

2.1. Instrucciones para el compilador...............................................................1

2.2. Definición de estructuras...........................................................................2

2.3. Definición de variables..............................................................................2

2.4. Funciones...................................................................................................2

2.5. Programa principal.....................................................................................2

3. Tipos y operadores ................................................................................................3

3.1. Tipos..........................................................................................................3

3.2. Estructuras.................................................................................................4

3.3. Uniones......................................................................................................5

3.4. Enumeraciones ..........................................................................................5

3.5. Modificadores de almacenamiento............................................................6

Modificador "extern"...............................................................................6

Modificador "auto"..................................................................................6

Modificador "register".............................................................................6

Modificador "const"................................................................................6

Modificador "volatile".............................................................................6

Modificador "static"................................................................................7

3.6 Operadores..................................................................................................7

Operadores aritméticos............................................................................7

Operadores de relación y lógicos.............................................................7

Operadores de incremento y decremento................................................8

Operadores para manejo de bits..............................................................8

Operadores de asignación y expresiones.................................................8

Precedencia y asociatividad de operadores.............................................9

Conversión de tipos.................................................................................10

4. Control de flujo......................................................................................................10

4.1. if-else.........................................................................................................11

Expresiones condicionales......................................................................11

4.2. else-if.........................................................................................................12

4.3. switch.........................................................................................................12

4.4. while..........................................................................................................13

4.5. for ..............................................................................................................13

4.6. do-while.....................................................................................................13

4.7. break y continue.........................................................................................14

5. Funciones...............................................................................................................14

6. Apuntadores...........................................................................................................16

7. Compilador cc........................................................................................................17

8. El preprocesador de C............................................................................................18

8.1. Unión de líneas..........................................................................................18

8.2. Definición y expansión de macros.............................................................18

8.3. Inclusión de archivos.................................................................................19

8.4. Compilación condicional...........................................................................19

8.5. Control de línea..........................................................................................20

8.6. Generación de errores................................................................................20

8.7. Pragmas......................................................................................................20

8.8. Directiva nula.............................................................................................20

8.9. Nombres predefinidos................................................................................21

9. Bibliografía.............................................................................................................21

Apéndice A Compilador XL C................................................................................21

USO:.................................................................................................................21

DESCRIPCIÓN:...............................................................................................22

OPCIONES:......................................................................................................22

1. Introducción

El lenguaje C fue hecho por Brian W. Kerninghan y Dennis M. Ritchie a mediados de los 70's, con el objeto de desarrollar el sistema operativo UNIX para la computadora PDP-11. Desde entonces a la fecha ha tenido una amplia aceptación dentro del área de la programación debido a su flexiblidad, tamaño y portabilidad.

Es un lenguaje de bajo-medio nivel, que permite el acceso al hardware de la computadora y a su vez el empleo del modelo de programación estructurada, de manera que se puede hacer uso eficiente de los recursos con los que cuenta un equipo de cómputo.

El presente curso tiene como objetivo hacer un estudio completo sobre el lenguaje, considerando su sintaxis, estructura y uso de sus instrucciones.

2. Estructura de un programa en C

Un programa en C, consta de varias secciones en donde se determinarán que variables y funciones tendrá el programa, así como la tarea que tendrá que realizar. Su estructura está determinada por las partes siguientes:

• Instrucciones para el compilador• Definición de estructuras• Definición de variables• Funciones• Programa principal

2.1. Instrucciones para el compilador

Las líneas que se escriben en esta sección indican al compilador la realización de diferentes tareas como: la definición de nombres, tomas de decisión durante la compilación, macros e inclusión de archivos entreotras.

Todas las líneas del preprocesador inician con el carácter '#'. Por ejemplo:

#include<stdio.h>#define PI 3.1416 /* Donde PI es el nombre de la etiquieta y su

valor es 3.1416 */

Donde todos los caracteres que se encuentren entre "/*" y "*/", son tomados como comentarios y no tienen efecto para la compilación.

1

2.2. Definición de estructuras

En esta área se definen todas las estructuras que requiera el programa. Donde una estructura es la colección de variables para la representación del problema que se está tratando. Por ejemplo:

struct esfera{float radio;float volumen;};

2.3. Definición de variables

Una vez creados los tipos y estructuras, se procede a la definición de las variables, que son etiquetas con las cuales se tiene acceso a localidades de memoria para el almacenamiento de información durante la ejecución del programa.

Un ejemplo definición de variable es:

struct esfera A;

2.4. Funciones

Las funciones son conjuntos de instrucciones encargadas de la realización de tareas específicas. . Su existencia permite la respresentación del problema en función del modelo de programación estructurada.

Una función que calcula el volumen de una esfera se presenta enseguida.

void volum(void){A.volumen= (4.0 / 3.0) * PI * A.radio * A.radio * A.radio;}

2.5. Programa principal

El programa principal contiene las instrucciones y llamadas a funciones que se ejecutan en primera instancia. Siempre se tiene el nombre de "main".

El programa principal para el cálculo del volumen de una esfera puede ser el siguiente:

void main(void){

2

printf("\n\t Deme el radio de la esfera: ");scanf("%f",&A.radio);volum();printf("\n\t El volumen de la esfera con radio %f, es:

%f\n",A.radio,\ A.volumen); }

Observación: Es de suma utilidad usar tabuladores para la claridad del programa.

3. Tipos y operadores

3.1. Tipos

Las variables usadas en lenguaje C, pueden ser de varios tipos. Éstos, definirán el tamaño en bytes de cada variable. Los tipos que existentes son:

void Sin valorchar Caractershort Entero cortoint Enterolong Entero largofloat Flotantedouble Flotante de doble precisiónsigned Usa signounsigned Sin signo

El tipo void permite declarar funciones que no regresan valores y también para la declaración de apuntadores genéricos, es decir capaces de apuntar a cualquier tipo de variable.

La declaración de una variable emplea la sintáxis siguiente:

Tipo nombre_variable, nombre_variable, nombre_variable = constante;

En la declaración de variables se pueden definir una o más variables del mismo tipo en el mismo renglón, por ejemplo:

int numero, altura, profundidad;

Todas las líneas terminan con punto y coma (;). También se les puede asignar un valor inicial en el momento de la definición. Por ejemplo:

char letra_inicial = 'J';float elevacion = 2.43, x = 4.0;

Es importante mencionar que en el nombre de la variable se pueden emplear letras minúsculas, mayúsculas y el carácter '_' (línea de subrayado).

3

También se pueden definir arreglos unidimensionales y multidimensionales.

char nombre[30];unsigned char meses[2][12] =

{{31,28,30,31,30,31,30,31,31,30,31,30,31},{31,28,30,31,30,31,30,31,31,30,31,30,31}};

Las cadenas de caracteres se representan usando doble comilla, por ejemplo: "Es un día soleado", mientras que para un solo carácter se emplea la comilla, por ejemplo: 'a', 'b', 'z'. Las cadenas de caracteres en C, se terminan con el carácter especial '\0'. Otros caracteres especiales (también se les denomina secuencias de escape) son:

'\a' carácter de alarma'\b' retroceso'\f' avance de hoja'\n' nueva línea'\r' regreso de carro'\t' tabulador horizontal'\v' tabulador vertical'\\' diagonal invertida'\?' interrogación'\'' apóstrofo'\"' comillas'\ooo' número octal'\xhh' número hexadecimal'\0' carácter nulo

3.2. Estructuras

Una estructura es una colección de variables que se agrupan bajo un una sola referencia. La sintáxis general es:

struct nombre_estructura {elemento 1;elemento 2;...} variable_struct;

Donde la palabra reservada es "struct", el nombre del conjunto de variables se pone en "nombre_estructura", se abre una llave y enseguida se ponen las variables (cada elemento, usa la declaración de variables usada en el punto 3.1); al terminar de definir todos los elementos, se cierra la estructura con una llave. Hasta aquí, sólo se ha definido la estructura, sin embargo no

4

hay ninguna instancia (creación física) de la misma. Por tanto se hace necesario definir una variable cuyo tipo sea la estructura predefinida.

Usemos una estructura ya vista:

struct esfera{float radio;float volumen;};

struct esfera A;

Para accesar un campo de la estructura, se usa el nombre de la variable, seguida por un punto y después por el nombre del campo que se va a usar.

A.radio = 4.0;A.volumen = 4332.8998;

3.3. Uniones

Existe la posibilidad de usar de manera más eficiente la memoria de la computadora, esto se puede lograr empleando la definición de unión. La sintáxis es similar a la de la estructura.

union nombre_de_la_union {elemento 1;elemento 2;...} variable_union;

La diferencia estriba, en que, en este caso las variables se solapan. Por ejemplo:

union libros {char inicial;int num;} lib;

En este caso la unión emplea 2 bytes para la variable "num", y uno de esos bytes se emplea para la variable "inicial", por tanto, no hay 3 bytes en la definición, sino sólo dos.

3.4. Enumeraciones

La enumeración es una lista de valores posibles que puede tomar una variable. Por ejemplo:

enum ciudades México, Zacatecas, Guanajuato, Nayarit;

5

enum ciudades ciud;

Donde "ciud" sólo puede tomar cualquiera de los nombre dados en la declaración previa.

3.5. Modificadores de almacenamiento

Con los modificadores de almacenamiento se altera la forma en que se crea elalmacenamiento. Los modificadores son: extern, auto, register, const, volatiley static.

Modificador "extern"

Se emplea cuando un programa se encuentra dividido en varios archivos. Como las variables sólo se definen una vez, se hace necesario hacer referencia de ellas en los archivos que así lo requieran.

La sintáxis es:

extern tipo la_variable; /* Se debe indicar también el tipo de la variable o función */

Se dice que este tipo de variables tienen "liga externa".

Modificador "auto"

Todas las variables son "auto" por omisión, y son objetos locales a un bloque y al salir de éste son descartadas.

Modificador "register"

Los objetos declarados como "register" son automáticos y sus valores se almacenan en registros del microprocesador de la computadora.

Modificador "const"

Las variables de tipo "const" no pueden cambiarse por el programa durante la ejecución.

Una variable "const" recibirá su valor desde una inicialización explícita o por medio de alguna dependencia del hardware.

Modificador "volatile"

6

Las variables modificadas por "volatile" indican que éstas pueden ser modificadas de forma no explícita por el programa. Por ejemplo: se podría guardar la hora exacta en una variable y que la asignación la hiciera la rutina de atención a la interrupción del reloj.

Modificador "static"

Se usa para mantener una variable local en existencia durante la ejecución de un programa, de manera que no se tiene que crear y destruir cada vez que se encuentra a la rutina donde está declarada.

3.6 Operadores

Los tipos de operadores que existen son: aritméticos, de relación y lógicos, de incremento y decremento, para manejo de bits, de asignación y expresiones, expresiones condicionales.

Operadores aritméticos

Los operadores aritméticos binarios son '+', '-', '*', '/' y '%'. Su significado se muestra a continaución:

+ Suma de dos operandos- Resta entre dos operandos* Multiplicación de dos operandos/ División entre dos operandos% Módulo entre dos operandos. Da el residuo de la división

resultante entre el operando1 (numerador) y el operando2(denominador).

La sistáxis es:

operando1 operador operando2

La división entera truca cualquier parte fraccionaria.

Operadores de relación y lógicos

Los operadores de relación son: '>', ">=", '<', "<=", "==" y "!=".

> Mayor que>= Mayor o igual< Menor que<= Menor o igual

7

== Idéntico!= Diferente a

Los operadores lógicos son: "&&" y "||"

&& Y|| Ó

El resultado del uso de estos operadores puede ser falso o verdadero. Se considera como falso el valor de cero, y como verdadero, todo aquel valor diferente de cero.

La sistáxis es:

operando1 operador operando2

Operadores de incremento y decremento

Los operadores de incremento y decremento, añaden o quitan una unidad al operando que están afectando, respectivamente. De tal manera que:

++i; es equivalente a: i=i+1; y después se emplea el valor de ii++; es equivalente a: se usa el valor de i, enseguida se incrementa--i; significa: i=i-1; y después se usa el valor de ii--; significa: se usa el valor de i, enseguida se decrementa en uno

Como nota importante se debe poner énfasis en la precedencia de cada expresión.

Operadores para manejo de bits

Los operadores para manejo de bits son:

& AND de bits. Ejemplo: 0x0F & 0xFE => 0x0E| OR inclusivo de bits. Ejemplo: 0x1E | 0x01 => 0x1F^ OR exlusivo de bits. Ejemplo: 0xF0 ^ 0x02 => 0xF2<< corrimiento a la izquierda. Ejemplo 0x02 << 2 => 0x08>> corrieminto a la derecha. Ejemplo 0x04 >> 2 => 0x01~ complemento a uno (unario). Ejemplo ~0xF0 => 0x0F

Operadores de asignación y expresiones

El operador de asignación '=', se usa como se muestra enseguida:

x = 5 + 4;

8

Y puede intrepetarse como: el resultado de sumar 5 + 4 se asigna a la variable x.

También se puede usar para la suma de dos variables y que el resultado quede en una tercera. Por ejemplo:

x = y / z;

Supongamos,

x = 4;

Cuando se tiene x = x + 5, primero se suma a x el 5 que implica que se obtenga el número 9, y después se asigna a x. Por tanto el valor final de x es idéntico a 9 (x == 9).

Otra forma de expresar lo anterior es: x += 5 que es equivalente a x = x + 5. De esta manera "+=" es un operador de asignación.

En general se puede decir que:

expresión1 op= expresión2

equivale a

expresión1 = (expresión1) op (expresión2)

Precedencia y asociatividad de operadores

La precedencia y asociatividad de los operadores se muestra en la tabla siguiente.

Nota: Los operadores que están en la misma línea tienen la misma precedencia; los renglones están en orden de precendencia decreciente, por ejemplo, '*', '/', y '%' todos tienen la misma precedencia, la cual es más alta que la de '+' y '-' binarios. El "operador" ( ) se refiere a la llamada a una función.

Operadores Asociatividad

() [] izquierda a derecha! ~ ++ -- + - * & (tipo) sizeof derecha a izquierda* / % izquierda a derecha+ - izquierda a derecha<< >> izquierda a derecha< <= > >= izquierda a derecha== != izquierda a derecha

9

& izquierda a derecha^ izquierda a derecha| izquierda a derecha&& izquierda a derecha|| izquierda a derecha?: derecha a izquierda= += -= *= /= %= &= ^= |= <<= >>= derecha a izquierda, izquierda a derecha

Conversión de tipos

Cuando un operador tiene operandos de tipos diferentes, éstos se convierten a un tipo común de acuerdo con un reducido número de reglas. Estas reglas son:

• Si cualquier operando es long double, conviértase el otro a long double.

• De otra manera, si cualquier operando es double, conviértase el otro a double.

• De otra manera, si cualquier operando es float, conviértase el otro a float.

• De otra manera, conviértase char y short a int.

• Después, si cualquier operando es long, conviértase el otro a long.

También se puede convertir de un tipo a otro usando el operador "cast". Que consiste en anteponer a la variable o función el tipo que se desea. Para ello se usan paréntesis. Por ejemplo:

char caracter;int entero;

entero = (int) caracter;

4. Control de flujo

Mediante las proposiciones de control de flujo se indica el orden en que se realizará el proceso. Las expresiones vistas anteriormente, se vuelven proposiciones cuando se terminan con punto y coma ';'.

10

Las llaves '{', '}' se emplean para agrupar declaraciones y proposiciones dentro de una proposición compuesta o bloque.

Para el control del programa existen las proposiciones siguientes: if-else,else-if, switch, while, for y do-while.

4.1. if-else

La proposición if-else se usa para expresar decisiones. La sintáxis es:

if(expresión)proposición1;

elseproposición2;

Si la expresión es verdadera, se ejecuta la proposición1, de lo contrario se realiza la proposición2.

No es indispensable el else, es decir, se puede tener una proposición de la forma:

if (expresión)proposición1;

Se debe hacer notar que la proposición1 o la proposición2, pueden ser proposiciones compuestas o bloques. Por ejemplo:

if( x == 1 ){y = r*j;printf("El resultado de y es: %u", y);}

else{printf("Se tiene un valor incorrecto de x");printf("Vuelva a repetir los pasos 1 al 8");}

Expresiones condicionales

Otra forma de escribir la proposición if-else es usando una expresión condicional.

expresión1 ? expresión2 : expresión 3

Que es equivalente a:

if( expresión1 )expresión2;

elseexpresión3;

11

Nota: Si las expresiones 2 y 3 son compuestas, cada proposición debe estar separada por coma ','. Por ejemplo:

(A.radio > 4) ?printf("\n Funciona\n"), printf("A ver??\n"): printf("\n Es más pequeño");

4.2. else-if

Con esta expresión se complementa la expresión vista en el punto anterior. Su sintáxis es:

if( expresión )proposición;

else if( expresión )proposición;

else if( expresión )proposición;

else if( expresión )proposición;

elseproposición;

Mediante esta expresión se puede seleccionar una condición muy específica dentro de un programa, es decir, que para llegar a ella se haya tenido la necesidad del cumplimiento de otras condiciones.

4.3. switch

La proposición switch, permite la decisión múltiple que prueba si una expresión coincide con uno de los valores constantes enteros que se hayan definido previamente.

Su sintáxis es:

switch( expresión ) {case exp-const: proposicionesbreak;

case exp-const: proposicionesbreak;

case exp-const: case exp-const: proposicionesbreak;

default: proposiciones}

12

Se compara la "expresión" con cada una de las opciones "exp-const", y en el momento de encontrar una constate idéntica se ejecutan las proposiciones correspondientes a ese caso. Al terminar de realizar las proposiciones del caso, se debe usar la palabra reservada "break" para que vaya al final del switch.

Si ninguno de los casos cumplen con la expresión, se puede definir un caso por omisión, que también puede tener proposiciones.

En todos los casos pueden ser proposiciones simples o compuestas. En las compuestas se usan llaves para definir el bloque.

4.4. while

La proposición "while" permite la ejecución de una proposición simple o compuesta, mientras la "expresión" sea verdadera. Su sintáxis es:

while( expresión )proposición

Por ejemplo,

while( (c = getchar()) == 's' || c == 'S' )printf("\nDesea salir del programa?");

while( (c = getchar()) == 's' || c == 'S' ){printf("\nDesea salir del programa?");++i;printf("\nNúmero de veces que se ha negado a salir: %u",i);}

4.5. for

La proposición "for" requiere tres expresiones como argumento. Las expresión1 y la expresión3 comúnmente se emplean para asignaciones, mientras que la expresión2 es la condición que se debe cumplir para que el ciclo "for" se siga ejecutando.

La sintáxis es:

for(expresión1; expresión2; expresión3)proposición

Ejemplo:

for(i=0; i <= 500; ++i)printf("\nEl número par # %i, es: %i", (2*i), i);

13

4.6. do-while

La proposición "do-while" es similar a la proposición "while", se ejecuta el ciclo mientras se cumpla la condición dada en "expresión".

La diferencia estriba en que en el "do-while" siempre se evalúa al menos una vez su "proposición", mientras que en el "while" si no se cumple la "expresión" no entra al ciclo.

Sintáxis:

doproposición

while( expresión );

Ejemplo:

i=0;do

{printf("\nEl número par # %i, es: %i", (2*i), i);++i;}

while( i < 500 );

4.7. break y continue

Cuando se quiere abandonar un ciclo en forma prematura debido a que ciertas condiciones ya se cumplieron, se puede usar la proposición "break". Ésta sirve par las proposiciones "for", "while" y "do-while".

También se tiene otra proposición relacionada, y esta es el "continue"; su función es la de ocasionar la próxima iteración del ciclo.

Ejemplos:

for(h=1; h <= 1000; ++h){if( h%5 == 0 )

continue;printf("Número que no es múltiplo de 5: %i", h);}

while(1){

14

if( getchar() == '$' )break;

printf("\nNo puedo parar, hasta que presione \'$\'");}

5. Funciones

Las funciones son fragmentos de un programa que realizan tareas específicas.Esto permite dar claridad al programa y facilita su mantenimiento.

La sintáxis de las funciones es:

tipo nombre_función (tipo argumento){expresión1:expresión2;expresión3;..}

El "tipo" determina la clase de variable que regresará la función. Los tipos definidos para las variables en la sección 3.1 son aplicables a las funciones.

El "nombre_función" deberá ser único en todo el programa y no se podrán usar ni palabras reservadas del lenguaje, ni funciones ya preestablecidas en las librerías del compilador.

A una función se le pueden pasar argumentos, con el fin de que con esos valores se realicen cálculos específicos. Los argumentos se separan por comas. Por ejemplo:

void integra(float x, float dx, float lim_inf, float lim_sup){..}

El paso de argumentos entre funciones puede ser por valor o por dirección.

Finalmente, las funciones pueden regresar un resultado, es decir, que al finalizar la ejecución de la función se produjo un dato que se va a usar posteriormente dentro del programa y por ello es necesario que sea dado como respuesta. Para realizar esto se emplea la palabra reservada "return". Por ejemplo:

float cuadrado(float x){float y;y = x * x;return(y);}

15

void main(void){float xx, yy, rr;...rr = sqrt( (cuadrado(xx) + cuadrado(yy)) );printf("\nEl valor de la hipotenusa es: %f", rr);}

La función "main", es la rutina principal de un programa en C. A partir de ella se llaman al resto de las funciones.

Nota: Una función puede llamar a otra función. En lenguaje C existe larecursión.

6. Apuntadores

Una variable puede ser usada por su nombre o por la dirección donde está el contenido de la variable. ¿Cómo se pueden usar las direcciones de las variables? Bueno, mediante apuntadores.

Sintáxis:

tipo *nombre_variable;

La diferencia entre una declaración de una variable normal y un apuntador es el uso del asterisco.

Para que quede claro que es un apuntador se presenta la siguiente analogía:

Imagínese un libro, éste, tiene hojas y cada una de ellas está numerada. Ahora, supongamos que tiene un índice al final del mismo y se desea hallar información relacionada con el ajedrez. Al encontrar la palabra ajedrez en el índice se tiene el número de página; en ese momento se cae en la cuenta de la necesidad deuna hoja para escribir esa información; enseguida se toma la hoja y se anota la página. Acto seguido se va a la página marcada con el número encontrado y se lee la información. En este caso el apuntador será la hoja con el número escrito en ella.

Bien, regresando al lenguaje C, cuando se declara "nombre_variable" se indica que se tiene necesidad de un lugar donde se pueda escribir y que éste sea de tipo determinado (que en el ejemplo precedente pudiera ser un pizarrón, una hoja, la pared, etc.). Sin embargo el objeto no está disponible aún, por ello se requiere de una instrucción adicional que indique la acción de tomar la hoja y tenerla dispuesta para su uso.

16

Un ejemplo concreto sería:

#include <stdlib.h>

char *caracter;

void main(void){.caracter = (char *)malloc(sizof(char));.*caracter = 'O';

}

La etiqueta "caracter" es el lugar en el que se puede escribir la dirección donde está la información que requerimos, (char *) indica el tipo de variable que va a ser, es decir apuntador a char (en nuestro ejemplo del libro: tipo hoja que tendrá números de página),mientras que "*caracter" apunta directamente al contenido de la variable (la hoja con el número de página).

Para tomar un espacio de memoria de la computadora que sirva para fines de almacenar direcciones se debe incluir la cabecera o "header" stdlib.h, después se declara la variable y luego se asigna memoria mediante la función "malloc".

La función malloc asigna memoria y usa como argumento el número de bytes que se quieran usar. Por eso se pone sizeof(char), donde la función sizeof, regresa el tamaño del tipo que se pone como argumento. Finalmente, para que exista consistencia entre tipos, se usa el operador cast (char *) para indicar que la variable contendrá direcciones para encontrar un char.

Si se ha definido una variable de manera "normal" (que no se haya definido como apuntador), también se puede usar su dirección. Para ello se antepone el caracter '&' a la variable usada.

Por ejemplo:

float x, *y;

void main(void){x = 4.3;y = &x;printf("El valor de y es: %f", *y);}

El resultado del printf será que y = 4.3;

17

7. Compilador cc

El compilador "cc" se encuentra en todos las computadoras que tienen sistema operativo UNIX. Por tanto es importante mencionar su existencia y su uso.

Para compilar un programa en UNIX se usa

$ cc nombre_archivo

El archivo "nombre_archivo" se denomina archivo fuente. La salida de esta instrucción va a ser un archivo ejecutable, que por defecto tiene el nombre "a.out".

Si se desea cambiar el nombre del archivo ejecutable se puede usar la siguiente instrucción:

$ cc nombre_archivo -o nombre_ejecutable

Este compilador puede procesar archivos fuente en ensamblador y archivos objeto.

Dependiendo de las necesidades de cada usuario podrá usar aquellas opciones que le sean más útiles, por ejemplo, optimización en tiempo, optimización en tamaño, el tipo de arquitectura que se está usando, etc.

En el apéndice A se presenta el manual del compilador.

8. El preprocesador de C

8.1. Unión de líneas

Las líneas que terminan con el carácter diagonal invertida '/' se empalman eliminando la diagonal inversa y el carácter nueva línea.

8.2. Definición y expansión de macros

Mediante una macro se pueden definir etiquetas que van ser sustituidas en tiempo de compilación dentro del programa.

18

La sintáxis es como sigue:

# define identificador secuencia-de-tokens

# define identificador (lista-de-identificadores) secuencia-de-tokens

# undef identificador

Esta última definición hace que el preprocesador olvide la definición del identificador.

Ejemplos:

#define TABSIZE 100#define ABSDIFF(a,b) ((a)>(b) ? (a)-(b) : (b)-(a))

En el caso del preprocesador las expresiones no terminan con punto y coma.

8.3. Inclusión de archivos

Mediante estas directivas un archivo completo se incluye en el programa actual.

# include <nombre-de-archivo> /* Pone el archivo según la rutaindicada por el sistema */

# include "nombre-de-archivo" /* Busca el archivo en el directorio actual, y si no lo encuentra

busca en la ruta indicada por el sistema */

# include secuencia-de-tokens /* Expande la secuencia de tokens como texto normal */

8.4. Compilación condicional

Estas directivas permiten tomar acciones al preprocesador en función de condiciones iniciales de ambiente.

preprocesador-condicional:línea-if texto partes-elif parte-else #endif

opt

línea-if:

# if expresión-constante# ifdef identificador# ifndef identificador

partes-elif:

19

línea-elif textopartes-elif (opt)

línea-elif:

# elif expresión-constanteparte-else:

# línea-else texto

línea-else:

#else

Ejemplo:

#define NUMERO 2

#ifdef NUMERO == 1#define VAR_TOKEN 100#define conver(x) (x + 5)

#else#define VAR_TOKEN 200#define conver(x) (x +6)

#endif

8.5. Control de línea

Ocasiona que el compilador suponga que el número de líndea de la siguiente línea fuente está dado por la constante entera decimal y que el archivo actual de entrada está nombrado por el identificador, todo esto par propósito de diagnóstico de errores.

# line constante "nombre-de-archivo"# line constante

8.6. Generación de errores

Ocasiona que el preprocesador escriba un mansaje de diagnóstico que incluyela "secuencia de tokens".

# error secuencia-de-tokens (opt)

8.7. Pragmas

20

Realiza acciones dependiendo de la implantación.

# pragma secuencia-de-tokens (opt)

8.8. Directiva nula

Una línea del preprocesador de la forma

#

no tiene efecto.

8.9. Nombres predefinidos

_ _LINE_ _ Constante decimal que contiene el número de línea actual._ _FILE_ _ Cadena literal que contiene el nombre del archivo que se está compilando._ _DATE_ _ Cadena literal que contiene la fecha de compilación, en la forma "Mmm dd aaaa"._ _TIME_ _ Cadena literal que contiene la hora de la compilación, en la forma "hh:mm:ss"._ _STDC_ _ La constante 1. Este identificador será definido como 1sólo en implantaciones que

conforman el estándar.

9. Bibliografía

Kernighan, Brian W.Ritchie, Dennis M.El lenguaje de programación CPrentice Hall.1991. Segunda edición

Barkakati, NabaThe Waite Group’s Turbo C++ BibleSAMS.1990.

Apéndice A Compilador XL C

21

Compilador XL C Versión 1.3.0.0

USO:

cc [ opcion | archivo ]

DESCRIPCIÓN:

Estos comandos también procesan archivos fuente en ensamblador y archivos objeto. A menos de que se especifique la opción -c, estos comandos llaman al editor de liga para producir un archivo objeto sencillo. Los archivos de entrada pueden ser de la siguiente manera:

1. nombre del archivo con extensión .c: archivo fuente en C2. nombre del archivo con extensión .i: archivo preprocesado fuente en C3. nombre del archivo con extensión .o: archivo objeto para el comando ld4. nombre del archivo con extensión .s: archivo fuente en ensamblador

OPCIONES:Las opciones pueden ser una o más de las siguientes:

1.Opciones Bandera:

-# Despliega información adicional sobre el progreso de compilación sin invocar nada.

-B<prefijo> Construye nombres de programas para el editor de ligas, ensamblador y compilador. El <prefijo> es añadido al inicio del nombre estándar de los nombres de programas.

-c Compila solamente; no llama al comando ld.-C Escribe comentarios a la salida mientras se realiza el preprocesamiento usado con

-E y -P.-D<nombre>[=<def>]

Define <nombre> como en la directiva #define. Si <def> no se especifica, se asume como 1.

-E Preprocesa pero no compila; las salidas van a la consola.-F<x>[:<stanza>]

Usa una configuración alterna del archivo <x> dejando opcional <stanza>. Si no se especifica el <stanza>, se asume como xlc.

-g Produce información de depuración.-I<dir> Busca en el directorio <dir> archivos incluidos que no comienzen con una ruta

absoluta.

22

-l<key> Busca el archivo de librería específico, donde <key> selecciona el archivo lib<key>.a.

-L<dir> Busca en el directorio <dir> archivos especificados por -l<key>.-M Crea un archivo de salida compatible para la inclusión en un archivo de

descripción para el comando make en UNIX.-o<nombre> Cuando se usa con -C, nombra el archivo <nombre>.o, de otra forma, nombra el

archivo ejecutable <nombre> en vez de a.out.-O Optimiza el código generado.-O2 Nivel equivalente de optimización como -O en la versión anterior.-O3 Realiza la optimización en el uso de memoria y tiempo de compilación además de

aquellos ejecutados con -O2. Las optimizaciones específicas de -O3 tienen el potencial para alterar las semánticas del programa del usuario.

-p Genera un código simple de soporte.-pg Genera un código más extenso de soporte que -p.-P Preprocesado pero no compila; su salida genera un archivo con extensión .i.-Q<x> Enlínea todas las funciones apropiadas donde x puede ser una de las siguientes:

! No enlínea función alguna.=<lc> Enlínea si el número de la sentencia fuente en la función es menor que el especificado en <lc>.-<nm> Función no enlineada listada por nombres en <nm>.+<nm>Enlínea la función listada por nombres en <nm>.

-S Produce un archivo con extensión .s para cualquier archivo fuente procesado por el compilador.

-t<x> Utiliza el prefijo de la opción -B al programa <x> especificado, donde x puede ser uno o más de las siguientes:p = preprocesadorc = compiladora = ensambladorl = editor de ligas.

-U<nombre> Nombre indefinido como en la directiva #undef.-v Despliega información adicional en el progreso de compilación.-w Suprime información, nivel del lenguaje y mensajes de advertencia.-y<x> Especifica el tiempo de compilación de las expresiones de punto flotante

constantes, donde <x> puede ser una de las siguientes:n = redondeando al valor más cercanom = acercándose a menos infinitop = acercándose a más infinitoz = redondeando a cero.

2. Otras Opciones:

Otras opciones se especifican como sigue:

-q<opción>

23

donde <opción> es un switch on/off de manera que, si x es la opción, -qx cambia la opción a on, y -qnox cambia la la opción a off. Por ejemplo, -qsource le dice al compilador que produzca un listado fuente, y -qnosource le dice al compilador que no produzca un listado fuente.

Las opciones son las siguientes:

ansialias Especifica el tipo de base de denominación que será usado durante la optimización.

attr Produce un listado de atributos (solamente los referenciados).compact Reduce el tamaño del código donde sea posible, dependiendo de la velocidad de

ejecución. El tamaño del código es reducido por optimizaciones inhibidas que expanden el código entre líneas.

cpluscmt Permite a "//" introducir un comentario que se mantiene hasta el final de la linea fuente actual, como en C++.

dbxextra Genera una tabla de información de símbolos para variables no referenciadas. Por defecto dicha información no se genera a menos que se reduzca la compilación ejecutable con la opción -g.

extchk Realiza externamente el chequeo de los nombres y funciones.idirfirs Especifica el orden de búsqueda para archivos incluidos con la directiva #include

"nombre_archivo". Usar -qidirfirst con la opción -Idirectorio. Si la opción -qidirfirst es especificada, los directorios especifica dos por la opción son buscados antes del directorio donde se encuentra el archivo actual se encuentra.

inlglue Genera rápidamente la liga externa enlineando el código necesario con llamadas por un apuntador de función y llamadas a procedimientos externos.

list Produce un listado objeto.listopt Imprime marcas de todas las opciones en el listado.mbcs Los strings literales y los comentarios pueden

contener caracteres MBCS.noprint Direcciona el listado a /dev/null.nostdinc Especifica que archivos estan incluidos con las directivas #include

"nombre_archivo" y #include <nombre_arch> Si -qnostdinc es especificado, el directorio/usr/include no es buscado.

ro No pone las literales de la cadena en el área de sólo lecturaphsinfo Despliega información de fase en la pantalla.ro Establece las cadenas literales en el área de sólo lectura. Esta opción está por

defecto para xlc.roconst Establece identificadores estáticos externos y globales que son constantes

calificadas en el área de sólo lectura.source Produce el listado fuente.srcmsg Especifica que las líneas fuente a ser desplegadas con el mensaje con apuntadores

a la posición de la columna del error.statsym Agrega nombres no externos definidos por el usuario que tienen como clase

almacenamiento estático al nombre de la lista.

24

strict Válido únicamente en -O3. Esta opción cambia a off la optimización agresiva que tiene el potencial para alterar las semánticas del programa del usuario. Esta opción también establece -qfloat=nofltint:norsqrt.

tocdata Establece los datos escalares externos de una palabrao menos en la tabla de contenidos (TOC). Si se activa esta opción, la dirección del dato escalar externo se establece en el TOC. Esto requiere una llamada extra de la dirección antes de accesar el dato.

xcall Genera el código de rutinas estáticas sin una unidad de compilación como si fueran rutinas externas.

xref Produce un listado de referencia cruzada (sólo nombres referenciados).

-q<opción>=<subopción>-q<opción>=<subopción1>:<subopción2>:...:<subopciónN>

donde <opción> se le asigna un valor de subopción específica o una lista de valores de subopción como sigue:

align=<algnopt>

Especificar una de las siguientes tres reglas de alineamiento:- arquitectura POWER (align=power, default)- alineación de dos bytes (align=twobyte)- alineación de un byte (align=packed)arch=<opción>

Especifica la arquitectura donde el programa ejecutable correrá. Las opciones disponibles son:

com Produce un objeto que contiene instrucciones que correrán en toda plataforma de hardware POWER y PowerPC.

pwr Produce un objeto que contiene instrucciones que correrán en la plataforma de hardware POWER.

pwr2 Produce un objeto que contiene instrucciones que correrán en la plataforma de hardware POWER2

pwrx Lo mismo que pwr2.ppc Produce un objeto que contiene instrucciones que correrán en cualquier plataforma

de harware de 32-bits y PowerPC. Si la opción -qarch es especificada sin el -qtune= <opción>, el compilador usará -qtune=pwr.

attr=full Produce una lista de atributos (todos los nombres, referenciados o no).chars=signed El tipo de dato char será señalado.datalocal=<nombre1>:<nombre2>:

Especifica qué datos son locales. Si no hay nombres especificados, todos se asumirán como locales.

dataimported=<nombre1>:<nombre2>:

25

Especifica qué datos son importados. Si no hay nombres especificados, todos se asumirán como importados. Esto esta por default.

enum=<enumopt>Especifica si los tipos enumerados de tamaño mínimo serán producidos o no.<enumopt> puede

ser small o int. Small denota que uno, dos o cuatro bytes de almacenamiento serán establecidos para enum variables basadas en el rango de las constantes enum. Int esta por default, y causa que las enum variables sean tratadas como si fueran de tipo señalado int.

flag=<sev1>:<sev2>Especifica el nivel de severidad de los diagnósticos que serán reportados en listados, <sev1>, y en

la pantalla, <sev2>.

float=<opt1>:<opt2>:...:<optN>

Las opciones disponibles son:

hssngl Redondea las expresiones de precisión sencilla sólo cuando los resultados son almacenados en las localidades de memoria REAL*4.

nans Detecta la conversión de NaNS de precisión sencilla con precisión doble llamando a chequeo.

hsflt Nunca redondea expresiones de precisión sencilla, y no realiza el chequeo de rango de punto flotante para integrar conversiones.

nomaf Suprime la generación de instrucciones suma-multiplicación.nofold Suprime la evaluación de tiempo-compilación de las expresiones constantes de

punto flotante.rrm Especifica el modo de tiempo-corrida. Compilar con esta opción si este modo se

redondea a menos infinito, a más infinito o no se conoce.rsqrt Especifica si la división del resultado de una raiz cuadrada puede ser reemplazado

con un multiplicador por el recíproco de la raiz cuadrada. Por omisión a -O2: -qfloat=norsqrt. Por omisión a -O3: -qfloat=rsqrt.

fltint Especifica si el rango checado del punto flotante para integrar conversiones esta hecho. Por omisión a -O2: -qfloat=nofltint. Por omisión a -O3: -qfloat=fltint.

flttrap=<opt1>:<opt2>:...:<optN> Genera instrucciones para detectar el punto flotante.Las opciones disponibles son: overflow, underflow, zerodivide, invalid, inexact, enable, imprecise.

halt=<sev> Detiene el compilador después de la primera fase si la severidad de los errores detectados es igual o equivale a <sev>.

initauto=<hh> Inicializa el almacenamiento automático a <hh>. <hh> es un valor hexadecimal. Esto genera un código extra y sólo deberá ser usado para la determicación de error.

isolated_call=<nombre1>:<nombre2>: Especifica que los llamados a las funciones listadas no tienen efectos secundarios. <nombre1> y <nombre2> son nombres de función. El usuario especificará los nombres de función como sea necesario.

26

langlvl=<langlvl> Especifica el nivel del lenguaje que será utilizado durante la compilación. <langlvl> puede ser ansi, saal2, saa, o extendido.

maxmem=<num>Limita la cantidad de memoria utilizado por las optimizaciones de espacio intensivas a <num>. <num> esta especificado en kilobytes.

pgmsize=<p> Establece el tamaño de la tabla de inicio que será usada por el compilador. <p> puede ser s, para pequeño; o l para largo.

proclocal=<nombre1>:<nombre2>: ...Especifica qué funciones son locales. Si no se especifican los nombres, todas las funciones invocadas se asumen que estan definidas dentro del archivo en uso. Las últimas especificaciones explícitas para una función toman precedencia.

procimported=<nombre1>:<nombre2>: ...Especifica qué funciones son importadas. Si los nombres de archivo no son especificados, todas las funciones invocadas se asumen que estan definidas fuera del archivo en uso. Las últimas especificaciones explicitas para una función toman precedencia.

procunknown=<nombre1>:<nombre2>: ...Especifica qué funciones no se conocen como locales o importadas. Si no son especificados los nombres de los archivos, todas las llamadas a funciones se asumen como desconocidas. Este es el default cuando el usuario no especifica opciones. Las últimas especificaciones explicitas para una función toman precedencia.

spill=<tamaño>Especifica el tamaño del area de localización del registro.

tune=<opción>Especifica el sistema de arquitectura para la que el programa ejecutable es óptimo. Las opciones disponibles son:

601 Produce un objeto optimizado para todos los procesadores PowerPC601 .pwr Produce un objeto optimizado para la plataforma de hardware POWER.pwr2 Produce un objeto optimizado para la plataforma de hardware POWER2.pwrx Lo mismo que pwr2.xref=full Produce un listado de referencia cruzada (todos los nombres referenciados o no).

27