introducción al c bajo unix - msc. jaime soto (ing ... · pdf fileintroducción...

43

Upload: dangthu

Post on 09-Feb-2018

213 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX

Hernando Silva VarelaEscuela Universitaria de Informática

Universidad de Valladolid campus Segovia

[email protected]

25 de noviembre de 2002

HSV - Escuela Universitaria de Informática. UVA campus Segovia

Page 2: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Compilación de un programa

Tema 1: Compilación de un programa

Figura 1: Etapas de compilación de un programa en C

Orden de compilación (en línea):

cc �chero fuente.c

cc -Aa -o �chero ejecutable �chero fuente.c

cc -ansi -o �chero ejecutable �chero fuente.c

HSV - Escuela Universitaria de Informática. UVA campus Segovia 1

Page 3: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Compilación de un programa

Etapas de compilación:

Preproceso Es el proceso en el cual se interpretan y ex-panden directivas, se reemplazan constantes, se eliminancomentarios, etc. Por ejemplo, para ver la salida "pre-procesada"en un �chero se puede usar

cc -E �chero fuente.c >salida.txt

Compilación Estas etapa convierte un �chero fuente en Cen un �chero objeto en lenguaje máquina. Para preprocesary compilar un �chero, generando un �chero objeto singenerar ejecutable, se puede usar la orden

cc -c �chero fuente.c

Enlace En esta etapa se enlazan los �cheros objeto delusuario con los �cheros objeto del sistema con el �n degenerar el �chero ejecutable �nal. Para enlazar un �cheroobjeto y generar un �chero ejecutable se puede usar

cc �chero fuente.o -o �chero ejecutable

NOTA: El enlazador consulta por omisión (default) las bib-liotecas estándar de Entrada/Salida. Para usar funcionesde otras bibliotecas hay que indicarlo explícitamente us-ando parámetros de compilación tales como -lm o -lX11

HSV - Escuela Universitaria de Informática. UVA campus Segovia 2

Page 4: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Generalidades del lenguaje C

Generalidades del lenguaje C

El C es un lenguaje de programación de propósito general.

C es un lenguaje estructurado que permite utilizar lasestructuras básicas: secuencia, selección e iteración.

C es un lenguaje de nivel medio que permite accedera recursos de bajo nivel en el sistema al combinar lascaracterísticas de los lenguajes ensamblador y los lenguajesde alto nivel.

El lenguaje C es fácilmente transportable que se puedecompilar en casi cualquier máquina con mínimas o nulasmodi�caciones.

C es un lenguaje modular en el que el programa puedeescribirse en �chero separados que luego se compilan yenlazan para producir un �chero ejecutable único.

HSV - Escuela Universitaria de Informática. UVA campus Segovia 3

Page 5: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Estructura de un programa en C

Estructura de un programa en C

La estructura de un programa en lenguaje C está formadapor los siguientes elementos:

Bloque de declaración de �cheros de cabecera y otrasdirectivas. Debe declararse un �chero de cabecera porcada biblioteca a utilizar.

Bloque de declaración de variables globales y de�niciónde funciones del programa.

La función main() de aparición obligatoria.

EJEMPLO:

/* Bloque de declaración de ficheros

de cabecera y otras directivas */

#include <stdio.h>

/* Bloque de declaración de variables globales y

definición de funciones del programa */

int a;

/* Función main */

main() {

printf("¾Cómo están usteeedeeeesss?\n");

}

HSV - Escuela Universitaria de Informática. UVA campus Segovia 4

Page 6: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Reglas generales de sintaxis en C

Identi�cadores

Un identi�cador sirve para identi�car a todas las variables,constantes y funciones. Los identi�cadores deben cumplir lassiguientes normas:

a) Pueden formarse con cualquier combinación de letrasy números pero deben empezar por letra.

b) Se puede utilizar también el carácter

c) Es conveniente evitar el uso de ñ, Ñ y tildes.

d) El lenguaje C es sensible a mayúsculas y minúsculas.

e) El identi�cador no debe coincidir con ninguna palabrareservada del C como if, for, break, to, while, etc

Comentarios

a) Los comentarios en C empiezan por /* y terminan con*/, pueden ser de varias líneas y se pueden poner casi encualquier parte del programa.

b) En general, no se permite el anidamiento de comen-tarios. Es decir no se puede escribir /* Esto está /* anidado*/ en un comentario */

HSV - Escuela Universitaria de Informática. UVA campus Segovia 5

Page 7: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Reglas generales de sintaxis en C

Punto y coma

El punto y coma (;) se coloca al �nal de cada sentenciasimple tal como declaración de variable, asignación de unavariable y llamada a una función.

Funciones del sistema y del usuario

a) En C existen dos tipos de funciones: las que propor-ciona el sistema y las que de�ne el programador.

b) Las funciones del sistema están declaradas en los �cherosde cabecera <*.h>que se indican al principio del programa.

c) Si el programador requiere funciones no de�nidas en elsistema, deberá generarlas.

d) Dentro de cada función se distinguen dos partes se-cuenciales: la declaración de variables y el código.

e) La ejecución empieza y termina en la función main

f) La ejecución de un programa en C termina cuando:

- Se llega al �nal de main- Se ejecuta una sentencia exit()

- Se interrumpe externamente la ejecución de alguna manera- El programa falla internamente

HSV - Escuela Universitaria de Informática. UVA campus Segovia 6

Page 8: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Reglas generales de sintaxis en C

EJEMPLO:

/* Bloque de declaración de ficherosde cabecera y otras directivas */#include <stdio.h>#include <stdlib.h>

/* Bloque de declaración de variables globalesy definición de funciones del programa */

float PI=3.141592;

int promedio(int a,int b){return(a + b)/2;}

/* Función main */main(){int i,j;int media;

/* Este es un comentario */i=7;j = 9;media=promedio(i,j);printf("La media de %d y %d es %d\n", i, j, media);exit(0);

}

HSV - Escuela Universitaria de Informática. UVA campus Segovia 7

Page 9: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Variables escalares elementales

Variables escalares elementales

int Las variables de tipo int almacenan datos de tipoentero con signo y tienen, generalmente, un tamaño de 2octetos. Las variables de este tipo se pueden declarar así:

int suma;

int suma, resta, a, b, c;

int suma=5;

char El tipo char sirve ara almacenar datos de tipo caractery es similar al entero int, sin embargo, solo almacena datosde 8 bits en el intervalo [-128,127]. La declaración de estetipo de variables se realiza de manera similar al tipo int.

Aunque una variable sea de tipo char, se le puede ma-nipular como un número y los siguientes códigos de programason perfectamente válidos.

#include <stdio.h>

main() {

char letra;

letra='A';

printf("La variable letra vale %c.",letra);

}

SALIDA: La variable letra vale A.

HSV - Escuela Universitaria de Informática. UVA campus Segovia 8

Page 10: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Variables escalares elementales

#include <stdio.h>

main() {

char letra;

int num;

letra='A';

num=65;

printf("letra vale %c y num vale %i.",letra,num);

}

SALIDA: letra vale A y num vale 65

#include <stdio.h>

main() {

char c;

c=65;

printf("La variable c vale %i.",c);

printf("y almacena el caracter ASCII %c.",c);

}

SALIDA: La variable c vale 65 y almacena

el caracter ASCII A.

NOTA: Las sentencias c=65 y c='A' son equivalentespara C e incluso una sentencia como c='a'+25 es válida.

HSV - Escuela Universitaria de Informática. UVA campus Segovia 9

Page 11: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Estructuras básicas de control

Estructuras básicas de control

Estructura secuencial

La estructura secuencial en C es bastante simple y con-siste únicamente en colocar una sentencia a continuación dela otra. Por supuesto, cada sentencia debe terminar en (;).Considérese el siguiente código:

a=19;

b=5;

printf("%i mas %i es %i, ", a, b, a+b);

printf("\ny %i menos %i, %i.",a, b, a-b);

Estructura alternativa if ... else ...

La estructura if ... else se usa para ejecutar códigode manera selectiva y tiene la siguiente sintaxis:

if (expresión)

sentencia_1;

else

sentencia_2;

donde la expresión debe ir siempre encerrada entre parén-tesis y las sentencias deben terminar en (;). La parte corre-spondiente al else es opcional. Por otra parte, si se deseaejecutar más de una sentencia en if o else, es necesarioencerrarlas entre llaves.

HSV - Escuela Universitaria de Informática. UVA campus Segovia 10

Page 12: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Estructuras básicas de control

Ejemplos con if ... else ...

#include <stdio.h>

int a=4;int b=0;

main() {if (a>b) printf("%i es mayor que %i.", a, b);else printf("%i es mayor que %i.", b, a);

}

#include <stdio.h>

int a=4;int b=0;int mayor,menor;

main() {if (a>b)

{mayor=a;menor=b;}

else{mayor=b;menor=a;}

printf("El mayor es %i y el menor es %i.", mayor, menor);}

HSV - Escuela Universitaria de Informática. UVA campus Segovia 11

Page 13: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Estructuras básicas de control

Operadores lógicos y relacionales

Los operadores relacionales más comunes en C son:

< menor que, <= menor o igual que,

> mayor que, >= mayor o igual que,

== igual que, != diferente que

Los operadores lógicos más comunes son:

&& AND, || OR, ! NO

Por ejemplo, el pseudo código

si a=5 o b=3Escribir "La condición se cumple"�n si

se codi�ca en C como

if ((a==5)||(b==3))

printf("La condición se cumple");

HSV - Escuela Universitaria de Informática. UVA campus Segovia 12

Page 14: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Estructuras básicas de control

La estructura alternativa switch y la

instrucción break

La sentencia switch es una estructura decisión múltipleque veri�ca si una expresión coincide con una o varias etique-tas formadas por valores constantes enteros trans�riendoel control a la etiqueta coincidente. La sintaxis general es:

switch(expresión) {

case valor1: sentencia 1;

case valor2: sentencia 2;

...

default: sentencia N;

}

En el caso de que 'expresión' tenga el 'valor 1', seejecutarán la 'sentencia 1' y todas las que le siguen; siexpresión tiene 'valor 2', se ejecutarán la 'sentencia 2' ytodas las que le siguen, y así hasta la 'sentencia N-1'.

Si 'expresión' no coincide con ninguna de las etiquetas, elcontrol se trans�ere a la sentencia etiquetada como 'default';la etiqueta 'default', sin embargo, es opcional.

Dado que muchas veces se desea ejecutar solo una de lasopciones, se puede utilizar la sentencia 'break' para transferirel control hacia fuera de la estructura 'switch'. Se puede,además, disponer de no una sino varias sentencias a ejecutarpara cada 'case'.

HSV - Escuela Universitaria de Informática. UVA campus Segovia 13

Page 15: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Estructuras básicas de control

Ejemplo con la sentencia 'switch'#include <stdio.h>

int a=3;

main(){

switch (a) {

case 1: printf("La variable a vale 1");

break;

case 2: printf("La variable a vale 2");

break;

case 3: printf(" 3 ");

case 4: printf(" 4 ");

case 5: printf(" 5 ");

break;

default: printf("a no está entre 1 y 5");

}

}

En este caso, si a vale 3 se ejecutarán todas la sentenciasentre el case 3 y el siguiente break.

3 4 5

En cambio, si a no está entre 1 y 5, se ejecutará la sen-tencia de�nida por omisión.

a no está entre 1y 5

HSV - Escuela Universitaria de Informática. UVA campus Segovia 14

Page 16: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Estructuras básicas de control

Estructura iterativa do ... while

La sintaxis de la estructura iterativa do ... while es:

doinstrucción;

while (expresión);

- El cuerpo del bucle se ejecuta al menos una vez.- Hay un punto y coma (;) después de la expresión.- Para ejecutar varias instrucciones se encierran entre llaves.

#include <stdio.h>main() {int a,b;char resp;

do {/* Lectura de datos */printf("\n Primer número: ");scanf("%i", &a);printf("\n Segundo número: ");scanf("%i", &b);

/* Mostrar los datos */printf("\n\n Suma: %i", a+b);printf("\n Resta: %i", a-b);printf("\n Producto: %i", a*b);

/* ¾Desea continuar? */printf("\n ¾Desea continuar (S/N)?");resp=getchar();} while ( (resp=='S') || (resp=='s') );

}

HSV - Escuela Universitaria de Informática. UVA campus Segovia 15

Page 17: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Estructuras básicas de control

Estructura iterativa while

La estructura iterativa while funciona de manera similara la estructura do ... while y su sintaxis es la siguiente:

while (expresión)

instrucción;

- Se evalúa primero la expresión y luego se ejecuta el cuerpo- Los cuerpos de más de una instrucción van entre llaves

Estructura iterativa for

La estructura iterativa for tiene la siguiente sintaxis:

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

sentencia;

- Normalmente expresión1 y expresión3 son asignacionesEjemplo: for (i=0;i<n;i=i+1)

- La expresión2 es una expresión relacional- Cualquiera de las tres expresiones se puede omitirEjemplo: for( ; ; ) { ... }

- Se pueden colocar más expresiones separadas por comasEjemplo: for (i=0,j=1; (i!=0)||(j<10); j=j+1)

- Los cuerpos con varias instrucciones van entre llaves

HSV - Escuela Universitaria de Informática. UVA campus Segovia 16

Page 18: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Estructuras básicas de control

Ejemplo con la estructura iterativa for

#include <stdio.h>

/* Imprime la tabla Fahrenheit-Celsius */main (){int fahr;

for (fahr = 0; fahr <= 300; fahr = fahr + 20)printf("%4d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));

}

break y continue

La sentencia 'break' provoca una salida anticipada de un'for', 'while' o 'do ... while', tal como lo hace en 'switch'.Para ello provoca la �nalización del bucle más interno en elque está contenida.

La sentencia 'continue', por su parte, provoca que seinicie la siguiente iteración del ciclo 'for', 'while' o 'do ...while' que la contiene.

Esto signi�ca que el en 'while' o en el 'do ... while' setrans�era el control a la evaluación de la expresión, mientrasque en el caso del 'for', se traslada el control a la expresión3,que generalmente es un paso de incremento.

HSV - Escuela Universitaria de Informática. UVA campus Segovia 17

Page 19: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Tipos de datos en C

Tipos de datos en C

Tipos de datos escalares

El C admite cuatro tipos de datos escalares, que son losque se presentan en la siguiente tabla:

Tipo Descripción básicachar Carácter y entero en un byte (octeto)int Entero�oat Número en coma �otante de precisión normaldouble Número en coma �otante de doble precisión

a) Tipos de datos enteros

Como ya se mencionó, los tipos de datos enteros en C sonchar e int. Además, a los datos de tipo int se les puedeasignar los cali�cadores short, long, signed y unsigned;los dos últimos cali�cadores son aplicables al tipo char.

Las declaraciones típicas para estos tipos de datos puedenser de las siguientes formas:

short int x; /* Entero corto [−215, 215 − 1] */long int y; /* Entero largo [−231, 231 − 1] */unsigned int z; /* Entero sin signo [0, 216 − 1]*/char u; /* Carácter [0, 27] */signed char a; /* Carácter con signo [−27, 27 − 1]*/unsigned char b; /* Carácter sin signo [0, 28 − 1]*/

HSV - Escuela Universitaria de Informática. UVA campus Segovia 18

Page 20: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Tipos de datos en C

b) Tipos de datos reales

Existen en C dos formatos para almacenar datos de tiporeal: float y double. Estos formatos se distinguen entresí en que el segundo utiliza más bits que el primero para elalmacenamiento.

Existe además un cali�cador que amplía la resolución(y el tamaño) de la representación: long. Las declaracionestípicas para estos datos serían de la forma:

�oat x; /* Tipo real de cuatro bytes */double y; /* Tipo real de 8 bytes */long double /* Tipo real de 12 bytes */

#include <stdio.h>

#define PI 3.1416

main() {

float radio, area;

printf("\ Introduzca el radio: ");

scanf("%f", &radio);

superficie=PI*radio*radio;

printf("\nEl area es: %f\n", area);

}

HSV - Escuela Universitaria de Informática. UVA campus Segovia 19

Page 21: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Tipos de datos en C

Tipos de datos compuestos

En C, los tipos de datos compuestos se componen de tiposde datos más sencillos; normalmente escalares. Se tienen trestipos de datos compuestos en C: vector, struct y union.

a) El tipo vector (array)

El tipo vector (array) es una estructura formada por unbloque de N objetos numerados por su índice que va desde 0hasta N-1. La sintaxis declarativa es:

<tipo>nombre [<tamaño>];

Por ejemplo, int v[10]; declara una variable v dediez elementos que se referencían como v[0], ..., v[9]

NOTAS: 1) La declaración de un �chero no conllevanecesariamente su inicialización y puede ser necesario ini-cializar explícitamente. 2) En C no se puede asignar direc-tamente un vector a otro. Por ejemplo, dados float

a[100],b[100]; no se puede hacer la operación a=b.

Los arreglos multidimensionales se declaran de acuerdo ala siguiente sintaxis:

<tipo>nombre [<tam1>][<tam2>] ... [<tamN>]

donde N es la dimensión del arreglo.

HSV - Escuela Universitaria de Informática. UVA campus Segovia 20

Page 22: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Tipos de datos en C

El tipo registro: struct

El tipo registro (struct) es un tipo de dato formadopor una serie de elementos llamados campos que pueden serde diferente tipo. Una de las sintaxis para el tipo struct es

struct etiqueta {

tipo1 campo1;

tipo2 campo2;

...

tipoN campoN;

};

la cual de�ne un nuevo tipo de variable (etiqueta) quetiene la estructura dada y se puede utilizar para declararvariables usando la sintaxis:

struct etiqueta var1, var2, ..., varN;

También se pueden declarar las variables al mismo tiem-po que se declara la estructura usando la sintaxis:

struct etiqueta {

tipo1 campo1;

tipo2 campo2;

...

tipoN campoN;

} var1, var2, ..., varN;

HSV - Escuela Universitaria de Informática. UVA campus Segovia 21

Page 23: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Tipos de datos en C

Para hacer referencia a alguno de los elementos de unavariable de tipo estructura se usa la sintaxis se adjunta alnombre de la variable el del campo, separados por un punto.

Por ejemplo, dada la declaración

struct punto {

int x;

int y;

} a, b, c;

se pueden ejecutar las siguientes sentencias:

a.x=1;b.y=2;

Las variables de tipo estructura se pueden inicializar aldeclararse. Por ejemplo

struct punto d={10,6};

y se pueden copiar todos los campos de una estructura aotra, siempre y cuando sean del mismo tipo. Es decir, dadoslos ejemplos anteriores, la sentencia

a=b;

copia en una operación todos los campos de b hacia a.

HSV - Escuela Universitaria de Informática. UVA campus Segovia 22

Page 24: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Tipos de datos en C

c) El tipo union

El tipo union es una estructura de datos que puedecontener, en distintos momentos, datos de tamaños y tiposdistintos. Las uniones se usan para guardar diferentes vari-ables en la misma zona de memoria.

La sintaxis de una union es similar a la de los registros:

union etiqueta {

tipo1 dat1;

tipo2 dato2;

...

tipoN datoN;

} var1, var2, ..., varN;

y el compilador se encarga de reservar memoria paraalmacenar el dato de mayor tamaño.

Por ejemplo, dada la siguiente declaración

union mezcla {

char c;

int i;

float f;

} a;

el tamaño de a será el de un dato de tipo �otante.

HSV - Escuela Universitaria de Informática. UVA campus Segovia 23

Page 25: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Punteros (pointers)

Punteros (pointers)

El puntero es uno de los tipos de variable más importantesen C. Una variable de tipo puntero es una variable quealmacena que almacena la dirección de otra variable quese encuentra en la memoria.

Este tipo de variables se usan en conjunto con los oper-adores & (dirección) y * (contenido). Por ejemplo, consid-érese el siguiente código:

int dato; /* Se declara un dato de tipo entero */int *punt; /* Se declara un puntero a entero */...punt=&dato; /* punt recibe la DIRECCIÓN del dato */*punt=5; /* el CONTENIDO de punt es cinco */

Al hacer la asignación punt=&dato, la variable punt alma-cena la dirección de la variable dato. La operación *punt=5

almacena un 5 en el contenido de la variable apuntada porpunt, es decir, dato.

Se pueden de�nir apuntadores a casi cualquier tipo dedato en C. Para ello se puede utilizar la sintaxis

<tipo> *nombre;

Antes de usar un apuntador, es indispensable asegurarsede que apunta a una dirección válida. Para ello, se puedeninicializar los punteros con un valor 0 ó nulo NULL.

HSV - Escuela Universitaria de Informática. UVA campus Segovia 24

Page 26: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Punteros (pointers)

Punteros y vectores

Habiendo de�nido un puntero y un vector del mismo tipode dato, el puntero puede �apuntar� a cualquiera de loscomponentes del vector. Considérese el siguiente código:

char vector[10];

char *puntero;

...

punt=&vector[0];

vector[2]=18;

*(puntero+2)=18;

Dado que al de�nir un vector (array) de N elementos loque se hace en realidad es de�nir un puntero a una zona deN elementos, las instrucciones siguientes son equivalentes

vector[2]=18;

*(vector+2)=18;

e incluso, dado que vector es una dirección, es posible hacerla asignación puntero=vector;

NOTA: Hay que recordar que un puntero es una variabley un arreglo es una constante que no se puede modi�car. Así,la siguiente operación es incorrecta:

vector=vector+1;

HSV - Escuela Universitaria de Informática. UVA campus Segovia 25

Page 27: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Punteros (pointers)

Punteros y memoria dinámica

En C se puede reservar memoria dinámica, es decir, entiempo de ejecución del programa. Para ello se usa la funciónmalloc(). La función malloc() tiene la sintaxis

p=malloc(tamaño en bytes);

y devuelve un apuntador genérico a una zona de memo-ria con el espacio reservado. Si la localización de memoria notuvo éxito, el valor devuelto por malloc() es NULL.

Para reservar memoria para una cierta cantidad N dedatos de tipo X y tamaño T, se puede usar la sintaxis

punt=(X *)malloc(N*sizeof(dato));

donde punt es un puntero de tipo X y sizeof() es unafunción que calcula el tamaño del mismo; en este caso, T.

Existe una función inversa a malloc() y es la funciónfree(), la cual se encarga de liberar la memoria que ha sidoasignada mediante una llamada a malloc().

El formato de esta función es simplemente

free(puntero);

Considérese el ejemplo de la siguiente página.

HSV - Escuela Universitaria de Informática. UVA campus Segovia 26

Page 28: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Punteros (pointers)

#include <stdio.h>

#include <stdlib.h>

main(){

struct fecha{

char dia;

char mes;

int anio;

} *punt;

/* Asignación de memoria a punt */

punt=malloc(sizeof(struct fecha));

if (punt==NULL) {

printf("Error: no hay memoria.");

exit(1);

}

printf("Día: ");

scanf("%i",&(punt->dia));

printf("Mes: ");

scanf("%i",&(punt->mes));

printf("Año: ");

scanf("%i",&(punt->anio));

printf("Dia %i, mes %i, anio %i,

punt->dia, punt->mes, punt->anio);

}

HSV - Escuela Universitaria de Informática. UVA campus Segovia 27

Page 29: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Punteros (pointers)

Punteros y cadenas de caracteres

No existe en C ningún tipo de dato especí�co para alma-cenar cadenas de caracteres. En lugar de ello, se almacenacomo vectores de caracteres, a razón de un caracter por cadaposición de memoria, colocándose al �nal un terminador.

El terminador de cadena se representa por el valor 0(cero), que es equivalente a la secuencia de escape \0 y laconstante NULL. Por ejemplo, la cadena Hola,soy yo. serepresentaría en memoria como

72 111 108 97 44 115 111 121 32 121 111 46 0H o l a , s o y y o . \0

Así, una cadena se almacena como un vector de carac-teres y debe declararse como tal. Por ejemplo, las siguientesdeclaraciones son válidas

char cad[30];

char cad[30]="Hola,soy yo.";

char cad[30]={'H','o','l','a',',','s','o','y','

','y','o','.',NULL};

La asignación de una cadena durante la ejecución del pro-grama, no se puede hacer directamente. Es decir, la siguientesentencia es inválida:

cad="Hola,soy yo."; /* Esto es inválido */

HSV - Escuela Universitaria de Informática. UVA campus Segovia 28

Page 30: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Punteros (pointers)

Si se desea hacer una asignación durante la ejecucióndel programa, existen varias posibilidades. Usando una asig-nación caracter a caracter basada en una notación de vectoresquedaría así:

cad[0]='H';

cad[1]='o';

...

cad[12]=0;

Si se usa una notación basada en punteros, la asignaciónquedaría así:

*cad='H';

∗(cad+1)='o';...

∗(cad+12)=0;

La opción más sencilla es usar la función strcpy() dela biblioteca estándar de C. Esta función tiene la sintaxis

char *strcpy(char *s, constante)

y en este caso se puede hacer la operación así

strcpy(cad,"Hola,soy yo.");

HSV - Escuela Universitaria de Informática. UVA campus Segovia 29

Page 31: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Punteros (pointers)

Salida de una cadena por pantalla

La salida de una cadena por pantalla se puede hacermediante la función printf() usando el descriptor%s. Porejemplo,

printf("La cadena es %s", cad);

Entrada de una cadena por teclado

Para leer una cadena por teclado, se puede usar la funciónscanf() y el descriptor%s como en la siguiente sentencia:

scanf(" %s",cad);

Existe también la posibilidad de leer una cadena usandola función gets(). Esta función tiene la sintaxis

char *gets(char *s)

La función gets() tiene la ventaja de que lee la entradapor teclado hasta encontrar un cambio de línea, mientrasque la función scanf() solo lee palabras sueltas, es decir,separadas por espacios.

Considérese el ejemplo de la siguiente página. El progra-ma lee una cadena por teclado y la despliega por pantallaconvirtiendo todos sus caracteres a minúsculas.

HSV - Escuela Universitaria de Informática. UVA campus Segovia 30

Page 32: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Punteros (pointers)

#include <stdio.h>

main(){

char cad[30];

int i;

printf("Introduce la cadena: ");

gets(cad);

for (i=0;cad[i]!=0;i++)

if ( (cad[i]>='A') && (cad[i]<='Z') )

cad[i]=cad[i]+32;

printf("La cadena en minúsculas es: %s", cad);

}

Práctica: Usando notación de punteros, hacer un pro-grama que lea una cadena por teclado y la escriba a con-tinuación en pantalla de acuerdo a la siguiente regla: si lacadena tiene N caracteres, se debe desplegar en el orden 1,N, 2, N-1, 3, N-2, ... Por ejemplo, si la cadena de entrada escartas, la cadena de salida será csaart.

Práctica: Usando memoria dinámica y notación depunteros, elaborar un programa que haga lo siguiente: (a)preguntar por el tamaño de una matriz; cuadrada; (b) leerlos datos de la matriz por teclado; (c) presentar en pantallala traspuesta de la matriz introducida.

HSV - Escuela Universitaria de Informática. UVA campus Segovia 31

Page 33: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Funciones de usuario

Funciones de usuario

Una función es un fragmento de código que puede ser in-vocado por otras funciones. Considérese el siguiente ejemplo:

#include <stdio.h>

/* Función para calcular el factorial */

double Factorial(int x){

int i; /* Variable local */

double fac=1; /* Variable local */

for (i=1;i<=x;i++) fac=fac*i;

return fac;

}

/* Función principal main() */

main(){

int numero; /* Variable local */

double resultado; /* Variable local */

printf("Introduce un número natural: ");

scanf("%i",&numero);

resultado=Factorial(numero);

printf("\n El factorial de %i es %f",

numero,resultado);

}

HSV - Escuela Universitaria de Informática. UVA campus Segovia 32

Page 34: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Funciones de usuario

Las funciones en C tienen las siguientes características:

a) Puede recibir cero, uno o varios parámetros.b) Puede usar variables globales y variables locales.c) Puede llamar a otras funciones.d) Puede regresar un resultado en la llamada.e) Se les pueden agrupar en bibliotecas de usuario.

Tipo de una función

El tipo de una función es siempre el tipo de dato quedevuelve y este tipo debe coincidir con el de la variable quelo recibe. En el ejemplo anterior, ambos son de tipo double.

Sin embargo, también existen funciones que no recibenni devuelven ningún parámetro. En este caso se usa un tipode dato especial que es void. Véase la siguiente función:

void EscribeAsteriscos(void) {

printf("**********************");

}

La de�nición de la función, se podría hacer también de-jando los paréntesis vacíos y para llamarla se usaría la sintaxis

EscribeAsteriscos();

NOTA: Una función puede devolver cualquier tipo dedato, pero para devolver estructuras se debe usar un puntero.

HSV - Escuela Universitaria de Informática. UVA campus Segovia 33

Page 35: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Funciones de usuario

Parámetros de entrada

Según el estándar ANSI C, la de�nición de los parámetrosde entradas se hace en la de�nición de la función de acuerdoa la siguiente sintaxis:

tipo_func nombrefunc (tipo1 param1,

tipo2 param2, ..., tipoN paramN) {

/* Cuerpo de la función */

}

donde:tipo func es el tipo de la función.nombre func es el nombre de la función.tipo1 es el tipo del parámetro param1.

NOTA: Algunos compiladores no siguen el estándar ANSIy pueden generar el mensaje de error

function prototypes are an ANSI feature

En este caso se tienen dos opciones:

a)Compilar usando un parámetro de línea que fuerce alcompilador a seguir el estándar ANSI.b) Cambiar la de�nición de funciones del formato ANSI alformato original de C, el cual también es soportado por loscompiladores ANSI.

HSV - Escuela Universitaria de Informática. UVA campus Segovia 34

Page 36: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Funciones de usuario

Parámetros formales y actuales

Los parámetros con los que se de�ne una función enC se llaman parámetros formales, mientras que losparámetros con los que se invoca a las funciones se llamanparámetros actuales.

Así, al llamar a las funciones, los valores de los parámetrosactuales se copian a la zona de memoria de los parámetrosformales, sean aquéllos una variable o una constante.

Paso de parámetros por valor y por referencia

En C, los parámetros de llamada a una función sepueden pasar por valor (copia) o por referencia (variable).En el primer caso, se pasa al parámetro formal el valor delparámetro actual de llamada, mientras que en el segundocaso se pasa la dirección de la variable que contiene el valordel parámetro actual.

La principal ventaja del paso de parámetros por referenciaes el poder modi�car el valor del parámetro actual dentro dela función invocada, lo cual no es posible en el caso del pasode parámetros por valor.

Otra ventaja del paso por referencia es darle a unafunción la capacidad de poder "devolver"más de un resultado.Considérense los siguientes ejemplos:

HSV - Escuela Universitaria de Informática. UVA campus Segovia 35

Page 37: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Funciones de usuario

#include <stdio.h>

/* Función para calcular el factorial */

double Factorial(int *x) {

int i;

double fac=1;

for (i=1;i<=(*x);i++) fac=fac*i;

return fac;

}

main(){ /* Función principal main() */

int numero; /* Variable local */

double resultado; /* Variable local */

printf("Introduce un número natural: ");

scanf("%i",&numero);

resultado=Factorial(&numero);

printf("\n El factorial de %i es %f",

numero,resultado);

}

void Circulo (float radio, float *perim,

float *area) {

*perim=2*3.1416*radio;

*area=3.1416*radio*radio;

}

HSV - Escuela Universitaria de Informática. UVA campus Segovia 36

Page 38: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Funciones de usuario

Reglas de ámbito para las variables

Las reglas de ámbito (scope rules) permiten distinguirlas zonas de código en las que son accesibles las variablesde�nidas. Esa zona de código se denomina campo o ámbito

de validez de la variable.

El campo de validez de una variable, según Kernighany Ritchie, depende de la parte del programa en la que estédeclarada. Así, por ejemplo, para una variable declarada alprincipio de una función, el campo de validez es la funciónen la que se declara.

NOTA: Dos variables con el mismo nombre que se handeclarado en funciones diferentes no están relacionadas.

Lo anterior vale también para los parámetros formales.

Ámbito de las variables globales

Una excepción a la regla anterior son las variables glob-ales, las cuales se declaran al principio del programa y fuerade toda función de�nida. Se recomienda evitar su uso.

Las variables globales son visibles desdecualquier punto del programa, incluyendo a main()

y al resto de las funciones de�nidas. Sin embargo, si existeuna variable de igual nombre dentro de una función, estatiene preponderancia y es la que se utiliza.

HSV - Escuela Universitaria de Informática. UVA campus Segovia 37

Page 39: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Funciones de usuario

Paso de estructuras de datos

Respecto al paso y devolución de estructuras de datos,solo hay que tener en cuenta una regla: se debe hacermediante punteros y no se puede usar una copia.

Considérese el siguiente programa donde se procesa unacadena leída para quitarle todos los espacios en blanco.

#include <stdio.h>

void QuitaEspacios(char *cad1, char *cad2){

int i=0,j=0;

for (i=0;cad1[i]!='\0';i++)

if (cad1[i]!=' ') cad2[j++]=cad1[i];

cad2[j]='\0';

}

main () {

char cadena1[50];

char cadena2[50];

printf("Introduce una cadena: ");

gets(cadena1);

QuitaEspacios(cadena1,cadena2);

printf("%s", cadena2);

}

HSV - Escuela Universitaria de Informática. UVA campus Segovia 38

Page 40: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Funciones de usuario

Parámetros de main()

Al igual que con las funciones de�nidas por el usuario,también es posible pasar parámetros a la función main().En este caso, los parámetros se deben pasar a main() comoargumentos en la línea de órdenes.

Para poder utilizar en el programa los argumentos querecibe en la línea de órdenes se debe declarar a main() de lasiguiente manera:

main(int argc,char *argv[]) {

...

}

donde argc indica el número de argumentos, incluyendoel nombre del programa, y argv es un vector de punterosa caracter que apuntan a cada uno de los argumentos. Elsiguiente programa muestra estos parámetros en pantalla:

#include <stdio.h>

main (int argc, char *argv[]) {

int i;

printf("Numero de argumentos: %i\n", argc);

printf("Argumentos:\n");

for (i=0;i<argc;i++) printf("%s\n", argv[i]);

}

HSV - Escuela Universitaria de Informática. UVA campus Segovia 39

Page 41: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Funciones de usuario

Punteros a funciones

En C existe la posibilidad de pasar funciones comoparámetros a otras funciones, lo cual es muy útil para indi-carle a una función que realice su tarea con ayuda de unafunción u otra, según sea el caso.

Supóngase que tenemos una función llamada Ordenar()que lee un vector de enteros de un �chero, lo ordena y lovuelve a almacenar en él. Esta función podría estar de�nidade la siguiente manera:

void Ordenar(void) {

int vector[15];

...

...

LeerVector(vector);

Sort(vector);

EscribirVector(vector);

...

}

Si se deseara ordenar el vector de acuerdo a diferentes crite-rios, se debería disponer de varias versiones de Sort() talescomo Sort1(), Sort2() y Sort3(), y para poder uti-lizarlas habría que disponer de tres versiones de Ordenar()para que cada una llamara a una función Sort.

HSV - Escuela Universitaria de Informática. UVA campus Segovia 40

Page 42: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Funciones de usuario

Otra posibilidad es disponer de una única función Or-denar() que recibiría como parámetro la dirección de lafunción de ordenación que debe utilizar.

Esa dirección se le puede pasar mediante un puntero afunción, el cual tiene la sintaxis:

tipo (*nombre punt)()

donde tipo es el tipo de dato que devuelve la función ynombre punt el nombre del puntero a función.

Por ejemplo, la declaración

int (*punt)()

de�ne a punt como un puntero a una función que devuelveun entero.

Debe tenerse en cuenta que lo anterior es diferente a

int *punt()

lo cual de�ne una función llamada punt que devuelve unpuntero a entero.

HSV - Escuela Universitaria de Informática. UVA campus Segovia 41

Page 43: Introducción al C bajo UNIX - MSc. Jaime Soto (Ing ... · PDF fileIntroducción al C bajo UNIX Hernando Silva Varela Escuela Universitaria de Informática Universidad de Valladolid

Introducción al C bajo UNIX Funciones de usuario

Si se utiliza un puntero a función y se le pasa aOrdenar(), la declaración de la función quedaría de lasiguiente manera:

void Ordenar(void (*punt)()) {

int vector[15];

...

...

LeerVector(vector);

*punt(vector);

EscribirVector(vector);

...

}

es decir, se le pasa punt como parámetro formal y en elcuerpo de la función se reemplaza Sort por "el contenidode punt", que es la dirección de la función que se deseaejecutar.

Por otra parte, para hacer la llamada de la funciónordenar(), y pasarle el parámetro actual que reemplaza apunt, se podría usar el siguiente código

...

if (orden=='a') Ordenar(Sort1);

else Ordenar(Sort2);

...

HSV - Escuela Universitaria de Informática. UVA campus Segovia 42