P. 1
Lenguaje de Programacion C

Lenguaje de Programacion C

|Views: 2.514|Likes:
Publicado porDaniel Arroyo

More info:

Published by: Daniel Arroyo on Oct 02, 2011
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

08/08/2013

pdf

text

original

Sections

  • Lenguajes de Programación I
  • Introducción al C
  • Historia del C
  • Características del C
  • Inconvenientes del C
  • Primer programa en C
  • Segundo programa en C
  • Modelo de compilación C
  • Entorno desarrollo IDE
  • Ejercicio
  • Comentarios
  • Identificador
  • Palabras reservadas
  • Variables
  • Tipos de datos básicos
  • Tipos de datos. Modificadores
  • Declaración de variables
  • Tipos definidos
  • La función printf()
  • La función printf() (y 2)
  • La función printf() (y 3)
  • La función printf (y 4)
  • Función scanf() (y 2)
  • Constantes simbólicas
  • Constantes o literales
  • Ejemplo
  • Operadores y expresiones
  • Expresiones y sentencias
  • Operador de asignación
  • Reglas de asignación
  • Conversión de tipos
  • Operadores aritméticos
  • Operadores relacionales
  • Operadores lógicos
  • Ejemplo
  • Operadores de asignación compuestos
  • Precedencia
  • Ejercicios
  • ERRORES COMUNES
  • Funciones
  • Introducción a funciones
  • Introducción
  • Definición de una función
  • Llamadas a funciones
  • Ejemplo 3
  • Ejemplo 3 - Continuación
  • Ejercicio 4
  • Solución
  • Recapitulación
  • Sentencias de control
  • Estructuras de control
  • Tipos de estructuras
  • If - else
  • Ejemplo if - else
  • Operador condicional
  • switch
  • Ejemplo switch
  • Bucles
  • Instrucción for
  • Ejemplo for
  • Instrucción while
  • Ejemplo while
  • Ejemplo do -while
  • Bucles anidados
  • Instrucción break
  • Ej
  • Ejemplo continue
  • Tabla de comparativas
  • Ejemplo - funciones y bucles
  • Recursividad
  • Ejemplo “torres de Hanoi”
  • Ejemplo “torres de Hanoi” (y 2)
  • Arrays (listas y tablas)
  • Ejemplo lista tamaño fijo
  • Ejemplo lista tamaño variable
  • Ordenación elementos de lista
  • biblioteca estándar string.h
  • Estructuras y uniones
  • Ejemplo (y 2)
  • Cont
  • Combinación de typedef y enum
  • Ficheros
  • Canales y ficheros
  • Canales y ficheros ( y 2)
  • Cierre de un fichero
  • Control de errores
  • Final de fichero
  • Ficheros de texto
  • Escribir a fichero binario
  • Lectura de fichero binario
  • Ejemplo agenda
  • Ejemplo: Lectura en bloques
  • Acceso directo
  • Acceso directo (y 2)
  • Programación modular
  • Tema 13
  • Variables globales
  • Variables globales (y 2)
  • Variables locales
  • Variables estáticas
  • Variables de tipo registro
  • Variables de tipo externas
  • Recomendaciones
  • Macros
  • Macros (y 2)
  • Directiva #include
  • Archivos de cabecera (.h)
  • Punteros y arrays
  • Punteros
  • Punteros (y 2)
  • Punteros (y 3)
  • Asignación punteros
  • Arrays
  • Ejemplo arrays
  • Tema 16
  • Paso de vectores a funciones
  • Punteros y vectores
  • Punteros y vectores (y 2)

Lenguajes de Programación I

Referencia Marta Zorrilla Universidad de Cantabria

Ing. Santiago Esparza Guerrero Ingeniería en Computación Unidad Académica de Ingeniería Eléctrica

1

Introducción al C
Objetivos:
Presentar la historia del lenguaje C y sus características principales. Presentar la estructura de un programa en C mediante ejemplos sencillos.

Contenidos:
1. La historia del C. 2. Características. 3. Mi primer programa en C.

2

Historia del C
Muchas ideas provienen de BCPL (Martin Richards, 1967) y de B (Ken Thompson, 1970). C fue diseñado originalmente en 1972 para el SO UNIX en el DEC PDP-11 por Dennis Ritchie en los Laboratorios Bell. Primer Libro de referencia de C: The C Programming Language (1978) de Brian Kernighan y Dennis Ritchie. En los 80, gran parte de la programación se realiza en C. En 1983 aparece C++ (orientado a objetos). En 1989 aparece el estándar ANSI C. En 1990 aparece el estándar ISO C (actual estándar de C). WG14 se convierte en el comité oficial del estándar ISO C. En década de los 90, WG14 trabaja en el estándar C9X/C99 que resuelve problemas de fiabilidad del ANSI C, amplia su funcionalidad con nuevos tipos de dato, funciones matemáticas, arrays irrestringidos, etc.
3

Características del C
Lenguaje de programación de propósito general, muy adecuado para programación de sistemas (unix fue escrito en C). Lenguaje relativamente pequeño: solo ofrece sentencias de control sencillas y funciones. La E/S no forma parte del lenguaje, sino que se proporciona a través de una biblioteca de funciones. Permite la agrupación de instrucciones. Programación estructurada. Permite la separación de un programa en módulos que admiten compilación independiente. Diseño modular. Programas portables.

4

*-F/OO/OO).printf("%1.3f\n". Es bastante permisivo con la conversión de datos.} 5 . #define _ -F<00||--F-OO--.OO=00.. Sin una programación metódica puede ser propenso a errores difíciles de encontrar.4. main(){F_OO().}F_OO() {…. int F=00.Inconvenientes del C No es un lenguaje fuertemente tipado. La versatilidad de C permite crear programas difíciles de leer.

} 6 . Programa DOCENA. docena).C */ #include <stdio.Primer programa en C /* Ejemplo 1. printf ("Una docena son %d unidades\n".h> main () { int docena. docena = 12.

error=imprimir_saludo (MENSAJE).h> #define MENSAJE “alumnos” /*prototipo funciones*/ int imprimir_saludo (char * destino). Programa saludo.c*/ #include <stdio. return(0). } 7 . int main (void) { int error=0. return(0). } int imprimir_saludo (char * destino) { printf (“hola %s \n". destino).Segundo programa en C /* Ejemplo 1.

El programa se ejecuta tecleando a.c . compilar y ejecutar un programa C Crear un fichero con extensión .out .Genera el ejecutable a.o .Crear.o El mandato cc ejemplo.Genera el código objeto ejemplo.o -o ejemplo genera el ejecutable ejemplo . 8 .El programa se ejecuta tecleando ejemplo.c genera el fichero objeto ejemplo.out El mandato cc -c ejemplo.c con un editor de texto Mandato de compilación básico: cc ejemplo.

Modelo de compilación C 9 .

Entorno desarrollo IDE 10 .

} int cuadrado (int lado) { return(lado*lado).h> int cuadrado (int). Calcula el área de la zona comprendida entre ambos. Sean dos cuadrados de lados L1 y L2 inscritos uno en otro. printf ("dame lado del cuadrado 2:"). cuadrado(lado1)-cuadrado(lado2)). } 11 . scanf( "%d".&lado2). utilizando para ello una función (que se llamará AreaCuadrado) que devuelve el área de un cuadrado cuyo lado se pasa como argumento printf ("dame lado del cuadrado 1:").Ejercicio #include <stdio. lado1. int main (void) { int lado2. return(0). printf ("El resultado de la diferencia es %d". scanf(" %d".&lado1).

Elementos de un programa en C 12 .

Enseñar las instrucciones de lectura y escritura junto con el formato de los datos.Elementos de un programa C Objetivos: Mostrar la utilidad de documentar el código utilizando los comentarios. 4. 5. Explicar los conceptos de variable y tipo de dato. Lectura de datos con scanf() . 2. Comentarios Identificadores y palabras reservadas Constantes Variables y tipos de dato Escritura de datos con printf() 13 6. 3. Contenidos: 1. Conocer los identificadores válidos y tipos de constantes.

Elementos de un programa C Básicamente el C está compuesto por los siguientes elementos: • • • • • • Comentarios Identificadores Palabras reservadas Variables y tipos de datos Constantes Operadores 14 .

Dentro de un comentario no puede aparecer el símbolo /* /* Este es un comentario que ocupa más de una línea */ // Este comentario ocupa una sola línea 15 .Comentarios Sirven para incrementar la legibilidad de los programas. No se pueden anidar.

Identificadores NO válidos: Empezar por – Empezar por un número Utilizar la " Ejemplos válidos: numero area_circulo valor_1 16 .Identificador Nombre que se asigna a los distintos elementos del programa (variables.…). funciones.

17 . pues el compilador no la reconoce como una instrucción. la palabra reservada for no puede escribirse como FOR.Palabras reservadas auto break case char const continue default do double else enum extern float for goto if int long register return short sizeof static struct switch typedef union unsigned void volatile while Es preciso insistir en que C hace distinción entre mayúsculas y minúsculas. sino que la interpreta como un nombre de variable. Por lo tanto.

Cada variable es de un tipo de dato determinado. 18 .Variables Identificador utilizado para representar un cierto tipo de información. Una variable puede almacenar diferentes valores en distintas partes del programa.

Tipos de datos básicos TIPO sin valor carácter entero coma flotante (simple precisión) coma flotante (doble precisión) PALABRA RESERVADA void char int float double TAMAÑO EN BYTES 0 1 2 4 8 19 .

4*10+38 ±1.768 a 32.648 a 2.4*10-4932 a ±1.295 -2.7*10-308 a ±1.1*10+4932 4 bytes 8 bytes 10 bytes Rango Ocupa 1 byte 1 byte 2 bytes 2 bytes 4 bytes El tipo de dato int coincide con el tamaño de palabra del procesador.483.647 4 bytes ±3.294.7*10+308 ±3.147. generalmente 4 bytes 20 .Tipos de datos.767 0 a 4.535 -32.147.4*10-38 a ±3.483.967. Modificadores Tipo char Modificadores unsigned signed int short unsigned signed long unsigned signed float double long 0 a 255 -128 a 127 0 a 65.

. unsigned long entero.. 21 . var2. int k. Deben asignarse a las variables nombres significativos. El formato de una declaración es: tipo_de_dato var1. b. char letra. numero_2. float numero_1.. c. Ejemplos: int a. varN..Declaración de variables Una declaración asocia un tipo de datos determinado a una o más variables. Deben declararse todas las variables antes de su uso. int temperatura.

Tipos definidos Permite dar nuevo nombre a tipos de datos que ya existen. typedef float Mts. Mts longitud. 22 . Sintaxis: typedef tipo_basico nombre. Y su uso al declarar variables: Kg peso. Declaración : typedef float Kg. siendo estos más acordes con aquello que representan.

28). printf("El numero 28 es %d\n". Ejemplos: printf("Hola mundo\n"). argumentos). 3.La función printf() Permite imprimir información por la salida estándar (pantalla) Formato: printf(formato.0e+8). printf("Imprimir %c %d %f\n". 'a'. 23 . 28.

f) unsigned hexadecimal int (con A.. .dddd [-]d... F) [-]dddd.. ..La función printf() (y 2) Formatos.dddd o bien e[+/-]ddd el más corto de %e y %f [-]d. TIPO DE ARGUMENTO Numérico CARÁCTER DE FORMATO %d %i %o %u %x %X %f %e %g %E %G %c %s %% %n %p FORMATO DE SALIDA signed decimal int signed decimal int unsigned octal int unsigned decimal int unsigned hexadecimal int (con a..dddd o bien E[+/-]ddd el más corto de %E y %f carácter simple cadena de caracteres el carácter % se refieren a punteros y se 24 Carácter Punteros .

CARÁCTER BARRA \a \b \t \n \v \f \r \" \' \\ SIGNIFICADO Alarma (Beep) Retroceso (BS) Tabulador Horizontal (HT) Nueva Línea (LF) Tabulador Vertical (VT) Nueva Página (FF) Retorno Comillas dobles Comilla simple Barra invertida 25 .La función printf() (y 3) Secuencias de escape.

produce la salida: Numero entero = 28 printf("Numero real = %5.4f \n".2). 28. produce la salida: Numero real = 28.2000 26 .La función printf (y 4) Especificadores de ancho de campo: printf("Numero entero = %5d \n". 28).

Función scanf() Permite leer datos del usuario. no & scanf("%s". Ejemplos: scanf("%f". cadena). argumentos). &entero. &real. No va texto Formato: scanf(formato. Especificadores de formato igual que printf(). scanf("%f %d %c". scanf("%ld". &entero_largo). La función devuelve el número de datos que se han leído bien. & scanf("%c\n". &letra). 27 . &letra). &numero).

scanf("%d". &numero).h> void main() { int numero. cuadrado = numero * numero. Comenzar ESCRIBIR Dame numero LEER numero cuadrado=numero * numero ESCRIBIR numero y cuadrado FIN } 28 .Función scanf() (y 2) Ejemplo: lee un número entero y lo eleva al cuadrado: #include <stdio. printf("El cuadrado de %d es %d\n". numero. int cuadrado.cuadrado). printf("Introduzca un numero:").

141593 CIERTO 1 FALSO 0 AMIGA "Marta" no acaba en .Constantes simbólicas Para evitar el uso de valores constantes dentro del código. #define #define #define #define PI 3. 29 . se definen las constantes simbólicas Suele escribirse en mayúsculas.

04E-12 Valores negativos (signo menos): -12 -2e+9 30 .2e+9. 1. 8. 14. " barco" Valores enteros: Notación decimal: 987 Notación hexadecimal: 0x25 ó 0X25 Notación octal: 034 Enteros sin signo: 485U Enteros de tipo long: 485L Enteros sin signo de tipo long: 485UL Valores negativos (signo menos): -987 Valores reales (coma flotante): Ejemplos: 12. .34 Notación exponencial: ..Constantes o literales Caracteres: Ejemplos: "Marta ".

Ejemplo. &radio).141593 ESCRIBIR Dame radio LEER radio area = PI * radio * radio ESCRIBIR area FIN 31 . area). float area. printf("El area del circulo es %5. area = PI * radio * radio.4f \n".h> #define PI 3. Programa que lee el radio de un círculo y calcula su área #include <stdio. } Comenzar PI =3. printf("Introduzca el radio: "). scanf("%f".141593 void main() { float radio.

print (Hay d días en una semana).h /* Programa que dice cuántos días hay en una semana /* main {} ( int d d := 7.Ejercicios Encuentra errores include studio. 32 .

num = 2."). c) printf ("Estamos \naprendiendo /naprogramar en C"). num. b) printf ("¿Cuántas líneas \nocupa esto?"). num + num). 33 . d) int num. printf ("Autor: Julio Cortázar"). num.Ejercicios Indica cuál sería la salida de cada uno de los siguientes grupos de sentencias: a) printf ("Historias de cronopios y famas. printf ("%d + %d = %d".

Operadores y expresiones 34 .

Precedencia 35 . Operadores lógicos 6. Expresiones y sentencias Operador asignación. operador y sentencia. 2. Mostrar el repertorio de operadores de C y el orden de precedencia. Operadores de asignación compuestos 7. 3. 4. Conversión de tipos Operadores aritméticos Operadores relacionales 5. Contenidos: 1.Operadores y expresiones Objetivos: Mostrar el concepto de expresión.

forman un bloque. Cuando un grupo de sentencias se encierran entre llaves { }.Expresiones y sentencias Sentencia: especifica una acción a realizar Ej. printf() Expresión: secuencia de operadores y operandos que especifican un valor Ej. 36 . sintácticamente equivalente a una sentencia. 4+5 Una expresión se convierte en una sentencia cuando va seguida de un punto y coma.

= expresión Las asignaciones se efectúan de derecha a izquierda. En i = j = 5 1.Operador de asignación Forma general: identificador = expresión . El operador de asignación = y el de igualdad == Asignaciones múltiples: id_1 = id_2 = . area = lado * lado... Ejemplos: a = 3. A j se le asigna 5 2. A i se le asigna el valor de j 37 .

3. Además: 1. 2. entonces el valor del operando de la derecha será automáticamente convertido al tipo del operando de la izquierda. Una cantidad entera puede alterarse si se asigna a una variable de tipo entero corto o a una variable de tipo carácter. Un valor en coma flotante se puede truncar si se asigna a una variable de tipo entero.Reglas de asignación Si los dos operandos en una sentencia de asignación son de tipos distintos. 38 . Un valor de doble precisión puede redondearse si se asigna a una variable de coma flotante de simple precisión. Es importante en C utilizar de forma correcta la conversión de tipos.

Ahora. el valor asignado a la variable y será 2.5.5. x = 5. x = 5. no se asigna a y el valor 2. y = (float) x / 2. int x. int x. sino 2. y = (float) (x / 2). x = 5. ya que los paréntesis que envuelven a la expresión x / 2 hacen que primero se efectúe la división entera y luego la conversión a flotante 39 . pues / realiza una división entera. y = x / 2.Conversión de tipos (tipo de dato) expresión int x. la variable y almacena el valor 2.

Operadores aritméticos
• División entera ( / ): división de una cantidad entera por otra ⇒ se desprecia la parte decimal del cociente. • El operador % requiere que los dos operandos sean enteros. • La mayoría de las versiones de C asignan al resto el mismo signo del primer operando. • Valores negativos con el signo OPERADOR UNARIOS -++ BINARIOS + * / % DESCRIPCIÓN Cambio de signo Decremento Incremento Resta Suma Producto División Resto de división entera

40

Ejemplo
int x, y; x = 9; y = 2; la operación x / y devuelve el valor 4, mientras que la operación x % y devuelve 1. Sin embargo, después de las sentencias float x; int y; x = 9.0; y = 2; la operación x / y devuelve 4.5, no pudiéndose aplicar, en este caso, el operador % puesto que uno de los operandos no es entero.
41

Operadores incremento, decremento
La expresión
i++; ++i; i--; --i;

es equivalente a
i i i i = = = = i i i i + + 1; 1; 1; 1;

Si el operador sigue al operando el valor del operando se modificará después de su utilización. Si el operador precede al operando el valor del operando se modificará antes de su utilización. Ejemplo: si a = 1 printf("a printf("a printf("a printf("a = = = = %d %d %d %d \n", \n", \n", \n", a); ++a); a++); a); Imprime: a a a a = = = = 1 2 2 3
42

Operadores relacionales
• Se utilizan para formar expresiones lógicas. • El resultado es un valor entero que puede ser: cierto, se representa con un 1 falso, se representa con un 0
BINARIOS

OPERADOR > >=

DESCRIPCIÓN Mayor que Mayor o igual que Menor que Menor o igual que Igual que Diferente que

Ejemplo 1: Si a = 1 y b = 2 Expresión a<b a>b (a + b) ! = 3 a == b a == 1 Valor 1 0 0 0 1 Interpretación cierto falso falso falso cierto

< <= == !=

43

Operadores lógicos Actúan sobre operandos que son a su vez expresiones lógicas que se interpretan como: • cierto. cualquier valor distinto de 0 • falso. el valor 0 Tabla de verdad a b F V F V !a V V F F a && b F F F V a || b F V V V 44 OPERADOR DESCRIPCIÓN UNARIOS BINARIOS ! && || not and or F F V V .

Ejemplo && y || se evalúan de izquierda a derecha. Ejemplos: si a = 7 y b = 3 Valor 0 1 1 1 Interpretación falso cierto cierto cierto Expresión (a + b) < 10 !((a + b) < 10) (a ! = 2) || ((a +b) <= 10) (a > 4) && (b < 5) 45 . ! se evalúa de derecha a izquierda.

= (y = 5). m = m . m = m + b. m += y . +.3. -. /. ^ para operaciones acumulativas es equivalente a m *= 5. %. m = m * 5. m += b.(y = 5). 46 . &. >>. <<.3. m = m + y . m . |.Operadores de asignación compuestos El operador de asignación se puede combinar con otros operadores como *.

++ % Operadores → ← → → → → → → → → → → ← ← → -> -(cast) * & sizeof .Precedencia Evaluación a igual nivel de prioridad Nivel de prioridad 1º 2º 3º 4º 5º 6º 7º 8º 9º 10º 11º 12º 13º 14º 15º () ! * + << < == & ^ | && || ?: operadores de asignación . 47 [] ~ / >> <= != > >= .

-v. los valores 2. v y t. t = .Ejercicios Indica cuáles de los siguientes identificadores no son correctos y por qué. a) e) contador dias2 b) CONTADOR c) _hola f) 2dias d) hola_ g) Suma_Total h) Suma-Total Sean x. 48 . ¿qué almacenarán después de ejecutar las siguientes sentencias? x++. 6 y 7. z. 5. u = x + y / 2. 4. u. v = x + (y *= 3) / 2. y = ++z. y. respectivamente. variables que contienen. 3.

fahrenheit.Ejemplo Programa que convierte grados Fahrenheit a grados centígrados. } 49 . scanf("%f". C = (5/9) * (F .32) #include <stdio.32).h> void main() { float centigrados. printf("%f grados fahrenheit = %f grados centigrados \n". printf("Introduzca una temperatura en grados fahrenheit: "). float fahrenheit. centigrados = 5.0/9 * (fahrenheit . &fahrenheit). centigrados).

ERRORES COMUNES Olvidar que el resultado de dividir dos enteros es entero Realizar división por cero Olvidar la prioridad de los operadores Errores en la conversión de tipos Confundir el operador de igualdad y el de asignación 50 .

Funciones 51 .

Ejemplos 52 . Declaración de funciones. Prototipos 4.Introducción a funciones Objetivos: Introducir al alumno en el diseño estructurado. Introducción al diseño estructurado. Concepto de función 2. Contenidos: 1. Presentar el concepto de función. Definición de funciones o Argumentos o Valor de retorno o Llamada a función 3. Mostrar la definición y declaración de funciones en C.

Todo programa C consta de una o más funciones. Permite dividir un programa en componentes más reutilización pequeños. Una de estas funciones se debe llamar main() Todo programa comienza su ejecución en la función main() El uso de funciones permite la descomposición y desarrollo modular.Introducción Una función es un segmento de programa que realiza una determinada tarea. 53 .

return(expresion). . tipoN argN) { /* CUERPO DE LA FUNCION */ } Los argumentos se denominan parámetros formales. En C no se pueden anidar funciones 54 ....Definición de una función tipo nombre_func (tipo1 arg1. La función devuelve un valor de tipo de dato tipo Si se omite tipo se considera que devuelve un int Si no devuelve ningún tipo ⇒ void Si no tiene argumentos ⇒ void void explicacion(void) Entre llaves se encuentra el cuerpo de la función (igual que main()). La sentencia return finaliza la ejecución y devuelve un valor a la función que realizó la llamada.

Permite la comprobación de errores entre las llamadas a una función y la definición de la función correspondiente.. 55 .Declaración de funciones: prototipos No es obligatorio pero si aconsejable. tipo nombre_func (tipo1 arg1... tipoN argN). .

Parámetros reales: los que se pasan en la llamada a la función. Deben ser del mismo tipo de datos que el argumento formal correspondiente.varN). respetando el orden de la declaración. Variables simples. En una llamada habrá un argumento real por cada argumento formal. 56 .…. Expresiones complejas. Los parámetros reales pueden ser: Constantes.var2. Parámetros formales: los que aparecen en la definición de la función.Llamadas a funciones Para llamar a una función se especifica su nombre y la lista de argumentos sin poner el tipo de dato. Cuando se pasa un valor a una función se copia el argumento real en el argumento formal. nombre_func (var1.

Como las variables locales a una función (y los parámetros formales lo son) se crean al entrar a la función y se destruyen al salir de ella. 57 . La función opera internamente con estos últimos. cualquier cambio realizado por la función en los parámetros formales no tiene ningún efecto sobre los argumentos.Paso de parámetros por valor En las llamadas por valor se hace una copia del valor del argumento en el parámetro formal.

58 .Ejemplo Programa que calcula el máximo de dos números.

return(prod).h> float potencia (float x. int y) /* definición */ { int i. int y).y).Ejemplo: Función que calcula x elevado a y (con y entero) #include <math. } 59 . /* prototipo */ float potencia (float x. float prod = 1. prod = pow(x.

n). else printf("%d no es cuadrado perfecto. void main() { int n. } 60 .\n". perfecto = cuadrado_perfecto(n). #include <stdio. n). if (perfecto) printf("%d es cuadrado perfecto. &n).Ejemplo 3 Programa que indica si un número es cuadrado perfecto. int cuadrado_perfecto(int x). scanf("%d". explicacion().h> #define TRUE 1 #define FALSE 0 void explicacion(void).h> #include <math. perfecto.\n".

Ejemplo 3 . /* cuadrado perfecto */ else perfecto = FALSE. printf("Introduzca un numero: ). /* no es cuadrado perfecto */ return(perfecto). int perfecto. printf("es cuadrado perfecto \n"). } int cuadrado_perfecto(int x) { int raiz. } 61 .Continuación void explicacion(void) { printf("Este programa dice si un numero "). raiz = (int) sqrt(x). if (x == raiz * raiz) perfecto = TRUE.

…... tipo inN.. tipo *out1. 62 .Paso de parámetros por referencia Hasta ahora las funciones solo devolvían un valor. &out1.. &outN). …tipo *outN) { /* CUERPO DE LA FUNCION */ } La llamada a la función nombre_func (in1. ... inN. pero ¿qué pasa si tienen que devolver más? En este caso. se requiere pasar parámetros por referencia La declaración de una función en este caso sería void nombreFunc (tipo in1. .

63 . Aunque en C todas las llamadas a funciones se hacen por valor.Paso de parámetros por referencia (II) En este tipo de llamadas los argumentos contienen direcciones de variables. En las llamadas por referencia cualquier cambio en la función tiene efecto sobre la variable cuya dirección se pasó en el argumento. mediante el operador *. Dentro de la función la dirección se utiliza para acceder al argumento real. No hay un proceso de creación/destrucción de esa dirección. Mediante & podemos pasar direcciones de variables en lugar de valores. y trabajar internamente en la función con los contenidos. pueden simularse llamadas por referencia utilizando los operadores & (dirección) y * (en la dirección).

printf("es cuadrado perfecto \n"). } void main() { int n. …….. explicacion(&n). perfecto = cuadrado_perfecto(n). perfecto. } 64 .Ejemplo 3 – con parámetros por referencia void explicacion ( int *numero) { printf("Este programa dice si un numero "). printf("Introduzca un numero: ). *&n). scanf("%d".

Ejercicio 4 Programa que calcula la hipotenusa de un triángulo rectángulo. Leer a y b ⇒ función leer 2. 65 . h = √(a2 + b2) Pasos a seguir: 1. Imprimir el valor de h ⇒ usar printf(). Calcular h según la fórmula dada ⇒ definimos una función hipotenusa 3.

leer (&a. b. } . *&a. float *h) { *h = sqrt(pow(a. h. 2)). float b.2) + pow(b.h> #include <math. h). *&b). hipotenusa(a. float *b) { printf("Dame valores a y b:\n").&b). scanf("%f %f".b. } void leer (float *a. printf("La hipotenusa es %f\n".Solución #include <stdio.h> void hipotenusa(float a. } 66 void main() { float a.&h).

Recapitulación Antes de escribir un programa: Leerlo detenidamente Hacer pseudocódigo o diagrama de flujo Decidir división en funciones Determinar parámetros de entrada y salida Desde main() invocar a las funciones 67 .

Sentencias de control 68 .

Estructuras de control Objetivos: Introducir los tres tipos básicos de sentencias de control: secuencia. Contenidos: 1. Tipos de estructuras 2. selección e iteración.else o Instrucción switch 3. Instrucción break 69 . Explicar la sintaxis y la semántica de las sentencias de control dedicadas a definir estructuras de selección. Estructuras condicionales o Instrucción if .

Tipos de estructuras Secuencia: ejecución sucesiva de dos o más operaciones. Selección: se realiza una u otra operación. Iteración: repetición de una operación mientras se cumpla una condición. dependiendo de una condición. 70 .

71 .If . o bien if (expresión) sentencia.else if (expresión) sentencia. else sentencia.

numero).h> main() { int numero. scanf("%d". #include <stdio.\n". if ((numero % 2) == 0) printf("El numero %d es par. else printf("El numero %d es impar. } 72 . numero).Ejemplo if .\n". &numero).else Programa que lee un número y dice si es par o impar. /* Leer el numero */ printf("Introduzca un numero: ").

} else { y=200.Operador condicional Se utiliza para sentencias if-else simples y=(x>9 ? 100 : 200). } LO MISMO 73 . if (x > 9) { y=100.

default: sentencia.. case cte2: sentencia. break. . break.switch Tipo entero o letra switch (variable) { case cte1: sentencia... } 74 . ..

letra). case 'u': case 'U': printf("Vocal %c\n". letra). scanf("%c". switch(letra) { case 'a': case 'A': printf("Vocal %c\n". break. break. case 'e': case 'E': printf("Vocal %c\n". printf("Introduzca una letra: "). case 'o': case 'O': printf("Vocal %c\n". letra). } } 75 . letra). break. break. default: printf("Consonante %c\n".Ejemplo switch #include <stdio. letra). case 'i': case 'I': printf("Vocal %c\n". &letra).h> void main() { char letra. break. letra).

while 2.Bucles Objetivos: Explicar la sintaxis y la semántica de las sentencias de control dedicadas a definir estructuras de iteración. Instrucciones break y continue 3. Contenidos: 1. Bucles anidados 76 . Instrucción while c. Instrucción for b. Mostrar patrones habituales de concatenación de sentencias de control con vistas a su utilización en el seno de un programa real. Bucles a. Instrucción do .

incremento) sentencia.Instrucción for for (inicialización. El bucle se repite mientras condición no sea cero (falso). Si sentencia es compuesta se encierra entre { } incialización e incremento se pueden omitir. 77 . Incremento: se utiliza para modificar el valor del parámetro. Inicialización: se inicializa algún parámetro que controla la repetición del bucle. Condición: es una condición que debe ser cierta para que se ejecute sentencia. Si se omite condición se asumirá el valor permanente de 1 (cierto) y el bucle se ejecutará de forma indefinida. condición.

for (numero=0. numero <100.Ejemplo for Programa que imprime los 100 primeros números #include <stdio. numero++) printf("%d\n". } 78 .h> void main() { int numero. numero).

Instrucción while while (expresión) sentencia. Si la sentencia es compuesta se encierra entre { } 79 . Lo normal es que sentencia incluya algún elemento que altere el valor de expresión. Primero se evalúa expresión. sentencia se ejecutará mientras el valor de expresión sea verdadero (distinto de 0). proporcionando la condición de salida del bucle.

. suma).Ejemplo while lee un número N y calcula 1 + 2 + 3 + … + N #include <stdio.*/ } printf("1 + 2 +. &N).. /* equivalente a N-.+ N = %d\n".h> void main() { int N. scanf("%d". int suma = 0. N = N . } 80 . while (N > 0) { suma = suma + N.1. /* leer el numero N */ printf("N: ").

Lo normal es que sentencia incluya algún elemento que altere el valor de expresión. proporcionando la condición de salida del bucle. Si la sentencia es compuesta se encierra entre { } Para la mayoría de las aplicaciones es mejor y más natural comprobar la condición antes de ejecutar el bucle (while).do . 81 . while (expresión). sentencia siempre se ejecuta al menos una vez (diferente a while).while do sentencia. sentencia se ejecutará mientras el valor de expresión sea verdadero (distinto de 0).

numero). } while (numero != 0) } 82 . numero).\n". else printf("El numero %d es par. do { /* se lee el numero */ printf("Introduzca un numero: "). scanf("%d". El programa se repite mientras el número sea distinto de cero.Ejemplo do -while Programa que lee de forma repetida un número e indica si es par o impar. &numero).\n". if ((numero % 2) == 0) printf("El numero %d es par.h> void main() { int numero. #include <stdio.

suma. do { /* leer el numero N */ printf("Introduzca N: ").. } while (N > 0).Bucles anidados Los bucles se pueden anidar pero es importante estructurarlos de forma correcta. j. suma). &N).. for (j = 0. + N = %d\n". j++) /* bucle anidado */ suma = suma + j. scanf("%d".h> main() { int N. #include <stdio. printf("1 + 2 + . suma = 0. Ejemplo: Calcular 1 + 2 + …N mientras N sea distinto de 0. /* fin del bucle do */ } 83 . j <= N.

En caso de bucles anidados. 84 . Es necesaria en la sentencia switch para transferir el control fuera de la misma.Instrucción break Se utiliza para terminar la ejecución de bucles o salir de una sentencia switch. pero no fuera de las externas. No es aconsejable el uso de esta sentencia en bucles pues es contrario a la programación estructurada. el control se transfiere fuera de la sentencia más interna en la que se encuentre. Puede ser útil cuando se detectan errores o condiciones anormales.

scanf("%d". selecciono opcion %d\n" . no hace nada\n"). case 2: printf ("Adios \n").Mensaje pantalla \n"). } printf("Elija la opcion: "). scanf("%d". &opcion). opcion).h> void main() { int opcion. printf("Elija la opción: "). Intentelo de nuevo\n"). break.salir \n"). printf (" cualquier carácter. printf ("1 . while (opcion) { switch(opcion) { case 1: printf("Hola. } } 85 . printf ("2 . default: printf("Seleccion invalida. break. &opcion). return.Ej. #include <stdio.

fuerza un nuevo ciclo del bucle. saltándose cualquier sentencia posterior. while y do/while. 86 . Cuando se ejecuta.Sentencia continue Esta sentencia se utiliza en los bucles for.

h> void main () { int n. se ejecuta continue que fuerza una nueva evaluación de la condición de salida del bucle. positivos++.h> #include <conio. Si n es negativo o vale 0. } while (n != -99). int positivos = 0. printf ("\n Has tecleado %d números positivos". do { printf ("\n Teclea un número (-99 finaliza): "). positivos). if (n <= 0) continue. &n). } La sentencia positivos++ sólo se ejecuta cuando n es un número positivo.Ejemplo continue #include <stdio. 87 . scanf ("%d".

antes del ciclo En el while entre paréntesis Antes de cada Dentro del ciclo vuelta después de las instrucciones a repetir Después de cada vuelta Dentro del ciclo después de las instrucciones a repetir No do while En el while entre paréntesis no 88 . antes del ciclo Hay que ponerlo fuera.Tabla de comparativas Valores iniciales. para seguir repitiendo 2º campo Cuando se comprueba Cambios que hay que hacer ¿pueden quedar campos vacíos? si Antes de cada 3º campo vuelta while Hay que ponerlo fuera. operaciones previas for 1º campo Cond.

i<n . siendo x y n dos números que se introducen por teclado #include <stdio. } printf("El resultado es: %f\n".i. i++) { potencia=potencia * x. scanf("%d %d". } 89 . float potencia=1. &n). potencia). &x.Ejercicios Escriba un programa que calcule xn.x. printf("Dame x y n \n: ").h> void main() { int n. for (i=0.

i++ ) { if ((i%2)==0) par+=i. } printf("El resultado suma par: %d e impar: %d \n". *&a . impar). else impar+=i. } 90 .Escriba un programa que calcule e imprima la suma de los pares y de los impares comprendidos entre dos valores que se piden por teclado (x y n) #include <stdio.x. scanf("%d %d".n). } while (a>b). int n) { int i. } void main() { int n.h> void leer (int *a.&n). leer (&x. printf("Dame a y b \n: "). i<=n. par. calcula(x. for (i=x. int *b) { do{ printf("Solicito dos numeros a<b \n"). int par=0. impar=0. *&b). } void calcula (int x.

cuadrado (t)). } 91 . t = lee_numero (). } int lee_numero () { int n. } void main () { int t.h> mensaje () { printf ("\nTeclee un número (0 finaliza): "). return n. scanf ("%d". for (mensaje ().funciones y bucles #include <stdio. &n). } cuadrado (int x) { printf ("\nEl cuadrado es %d". x * x).Ejemplo .

Recursividad 92 .

Mostrar la capacidad de la recursión y las funciones recursivas. Contenidos: 1.Recursividad Objetivos: Repaso: paso de parámetros por valor y por referencia a una función.Paso de parámetros a una función 2.Recursividad 93 .

cualquier cambio realizado por la función en los parámetros formales no tiene ningún efecto sobre los argumentos.Paso de parámetros por valor En las llamadas por valor se hace una copia del valor del argumento en el parámetro formal. La función opera internamente con estos últimos. Como las variables locales a una función (y los parámetros formales lo son) se crean al entrar a la función y se destruyen al salir de ella. 94 .

Ejemplo 95 .

y trabajar internamente en la función con los contenidos. 96 . Aunque en C todas las llamadas a funciones se hacen por valor. Dentro de la función la dirección se utiliza para acceder al argumento real. En las llamadas por referencia cualquier cambio en la función tiene efecto sobre la variable cuya dirección se pasó en el argumento. No hay un proceso de creación/destrucción de esa dirección. pueden simularse llamadas por referencia utilizando los operadores & (dirección) y * (en la dirección). mediante el operador *. Mediante & podemos pasar direcciones de variables en lugar de valores.Paso de parámetros por referencia En este tipo de llamadas los argumentos contienen direcciones de variables.

printf("Despues x = %d.h> void funcion(int *a. *b = %d\n".Ejemplo #include <stdio. } void funcion(int *a. y = %d\n". printf("Dentro *a = %d. y). y punteros 97 . } x. x. printf("Antes x = %d. int y = 5. y = %d\n". *a. *b). return. funcion(&x. x. &y). int *b). *b = 0. /* prototipo */ main() { int x = 2. int *b) { *a = 0. y).

x. #include <stdio. *b = *a. printf("Despues x = %d. } void swap_ref (int *a. printf("Antes x = %d. y). *a = temp.Ejemplo Función que intercambia el valor de dos variables. y = %d\n". x. &y). } 98 . temp = *b. int y = 5. swap(&x. y). int *b).h> void swap_ref (int *a. int *b) { int temp. y = %d\n". /* prototipo */ void main() { int x = 2.

else return(n * factorial(n-1)).Recursividad Una función se llama a sí misma de forma repetida hasta que se cumpla alguna condición. Ejemplo: el factorial de un número: long int factorial(int n) { if (n <= 1) return(1). } 99 .

} Izquierda Centro Derecha 100 . void main() { int n.'I'. char temp). printf ("¿Cuántos discos?\n").'C').'D'. transferir(n.h> void transferir( int n. char hacia.Ejemplo “torres de Hanoi” #include <stdio. char desde. scanf("%d". printf ("Bienvenido a las torres de Hanoi \n"). &n).

temp. printf ("mover disco %d desde %c hasta %c\n". desde. char hacia. hacia). hacia. desde. temp. } 101 . hacia). } return. char desde.Ejemplo “torres de Hanoi” (y 2) void transferir(int n. transferir (n-1.desde). n. char temp) { /* transferir n discos de un pivote a otro*/ /* n = numero de discos desde = origen hacia = destino temp = almacenamiento temporal */ if (n>0) { transferir (n-1.

Arrays (listas y tablas) 102 .

Contenidos: 1. Inicialización de un array 3. Arrays multidimensionales 103 . Arrays o o o o Declaración Subíndices Almacenamiento en memoria Tamaño de los arrays 2. Array de caracteres y cadenas de texto 4. Mostrar la representación de datos mediante arrays unidimensionales y multidimensionales.Arrays (listas y tablas) Objetivos: Introducir el concepto de tipo de dato estructurado. Conocer la representación de cadenas de caracteres y las funciones de manipulación.

1} el compilador asume array de 2 elementos El procesamiento se debe hacer elemento a elemento 104 . float temperaturas[100].1} int numeros[]={0. int numeros[20]. el primero se referencia con el índice 0 y el último con el índice N-1 Inicialización int numeros[2]={0.Listas Conjunto de datos del mismo tipo a los que se da un nombre común y a los que se accede a través de un índice tipo_dato variable_lista[num_elementos]. En un vector de N elementos.

void nombreFuncion (int variable) en la llamada a la función nombreFuncion (variable_lista[posicion]) 105 .Listas ¿cómo se utilizan? Usar un elemento de la lista variable_lista[posicion]. Pasar a funciones en la declaración Empieza en 0 temperaturas[10].

tamaño) Pasar la lista a una función Sean de entrada o salida. Ojo. corchetes 106 . Podemos: Copiar una lista en otra memcpy (listadestino.Listas de números ¿cómo se utilizan? Usar toda la lista. no requieren * void nombreFuncion (int nombreLista[TAMAÑO]) nombreFuncion ( nombreLista ).listaorigen.

nombreLista ). Se debe declarar la lista dentro de un bloque Antes debe ser conocida la variable tamano La lista sólo es conocida dentro del bloque 107 . Podemos: Pasar la lista a una función de tamaño ajustado void nombreFuncion (int tamano. int nombreLista[tamano]) nombreFuncion ( tamano.Listas de números ¿cómo se utilizan? Usar toda la lista.

int vector_b[TAM_VECTOR]. escribir (vector_b). j < TAM_VECTOR. j. j).Ejemplo lista tamaño fijo #include <stdio. vector[j]). vector_b). j++) vector_b[j] = vector_a[j]. j++) { printf("Elemento %d: ". } 108 . j++) printf("El elemento %d es %d \n". for (j = 0. copiar (vector_a. } void escribir (int vector[TAM_VECTOR]) { int j. } } void copiar (int vector_a[TAM_VECTOR]. scanf("%d". &vector_a[j]). int vector_b[TAM_VECTOR]) { int j. } void main() { int vector_a[TAM_VECTOR].h> #define TAM_VECTOR 10 void leer (int vector_a[TAM_VECTOR]) { int j. j < TAM_VECTOR. for (j = 0. leer ( vector_a). /* variable utilizada como indice */ for (j = 0. j < TAM_VECTOR.

i++) { printf("%i\n". i< cuantos . float lista[cuantos]) { int i. &lista[i]). } } 109 . printf ("teclealos :\n"). i++) { scanf("%f".h> void leer (int cuantos. printf ("dame cuantos \t"). pintar (cuantos. scanf("%i". i< cuantos . { float lista[cuantos]. lista[i]). lista). leer(cuantos. for (i=0 .Ejemplo lista tamaño variable #include <stdio.lista). for (i=0 . &cuantos). } } void main() { int cuantos. float lista[cuantos]) { int i. } } void pintar(int cuantos.

lista). int *num2) return ((*num1)-(*num2)).comparar). sizeof(lista[0]. } } 110 .Ordenación elementos de lista #include <stdio.h> int comparar (int *num1. pintar (cuantos. } { void main() { int cuantos.cuantos. leer(cuantos. &cuantos). scanf("%i". qsort(lista. { float lista[cuantos].lista). printf ("dame cuantos \t").h> #include <stdlib.

printf("un double ocupa %d bytes\n". printf("un float ocupa %d bytes\n". sizeof(int)).La función sizeof() Devuelve el tamaño en bytes que ocupa un tipo o variable en memoria. printf("un int ocupa %d bytes\n". sizeof(float)). sizeof(char)). printf("un char ocupa %d bytes\n". printf(" cadena ocupa %d bytes\n". sizeof(cadena)). } 111 . #include <stdio. sizeof(double)).h> main() { char cadena[10].

Algoritmos de ordenación y búsqueda Transparencias en pdf aparte 112 .

y permite almacenar num_car-1 caracteres y el carácter nulo '\0' de terminación. mediante sentencias del tipo char cadena[ ] = "Esto es una cadena de caracteres". char frase[21]. es apta para almacenar 20 caracteres y el nulo. pues lo hace automáticamente el compilador. C permite la inicialización de cadenas de caracteres en la declaración. Se declara: char nombre[num_car]. Generalmente se utiliza tamaño por exceso. en la que no es necesario añadir el nulo final ni indicar el tamaño.Cadenas de caracteres Un caso particular de lista es la cadena de caracteres. no se suele preguntar al usuario cuántos caracteres va a introducir 113 .

palabra) scanf (“%[^\n]”. Igual que lista de números. Usar toda la lista. palabra) Copiar una lista de letras <string. frase) Escribir una lista de letras printf (“%s”. str_origen) 114 coge hasta espacio o fin de línea coge hasta fin de línea . Hay diferencias: Leer una lista de letras con una sola instrucción scanf (“%s”.h> strcpy (str_destino.Cadenas de caracteres ¿Cómo se utilizan? Usar un elemento de la lista.

biblioteca estándar string.h
char *strcat (char *cad1, const char *cad2) Concatena cad2 a cad1 devolviendo la dirección de cad1. Elimina el nulo de terminación de cad1 inicial. char *strcpy (char *cad1, const char *cad2) Copia la cadena cad2 en cad1, sobreescribiéndola. Devuelve la dirección de cad1. El tamaño de cad1 debe ser suficiente para albergar a cad2. int strlen (const char *cad) int isalnum (int ch) int isalpha (int ch) int isdigit (int ch) int islower (int ch) int isupper (int ch) int tolower (int ch) int toupper (int ch) Devuelve el número de caracteres que almacena cad (sin contar el nulo final). Devuelve 1 si ch es alfanumérico (letra del alfabeto o dígito) y 0 en caso contrario. Devuelve 1 si ch es una letra del alfabeto y 0 en caso contrario. Devuelve 1 si ch es un dígito del 0 al 9, y 0 en caso contrario. Devuelve 1 si ch es un letra minúscula y 0 en caso contrario. Devuelve 1 si ch es una letra mayúscula y 0 en caso contrario. Devuelve el carácter ch en minúscula. Si ch no es una letra mayúscula la función devuelve ch sin modificación. Devuelve el carácter ch en mayúscula. Si ch no es una letra minúscula la función devuelve ch sin modificación.
115

Ejemplo: lectura y escritura de cadenas de caracteres
#include <stdio.h> #define TAM_CADENA 80 main() { char cadena[TAM_CADENA]; printf("Introduzca una cadena: "); scanf("%s", cadena); printf("La cadena es %s\n", cadena); }

no requiere &

scanf deja de buscar cuando encuentra un blanco ⇒ si se introduce Hola a todos, solo se leerá Hola. No es necesario el operador de dirección (&) ya que cadena representa de forma automática la dirección de comienzo.
116

Ejemplo: lectura y escritura de cadenas de caracteres (y 2)
La función gets lee una línea completa hasta que encuentre el retorno de carro incluyendo los blancos. La función puts escribe una cadena de caracteres junto con un salto de línea.
#include <stdio.h> #define TAM_LINEA 80 main() { char linea[TAM_LINEA]; printf("Introduzca una linea: \n"); gets(linea); puts("La linea es"); puts(linea); } Son equivalentes: puts("La linea es:");

printf("La linea es: \n");

117

Ej.

Programa que lee una palabra y la escribe al revés

#include <stdio.h> #include <string.h> #define MAXLETRAS 20 void leer (char palabra[MAXLETRAS]) { printf ("\nTeclee una cadena de caracteres: "); scanf(“%s”, palabra); } void escribir (char palabra[MAXLETRAS]) { int primera=0, ultima=0, i; ultima=strlen(palabra)-1; for (i=ultima; i>=primera; i--) printf(“%c”,palabra[i]); } void main (void) { char palabra[MAXLETRAS]; leer(palabra); escribir(palabra); }

118

puts (cadena). } printf ("\nLa cadena tiene %d dígitos numéricos\n". } void main (void) { char frase[MAXLETRAS].h> #include <string. } void escribir (char cadena[MAXLETRAS]) { int i. escribir(frase). for (i = 0. Además cuenta cuántos caracteres son dígitos numéricos. contador).Ej.h> #define MAXLETRAS 100 void leer (char cadena [MAXLETRAS]) { printf ("\nTeclee una cadena de caracteres: "). contador=0. #include <stdio. i <= strlen (cadena). else if (isdigit (cadena[i])) contador++. gets (cadena). else if (islower (cadena[i])) cadena[i] = toupper (cadena[i]). i++) { if (isupper (cadena[i])) cadena[i] = tolower (cadena[i]). leer(frase). El programa siguiente hace uso de alguna de las funciones anteriores para examinar una cadena de caracteres y convertir las minúsculas a mayúsculas y viceversa. } 119 .

120 . La numeración comienza en 0... [expN]. Matrices o vectores de 2 dimensiones: int matriz[20][30].Vectores multidimensionales Un vector multidimensional se declara: tipo_dato vector[exp1] [exp2] . Generalmente se declaran por exceso. define una matriz de 20 filas por 30 columnas.

Tablas ¿Cómo se utilizan? Usar un elemento de la tabla tabla[fila][columna] Pasar un elemento a una función. llamada nombreFuncion (arg1.….. tipo variablesimple) Usar una columna de la tabla: NO SE PUEDE EN C 121 .. nombretabla[fila][columna]) declaración void nombreFuncion (tipo arg1..

clientes1. Usar una tabla completa Copiar memcpy(destino. tabla) 122 .….. tipo lista[COLUMNAS]) llamada nombreFuncion (arg1. sizeof(int)*filas*columnas) Parámetro de una función Declaración de función void nombreFuncion (tipo arg1.Tablas Usar un vector de la tabla como argumento a una función: tabla[fila] declaración void nombreFuncion (tipo arg1. nombretabla[fila]).…. tipo tabla[FILAS][COLUMNAS]) Llamada a una función nombreFuncion (arg1.…...tamaño) Ej: memcpy ( clientes2. origen.

columnas. tabla1[i][j]+tabla2[i][j]). tabla1). &columnas). &tabla[i][j]).j<columnas.h> Leer dos matrices de dimensiones indicadas por el usuario y escribir su suma void sumar(int filas. scanf("%i %i".columnas. int columnas.i++) { for (j=0.j. } } void leer(int filas. sumar(filas.j++) { printf("%f \t". tabla2). int columnas.i<filas. } } 123 . } printf("\n"). printf("dame tabla:\n"). printf("dame filas y columnas: \n"). { float tabla1[filas][columnas].Ejemplo #include <stdio. leer(filas. &filas.j.tabla1.i++) { for (j=0.columnas.j++) { scanf("%f". float tabla1[filas][columnas]. for (i=0. leer(filas. } } } void main() { int filas. acumulador=0. float tabla2[filas][columnas]) { int i. for (i=0.j<columnas.i<filas. tabla2). float tabla[filas][columnas]) { int i. tabla2[filas][columnas]. columnas.

0. for(i = 0. i++) for(j = 0.Ejemplo Función que calcula el producto de dos matrices cuadradas. j < DIM. k. j. j++) { c[i][j] = 0. k++) c[i][j] += a[i][k] * b[k][j]. for(k = 0. } } 124 . float b[DIM][DIM]. float c[DIM][DIM]) { int i. void multiplicar(float a[DIM][DIM]. i < DIM. k < DIM.

pal.i++) { leer(numpal.tabla[i]). } void calcular(int numpal.h> #define MAX 30 /*incluye el fin de línea*/ void main() { int numpal. char tabla[numpal][MAX]. tabla.i<numpal.h> #include <string. void leer(int numpal.i<numpal. } } printf(“la palabra buscada %s. calcular(numpal. pal). for (i=0.: Leer lista de palabras y contar el nº de veces que está una palabra que solicita el usuario #include <stdio. for (i=0.pal). scanf("%s". { scanf("%i". char pal[MAX]) printf("dame nº palabras: \n"). char tabla[numpal][MAX].i++) { if (strcmp(listapal[i]. suma).suma=0.Ej. printf("dame palabras:\n"). int columnas.pal)==0) { suma ++. &numpal). { char tabla[numpal][MAX]. } 125 . int columnas. } } printf("dame palabra a buscar:\n").pal). int i. aparece %d veces\”. char pal[MAX]) { int i. } scanf("%s". pal[MAX].tabla.

Estructuras y uniones 126 .

5. Estructuras o Concepto de campo o Declaración e inicialización 2. 4. Acceso a estructuras Declaración typedef Combinación de datos estructurados Campos variables con el uso de union 127 . Explicar la posibilidad de combinar tipos de datos estructurados. Contenidos: 1.Estructuras y uniones Objetivos: Conocer la posibilidad de definir tipos de datos estructurados con campos heterogéneos mediante el uso de estructuras. 3. Mostrar los tipos union.

Cada uno de los elementos de una estructura se denomina miembro. tipoDatoN miembro_N. Declaración de una estructura: struct nombre_estructura { tipoDato1 miembro_1. tipoDato2 miembro_2. . }. Los miembros pueden ser de cualquier tipo excepto void 128 . .Estructuras Es una estructura de datos compuesta de elementos individuales que pueden ser de distinto tipo.

cd2 = cd1. Declaración de una variable denominada cd1 de tipo struct CD. char artista[50]. 129 . struct cd1 CD. Se pueden copiar estructuras. int num_canciones.Ejemplo Declaración de una estructura denominada CD. struct CD { char titulo[100].cd2. Euros precio. int anio. pero NO comparar: struct CD cd1. }.

strcpy(cd1.Inicialización de una estructura Dos formas: En la declaración: struct CD { char titulo[100]. } cd1= {“Un sueño de verano”.num_canciones = 2.titulo. strcpy(cd1. En el programa: struct CD cd1.artista. int anio. “Un sueño de verano").1989. c1. 130 . char artista[50].anio = 1989. cd1. “Miguel Rios"). int num_canciones. Euros precio.10}.”Miguel Rios”.

anio. ayer-> anno). printf("%d: %d: %d\n". 131 .hoy. }. ayer->dia.dia.anno). struct fecha *ayer. mes. hoy. se utiliza el operador -> si la variable es de tipo puntero a estructura variable_estructura->miembro Ejemplo: imprimir la fecha de hoy struct fecha { int dia. hoy. printf("%d: %d: %d\n". se utiliza el operador .mes. Para hacer referencia a un miembro determinado.Acceso a una estructura Los miembros de una estructura se procesan individualmente.miembro O. si la variable es de tipo estructura variable_estructura. ayer-> mes. struct fecha hoy.

struct cuenta { int cuenta_no. }. }. int mes. int anno.Ejemplo #include <stdio. float saldo. struct fecha ultimo_pago. char nombre[80]. 132 .h> struct fecha { int dia.

c1. printf("Saldo %f \n". } 133 . c1.anno).ultimo_pago.ultimo_pago.ultimo_pago.mes = 5.nombre.saldo = 100000. strcpy(c1.Ejemplo (y 2) main() { struct cuenta c1.cuenta_no = 2.ultimo_pago.saldo). c1. c2. printf("Fecha de ultimo pago: %d:%d:%d \n". "Pepe").cuenta_no). Cuenta %d \n".dia. c2.ultimo_pago. printf("Nombre %s \n". c1. /* rellena la estructura c1 */ c1.nombre).ultimo_pago. c2.anno = 1997. c2. c2. /* asignacion de estructuras */ c2 = c1. c2.dia = 12. c2. printf("No.mes.

/* Comprobar si el registro existe. precio) e imprimirlas #include <stdio.. nombre.h> #include <string. /* Número de piezas. } registro_piezas. */ */ */ float precio_unitario. nro.. Caja N caja . char existe.h> #define NUMCAJAS 3 typedef struct { char pieza[20]. */ 134 .Combinación de datos estructurados: vector de estructuras Programa que permita introducir las piezas de un almacén (tipo. /* Precio de cada pieza. int cantidad. Caja 1 /* Tipo de pieza.

precio_unitario). */ printf("Nombre de la pieza => "). /* Indicar que el registro tiene datos. scanf("%d". */ printf("Numero de piezas => "). cajas[registro]. scanf("%f". /* Leer el precio de cada pieza. scanf("%s". */ printf("Precio de cada pieza => "). /* Leer el número de piezas. do { /* Leer el nombre de la pieza. V */ cajas[registro]. &cajas[registro]. &cajas[registro].main() { registro_piezas cajas[NUMCAJAS].pieza). int i. } while (registro < NUMCAJAS). registro ++.existe = 'V'. 135 .cantidad). int registro=0.

/* Imprimir la información. registro < NUMCAJAS.existe == 'V') { printf("La caja %d contiene:\n". registro + 1). */ } /*fin main*/ 136 . cajas[registro]. printf("Precio unitario => $%f\n". cajas[registro].pieza). printf("Cantidad => %d\n". } } /* Fin for.Cont. printf("Pieza => %s\n". cajas[registro].precio_unitario).cantidad). registro++) { if(cajas[registro]. */ for(registro = 0.

void imprime_x (float x) { printf ("el valor de x %f". el tiempo para copiar un estructura (paso por valor) es prohibitivo. Se pueden pasar miembros individuales y estructuras completas a una función.x). float y. por eso se aconseja pasarlo por referencia. } /*llamada a función*/ imprime_x (p1. Si la estructura es grande.Paso de estructuras a funciones Una función puede devolver una estructura. Paso de miembros individuales struct punto { float x. x). }. 137 .

f. imprimir_fecha(fecha_de_hoy).dia)). }. printf("Dia: ").mes). f. scanf("%d". printf("Mes: %d\n". printf("Anno: "). printf("Mes: "). f. #include <stdio.anno)). scanf("%d". int anno.h> struct fecha { int dia.dia). int mes. &(f.: leer y escribir una fecha. void imprimir_fecha(struct fecha f) { printf("Dia: %d\n". &(f. } struct fecha leer_fecha(void) { struct fecha f. } } main() { struct fecha fecha_de_hoy. return(f).mes)).anno). fecha_de_hoy = leer_fecha(). printf("Anno: %d\n". 138 . scanf("%d".Paso de estructuras a funciones por valor Ej. &(f. return.

scanf("%f". p. } void imprimir_punto(struct punto p) { printf("x = %f\n". leer_punto(&p1). &(p->y)).Paso de estructuras a funciones por referencia void leer_punto(struct punto *p). printf("y = %f\n". main() { struct punto p1.y). }. imprimir_punto(p1). } . void imprimir_punto(struct punto p). &(p->x)). } 139 void leer_punto(struct punto *p) { printf("x = "). struct punto { float x. float y. scanf("%f".x). p. printf("y = ").

Todos los miembros que componen la union comparten la misma zona de memoria → ahorro de memoria. tipoDato2 miembro_2. Una variable de tipo union sólo almacena el valor de uno de sus miembros. . 140 . }. .Uniones Una union contiene miembros cuyos tipos de datos pueden ser diferentes (igual que las estructuras). Su declaración es similar a las estructuras: union nombre_estructura { tipoDato1 miembro_1. tipoDatoN miembro_N.

scanf("%d". scanf("%f". main() { union numero num.Ejemplo #include <stdio. /* leer un entero e imprimirlo */ printf("Entero: "). num. &(num. }. float real.real)). num. /* leer un real e imprimirlo */ printf("Real: ").h> union numero { int entero. } 141 0 1 2 entero real 3 .real).h> #include <stdlib.entero)). printf("El entero es %f\n".entero). &(num. printf("El entero es %d\n".

char nombre[40]. struct PROFESOR { char nrp[16]. char cargo[21]. struct DATOS { char tipo.. struct PROFESOR pr.Combinación de datos estructurados: vector de estructuras y union struct ALUMNO { char grupo[15]. union AL_PR { struct ALUMNO al. char telefono[15]. union AL_PR ambos. int asignat. } personal[100]. 142 Persona 1 Persona n Persona . char direccion[40]. .. char repite. int edad. }. }. }.

El siguiente segmento de programa muestra los datos de la matriz personal.nrp). i++) { printf ("\nNombre: %s".nombre).al. printf ("\nRepite: %d". printf ("\nGrupo: %s".repite). printf ("\nEdad: %d". for (i = 0.asignat).ambos. i < 100. personal[i]. if (personal[i]. personal[i]. personal[i]. printf ("\nDirección: %s". printf ("\nN.al.tipo == 'A') { printf ("\nALUMNO").grupo). } else { printf ("\nPROFESOR").P. personal[i]. printf ("\nCargo: %s".ambos.pr. personal[i].direccion). personal[i].R. printf ("\nTeléfono: %s".al.ambos.pr.: %s".edad). personal[i].ambos. personal[i]. } } 143 . printf ("\nNº de Asignaturas: %d".telefono).cargo). personal[i].ambos.

144 . m2. . blanco.. Sus miembros son constantes de tipo int. rojo}.Tipos enumerados Un tipo enumerado es similar a las estructuras.. mN}. Ejemplo: enum color {negro.. Es útil definir nuevos literales para Asociar un nombre a un valor numérico Limitar los valores que puede tomar una variable entera Hacer el código más legible Definición: enum nombre {m1.

} } 145 . for(estado =rojo. case amarillo: printf(“Parar si no tienes vehículo encima\n"). verde}. main() { enum estado semaforo. break.Ejemplo #include <stdio. estado <=verde. sino multa\n"). break. estado ++) switch(estado ) { case rojo: printf(“Parar. amarillo.h> enum semaforo {rojo. break. case verde: printf(“Circular\n").

146 . int mes. letra c. } FECHA.Definición de tipos de datos (typedef) Permite dar nuevo nombre a tipos de datos que ya existen: typedef tipoDato nuevo_tipo. typedef struct{ int dia. Ejemplos: typedef char letra. FECHA a. int anio.

/* Error. else printf("f es falso\n"). boolean f=false.Combinación de typedef y enum Usando typedef y enum se pueden definir tipos que sólo pueden tomar ciertos valores Ej.. . tipo booleano en C typedef enum {false.... true} boolean. f=45. .. if(f) printf("f es verdadero\n").. no debería tomar ese valor */ 147 . .

Ficheros 148 .

cadenas de caracteres y con formato o Lectura/escritura de ficheros binarios o Acceso directo a información de archivos 149 . cerrar y gestionar ficheros. Capacitar al alumno a trabajar con ficheros de texto y binarios. Concepto de ficheros y sus tipos 2. Contenidos: 1.Ficheros Objetivos: Presentar el tipo de dato FILE y los tipos de fichero. Explicar las instrucciones para abrir. Operaciones con ficheros: o Abrir y cerrar ficheros o Control de errores y fin de fichero o Lectura/escritura de ficheros de texto: caracteres. Declaración de una variable tipo fichero 3.

Existen dos tipos de canales: Canales de texto: Son secuencias de caracteres. no hay conversiones. Este intermediario se llama canal o flujo (stream) y es un buffer independiente del dispositivo al que se conecte. Dependiendo del entorno puede haber conversiones de caracteres (LF ⇔ CR + LF)... cinta. A diferencia de los canales de texto.Canales y ficheros El sistema de E/S del ANSI C proporciona un intermediario entre el programa y el dispositivo al que se accede (pantalla. en los canales binarios la correspondencia de caracteres en el canal y en el dispositivo es 1 a 1. disco. es decir.). Esto hace que el número de caracteres escritos/leídos en un canal pueda no coincidir con el número de caracteres escritos/leídos en el dispositivo. Canales binarios: Son secuencias de bytes. 150 ..

También incluye funciones para realizar las operaciones de lectura/escritura así como para desasociar un canal de un archivo (operación de cierre). Por defecto la pantalla. Por defecto el teclado. Por defecto la pantalla. Un canal se asocia a un archivo cuando se abre o se crea éste para lo cual se utilizan funciones de la biblioteca stdio.Canales y ficheros ( y 2) Hay 3 canales que se abren siempre que comienza un programa C: stdin stdout stderr (ANSI) Canal estándar de entrada. (ANSI) Canal estándar de salida.h. (ANSI) Canal estándar de salida de errores. 151 .

se declara como: FILE *desc.Apertura de un archivo Para abrir un archivo: desc = fopen(nombre_archivo. y modo especifica la forma de apertura del archivo. el descriptor. el fichero no se pudo abrir. si fopen devuelve NULL. modo) donde desc. 152 .

se está abriendo el fichero en modo texto sólo para lectura Modo BINARIO: añadir letra b. w+ a+ Modo TEXTO: añadir letra t. perdiéndose el contenido anterior. Si existe. Si ya existe un fichero con este nombre. Si el fichero no existe fopen() devuelve un puntero nulo y se genera un error. Si el fichero existe. Si ya existe un fichero con este nombre. Ej: si modo es rt. Si no existe se crea uno nuevo. se abre apuntando al final del mismo. Crea un nuevo fichero para leer y escribir. Abre o crea un fichero para leer y añadir. Abre o crea un fichero para añadir.Parámetros para abrir un fichero DESCRIPCIÓN MODO r w a r+ Abre un fichero sólo para lectura. Crea un nuevo fichero para escritura. Abre un fichero para leer y escribir. Ej: modo es w+b se abrirá o creará un fichero en modo binario para lectura y escritura 153 . pueden realizarse sobre él operaciones de lectura y de escritura. Si el fichero ya existe se abre apuntando al final del mismo. Si no existe se crea un fichero nuevo. se sobreescribe. perdiéndose el contenido anterior. Sobre el archivo pueden realizarse operaciones de lectura y de escritura. se sobreescribe. Si el fichero no existe fopen() devuelve un puntero nulo y se genera un error.

se debe usar la función fclose() int fclose (FILE *canal). 154 .Cierre de un fichero Para cerrar un fichero y liberar el canal previamente asociado con fopen(). y distinto de 0 en caso de error. Esta función devuelve 0 si la operación de cierre ha tenido éxito.

“w"). } 155 .txt". if (desc == NULL) { printf("Error. } exit(0).Ejemplo #include <stdio. desc = fopen("ejemplo. } else { /* se procesa el archivo */ /* al final se cierra */ fclose(desc). no se puede abrir el archivo \n").h> main() { FILE *desc.

Esta función devuelve 0 si la última operación sobre el fichero se ha realizado con éxito. Para ello disponemos de la función ferror() int ferror (FILE *canal).Control de errores Cada vez que se realiza una operación de lectura o de escritura sobre un fichero debemos comprobar si se ha producido algún error. 156 .

Por ello. controlar la condición de fin de fichero. pues. debemos saber que cuando se intentan realizar lecturas más allá del fin de fichero. el indicador de posición del fichero se actualiza. 157 . examinar la condición de fin de fichero mediante la función feof() int feof (FILE *canal). Sin embargo en los canales binarios un dato puede tener el valor EOF sin ser la marca de fin de fichero. por ello. el carácter leído es siempre EOF.Final de fichero Cada vez que se realiza una operación de lectura sobre un fichero. Es necesario. Es aconsejable. Esta función devuelve un valor diferente de cero cuando se detecta el fin de fichero.

Usualmente tienen la extensión “txt”. Para abrir un archivo en modo texto se debe emplear el modificador “t” en el modo de apertura del archivo.Ficheros de texto Se trata de archivos cuyo contenidos son caracteres en formato ASCII. Existen dos formas de tratar ficheros de texto: Carácter a carácter (fgetc y fputc) Cadenas de caracteres (fgets y fputs) Con formato (fprintf y fscanf) 158 . son legibles y editables por cualquier editor de texto. por tanto.

Funciones de manejo carácter a carácter Lectura: int fgetc(FILE *fich) Lee un carácter del archivo (EOF si estamos al final del mismo) Escritura: int fputc(char c. FILE *fich) Escribe el carácter c en el archivo. 159 . Si es correcto devuelve el mismo carácter y si no EOF.

n++. buffer[t] = c. 160 . buffer). t++. t. “rt”). while (!feof(entrada)) { t = 0. do { c = fgetc(entrada). //fin de fichero o de línea strcpy(lineas[n]. FILE *entrada.Ejemplo Ejemplo que realiza la lectura de un archivo carácter a carácter empleando un buffer: char buffer[255]. c. } while (c!=EOF && c!=’\n’).txt”. lineas[100][80]. int n. entrada = fopen(“ejemplo. } fclose(salida).

FILE *fich) Lee n-1 caracteres o hasta carácter de fin de línea (que también se almacena en s). Si es correcto devuelve un valor no negativo y si no EOF. FILE *fich) Escribe la cadena s en el archivo. en caso contrario. Escritura: int fputs(char *s. la función devuelve un puntero a char. int n. 161 . Si no se produce error. devuelve un puntero nulo. No copia el carácter nulo ni añade el carácter de fin de línea.Funciones de manejo cadenas de caracteres Lectura: char *fgets(const char *s.

txt". "Error abriendo entrada. con creación si no existe. return(0). FILE *fsal. char car[120]. "r"). return(0).txt \n"). if (fsal == NULL) { fprintf(stderr. char * ret. fclose(fent). "w")./entrada.h> int main(void) { FILE *fent. } /* Apertura. int res = 0.Ejemplo #include <stdio. } 162 .txt \n"). "Error creando salida. del archivo de salida */ fsal = fopen(". /* Apertura del archivo de entrada */ fent = fopen(". if (fent == NULL) { fprintf(stderr.txt"./salida.

strlen(car)). fsal). } 163 . if (res == EOF) fprintf(stderr. } } while (ret != NULL). "Error al leer \n"). if ( car == NULL) fprintf(stderr. return(0). /* Cierre de los streams de entrada y de salida */ fclose(fent). else fprintf(stdin. car). "Longitud linea leida: %d \n". fent).Ejemplo (y 2) /* Bucle de lectura y escritura con líneas */ do { /* Lectura de la línea siguiente */ ret = fgets(car. fclose(fsal). /* Escritura de la línea */ if (ret != NULL) { res = fputs(car. 110. "Error al escribir %s \n".

…argN) Su uso es el mismo que scanf pero con la salvedad de que lee desde un archivo. arg1. Escritura: int fprintf(FILE *fich.Funciones de manejo con formato Lectura: int fscanf(FILE *fich. 164 .…argN) Su uso es igual al de printf pero con la salvedad de que escribe en un archivo en vez de en la pantalla.arg2. char *formato. arg1. char *formato. en vez desde el teclado.arg2.

165 .Ejemplo Veamos un ejemplo para escribir una cadena de caracteres en un fichero: char cadena[255]. “wt”). fclose(salida). FILE *salida.txt”. strcpy(cadena.”%s”. fprintf(salida. “Prueba de escritura”).cadena). … salida = fopen(“salida.

Generalmente se utilizan para leer estructuras 166 . por tanto NO son legibles ni editables. Para asegurarnos que la apertura de un archivo se hace en modo binario se debe emplear el modificador “b” en el modo de apertura del archivo. Si no ponemos nada se asume el modo binario por defecto.Ficheros binarios Son archivos cuyo contenido son caracteres en formato binario. Las funciones básicas de escritura y lectura asociadas a este modo son: fwrite y fread.

Escribir a fichero binario Escritura int fwrite(void *datos. *fich = puntero a FILE (archivo donde escribir). int tam. Parámetros: *ptr = puntero al origen de los datos. 167 . Devuelve: Número de elementos (no bytes) escritos en el archivo. int ndatos. FILE *fich). tam = tamaño de cada elemento. ndatos = número de elementos.

sizeof(int).”). int valor. n = fwrite(&ficha. 168 .”). int n. sizeof(TFicha). … archivo=fopen(“c:\archivo.”w”). if (n!=1) printf(“Error: escritura incompleta. Tficha ficha. n = fwrite(&valor. 1. archivo).Ejemplo FILE *archivo. archivo). 1.dat”. if (n!=1) printf(“Error: escritura incompleta.

ndatos = número de elementos. Parámetros: *ptr = puntero al destino de los datos. int tam. FILE *fich). *fich = puntero a FILE (archivo de donde leer). Devuelve el número de elementos (no bytes) leídos del archivo. tam = tamaño de cada elemento.Lectura de fichero binario Sintaxis: int fread(void *datos. 169 . int ndatos.

int nfichas. while (!feof(agenda)) { fread(&fichas[nfichas]. agenda = fopen(“agenda. agenda). nfichas ++. FILE *agenda. “rb”).Ejemplo TFicha fichas[100]. } fclose(agenda). sizeof(TFicha). 170 . nfichas =0.dat”. 1.

Ejemplo agenda El registro de ese archivo constará de los siguientes campos: Nombre Domicilio Población Provincia Teléfono 40 caracteres 40 caracteres 25 caracteres 15 caracteres 10 caracteres El programa crea el fichero llamado LISTIN.TEL con los datos suministrados por el usuario 171 .

char dom[41]. char tel[11]. "wb"))) { perror ("LISTIN. gets (var.Ejemplo #include <stdio. return. void main (void) { FILE *f. REG var. if (!(f = fopen ("LISTIN.TEL". } printf ("Nombre: "). 172 .nom). char pob[26]. char pro[16].h> typedef struct { char nom[41]. } REG.TEL").

nom). fwrite (&var. gets (var. } fclose (f).dom). printf ("\nTeléfono: ").pob). gets (var. getch (). printf ("\nPoblación: ").pro). } 173 .Ejemplo (y 2) while (var. } printf ("Nombre: ").nom[0]) { printf ("\nDomicilio: "). gets (var.tel). gets (var. if (ferror (f)) { puts ("No se ha almacenado la información"). gets (var. sizeof (var). f). printf ("\nProvincia: "). 1.

tel). REG var[4]. char tel[11]. } 174 . for (i = 0. var[i]. i < n. 4. int i.TEL". i++) printf ("\n%-41s %s".TEL"). n.Ejemplo: Lectura en bloques #include <stdio.. getch (). if (!(f = fopen ("LISTIN. var[i].nom. f). char pob[26]. exit (1).. } do { n = fread (var. } REG. } while (!feof (f)). puts ("\nPulse una tecla . char pro[16]. fclose (f).h> typedef struct { char nom[41]."). sizeof (REG). "rb"))) { perror ("LISTIN. char dom[41]. void main (void) { FILE *f.

En caso contrario devuelve un valor diferente de 0. después de usar fseek() debe ejecutarse una función de lectura o escritura. 175 . La función devuelve 0 cuando ha tenido éxito. Por ello. se realiza con la ayuda de la función fseek() que permite situar el indicador de posición del archivo en cualquier lugar del mismo. Esta función simplemente maneja el indicador de posición del fichero. Esta función sitúa el indicador de posición del fichero nbytes contados a partir de origen.Acceso directo El acceso directo a un archivo. pero no realiza ninguna operación de lectura o escritura. long nbytes. int fseek (FILE *canal. int origen).

Los valores posibles del parámetro origen y sus macros asociadas ORIGEN Principio del fichero Posición actual Fin del fichero VALOR 0 1 2 MACRO SEEK_SET SEEK_CUR SEEK_END 176 . int origen). long nbytes.Acceso directo (y 2) int fseek (FILE *canal.

if (!(f = fopen ("FRASE. gets (frase). 1. char frase[80]. caracter.h> #include <string. else puts ("Se sobrepasó el fin de fichero"). strlen (frase) + 1. &nbyte). else { caracter = getc (f). } fclose (f). scanf ("%d".TXT con una cadena de caracteres.TXT".Ejemplo: #include <stdio. return. nbyte. if (caracter != EOF) printf ("\nEl carácter es: %c". "w+t"))) { perror ("FRASE. SEEK_SET). if (st) puts ("Error de posicionamiento"). st. } printf ("Teclee frase: "). Posteriormente lee un carácter de la cadena cuya posición se teclea. printf ("\nLeer carácter nº: ").h> Se crea un archivo llamado FRASE.TXT"). fwrite (frase. int nbyte. void main (void) { FILE *f. st = fseek (f. f). caracter). } 177 .

scanf ("%d".h> typedef struct { char nombre[40]. void main (void) { FILE *f1. REGISTRO mireg. float altura. long int puntero. "r+b"))) { puts ("Error de apertura"). } REGISTRO. } printf ("Escribir registro nº: ").Ejemplo: #include <stdio. int num. int edad. 178 . programa escribe registros ayudándose de fseek(). &num). if (!(f1 = fopen ("REGISTRO.DAT". return.

(y2) while (num > 0) { getchar (). 1. gets (mireg.1) * sizeof (REGISTRO).altura). printf ("Nombre: "). scanf ("%f". else { fwrite (&mireg. f1).nombre). printf ("Altura: "). &mireg. puntero. scanf ("%d".Ejemplo: programa escribe registros ayudándose de fseek(). &mireg.edad). } fclose (f1). if (ferror (f1)) { puts ("ERROR de escritura"). } 179 . } } printf ("Escribir registro nº: "). puntero = (num . sizeof (mireg). printf ("Edad: "). getch (). &num). scanf ("%d". if (fseek (f1. SEEK_SET)) puts ("Error de posicionamiento").

Programación modular Tema 13 180 .

Variables estáticas 3.Tema 13 Objetivos: Explicar el ámbito de las variables del programa. 4. Contenidos: 1. Variables globales y locales 2. El preprocesador C: #include y #define. Familiarizar al alumno con la creación de programas modularizados y la creación de librerías de funciones propias. Bibliotecas de funciones 181 . Programas modulares 5.

char. El tipo de almacenamiento se refiere a su permanencia y a su ámbito. las variables pueden ser: Variables Variables Variables Variables automáticas. estáticas. de tipo registro. externas. . Variables globales. las variables pueden ser: Variables locales. Según el ámbito. ). . Según el tipo. . 182 .Ámbito de las variables y tipos de almacenamiento Existen dos formas de caracterizar una variable: Por su tipo de dato Por su tipo de almacenamiento El tipo de dato se refiere al tipo de información que representa la variable (int. El ámbito de una variable es la porción del programa en la cual se reconoce la variable.

/* variable global */ main() { int b = 2. #include <stdio. a. Pueden ser accedidas desde cualquier función. int a = 1000. c). c = %d \n". } void funcion1(void) { int c = 4. /* variable local */ printf("a = %d. return.Variables globales Se declaran fuera de las funciones y antes de su uso.h> void funcion1(void). printf("a = %d. } 183 . b). b = %d \n". a. /* variable local */ funcion1().

} 184 . a).Variables globales (y 2) Mantienen los valores que se les asignan en las funciones. #include <stdio. printf("Despues a = %d\n".h> void funcion1(void). a). int a=10. /* variable global */ main() { printf("Antes a = %d\n". } void funcion1(void) { a = 1000. funcion1(). Es mejor hacer uso de variables locales para evitar efectos secundarios o laterales. return.

#include <stdio. /* equivalente a int valor */ valor = 5.Variables locales Las variables locales que se definen en las funciones. valor).h> main() { auto int valor. Su ámbito es local. printf("El valor es %d\n". } 185 . Su vida se restringe al tiempo en el que esta activa la función. Se pueden especificar con la palabra reservada auto aunque no es necesario. Los parámetros formales se tratan como variables automáticas.

Su vida coincide con la del programa ⇒ retienen sus valores durante toda la vida del programa. #include <stdio. veces).Variables estáticas Su ámbito es local a la función. funcion().h> void funcion(void). main() { funcion(). } void funcion(void) { static int veces = 0. printf("Se ha llamado %d veces a funcion\n". funcion(). Se especifican con static. veces = veces + 1. } 186 .

for (j = 0. j). j < 10.Variables de tipo registro Informan al compilador que el programador desea que la variable se almacene en un lugar de rápido acceso. Se especifican con register #include <stdio. j++) printf("Contador = %d\n". } 187 .h> main() { register int j. Si no existen registros disponibles se almacenará en memoria. generalmente en registros.

En los demás se declara (extern) 188 . Se emplean cuando un programa consta de varios módulos. Hay que distinguir entre definición y declaración de variable externa. Una declaración no reserva espacio de almacenamiento ⇒ se especifica con extern.Variables de tipo externas Variables globales. En uno de ellos se define la variable. La definición se escribe de la misma forma que las variables normales y reserva espacio para la misma en memoria.

Se compila por separado: gcc -c -Wall main.o -o prog 189 .o.El ejecutable (prog) se genera: gcc main.Ejemplo Modulo principal (main.c .o aux.Se obtienen dos módulos objetos: main.h> extern int valor.o y aux. printf("Valor = %d\n". main() { funcion(). /* se declara */ void funcion(void). valor). } . .c) int valor.c) #include <stdio. /* se define la variable */ void funcion(void) { valor = 10.c gcc -c -Wall aux. } Modulo auxiliar (aux.

se pasará como argumento.Recomendaciones Evitar el uso de variables globales. Mantener las variables lo más locales que se pueda. 190 . Cuando se precise hacer accesible el valor de una variable a una función.

&x. y. max = maximo(x.h> #define maximo(a.b) ((a > b) ? a : b) main() { int x. int max. #include <stdio. printf("Introduzca dos numeros: "). } 191 . &y). /* uso de la macro */ printf("El maximo es %d\n".Macros Una macro es un identificador equivalente a una expresión. scanf("%d %d". sentencia o grupo de sentencias. max).y).

Macros (y 2) No puede haber blancos entre el identificador y el paréntesis izquierdo. Se repite el código en cada uso de la macro ⇒ mayor código objeto. El preprocesador sustituye todas las referencias a la macro que aparezcan dentro de un programa antes de realizar la compilación: No se produce llamada a función ⇒ mayor velocidad. 192 . Una macro no es una llamada a función.

Directiva #include
Indica al preprocesador que incluya un archivo fuente nom_fich. El formato es: #include "nom_fich" o bien, #include <nom_fich> El uso de comillas dobles " " o ángulos < > indica dónde debe buscar el preprocesador el fichero nom_fich.
• comillas dobles " " : en el directorio de trabajo o en el camino absoluto que se especifique en la sentencia include • ángulos < >: en los directorios donde se encuentran las bibliotecas que proporciona el compilador

193

Archivos de cabecera (.h)
Permiten modularizar el código y favorecer la ocultación de información. Puede contener:
Definiciones de macros #define MIL 1000 Declaraciones de variables extern int dia; Declaraciones de funciones extern void f(void); Otras directivas de inclusión #include “a.h” Comentarios Definiciones de tipos de dato (typedef)

Nunca debe tener:
Definiciones de variables int dia; Definiciones de funciones void f(void);
194

Compilación prog. varios módulos
preprocesador leyOhm.h prog_ppal.c leyOhm.h prog_ppal.c prog_ppal.o enlazador
Inclusión del archivo leyOhm.c

leyOhm.c

compilador

leyOhm.o

prog_ppal.exe
195

La biblioteca de funciones
LENGUAJE ARCHIVO DE CABECERA ALLOC.H DESCRIPCIÓN Define funciones de asignación dinámica de memoria

ANSI C C++

ASSERT.H BCD.H BIOS.H

Declara la macro de depuración assert Define la clase bcd Define funciones utilizadas en rutinas de ROM-BIOS

C++ C++ ANSI C

COMPLEX.H CONIO.H CTYPE.H DIR.H

Define las funciones matemáticas complejas Define varias funciones utilizadas en las llamadas a rutinas de E/S por consola en DOS Contiene información utilizada por las macros de conversión y clasificación de caracteres Contiene definiciones para trabajar con directorios.

DOS.H

Declara constantes y da las declaraciones necesarias para llamadas específicas del 8086 y del DOS Declara mnemónicos constantes para códigos de error Declara constantes simbólicas utilizadas en conexiones con la biblioteca de rutinas open() Contiene parámetros para rutinas de coma flotante

ANSI C

ERRNO.H FCNTL.H

ANSI.C

FLOAT.H

196

La biblioteca de funciones LENGUAJE ARCHIVO DE CABECERA FSTREAM.H Define los gestores de flujos de E/S de C++ y contiene macros para creación de gestores de parámetros Define rutinas básicas de flujo de E/S de C++ (v2.H Declaraciones para dar soporte a saltos no locales Parámetros utilizados en funciones que utilizan arhivos-compartidos ANSI C SIGNAL. exec() ANSI C SETJMP.H LIMITS.H DESCRIPCIÓN C++ C++ C++ Define los flujos de C++ que soportan E/S de archivos Contiene macros para declaraciones de clase genéricas Define prototipos para las funciones gráficas Declaraciones de rutinas de E/S tipo UNIX C++ C++ ANSI C ANSI C ANSI C IOMANIP.H Contiene estructuras y declaraciones para las funciones spawn().0) Parámetros y constantes sobre la capacidad del sistema Define funciones sobre el país e idioma Define prototipos para las funciones matemáticas Define las funciones de gestión de memoria PROCESS.H SHARE.H IO.H GRAPHICS.H Declara constantes y declaraciones para utilizarlos en funciones signal() y raise() 197 .H IOSTREAM.H MEM.H LOCALE.H MATH.H GENERIC.

H STREAM.H STDLIB.H TIME.H STDIOSTR.H SYS\STAT.H STRING.H STDIO.h Define algunas de las rutinas comúnmente utilizadas Define las clases de flujo de C++ para utilizarlas con arrays de bytes en memoria Define varias rutinas de manipulación de cadenas y de memoria Declara constantes simbólicas utilizadas para abrir y crear archivos SYS\TIMEB.H VALUES.H DESCRIPCIÓN Soporte para aceptar un número variable de argumentos Declara varios tipos de datos y macros de uso común Declara tipos y macros para E/S estándar Declara las clases de flujo para utilizar con estructuras del archivo stdio.H Define el tipo time_t Estructuras y prototipos para funciones de tiempo Declara constantes dependientes de la máquina 198 .H Define la función ftime() y la estructura timeb C++ ANSI C SYS\TYPES.H STDDEF.La biblioteca de funciones LENGUAJE ANSI C ANSI C ANSI C C++ ANSI C C++ ANSI C ARCHIVO DE CABECERA STDARG.

Punteros y arrays Tema 14 199 .

Inicialización de un array 4. Contenidos: 1. Array de caracteres y cadenas de texto 5. Arrays multidimensionales 200 .Punteros y arrays Objetivos: Introducir el concepto de puntero. Introducir el concepto de tipo de dato estructurado. Mostrar la representación de datos mediante arrays unidimensionales y multidimensionales. Conocer la representación de cadenas de caracteres y las funciones de manipulación. Arrays o o o o Declaración Subíndices Almacenamiento en memoria Tamaño de los arrays 3. Punteros o Declaración o Operadores 2.

la dirección de otra variable . Por ejemplo.Punteros Un puntero es una variable que contiene una dirección de memoria. 201 .

Por ejemplo: char *m. y tipo el tipo de variable a la que apunta. n y p son punteros que apuntan. a datos de tipo char. float *p. las variables m. int *n. siendo nombre el identificador de la variable puntero.Punteros (y 2) Las variables puntero se declaran de la siguiente forma: tipo *nombre. int y float. En estas declaraciones. respectivamente. 202 .

Punteros (y 3) Los operadores de punteros son: & * dirección de en la dirección de El operador * sólo se puede aplicar a punteros Las operaciones permitidas con punteros son: Asignación Incremento / Decremento Suma / Resta Comparación 203 .

El mismo efecto se consigue con la asignación directa entre punteros: p = &x. 204 .Asignación punteros Dadas las declaraciones float x. q = &x. float *p. *q. la forma de asignar a p y q la dirección de x es: p = &x. q = p. Ahora p y q almacenan la misma dirección de memoria: la de la variable x. No es correcta una sentencia como p = x.

px = &x. (&x) 1000 5 px=&x. 2 (&px) 3000 100 0 205 . printf("*px = %d\n". } 1 int x. y). /* asigna a px la direccion de x */ y = *px. /* asigna a y el contenido de la direccion almacenada en px */ printf("x = %d\n".h> main() { int x. printf("y = %d\n". *px). x=5.Ejemplo #include <stdio. /* variable entera */ int *px. int *px. /* variable puntero a entero */ x = 5. 3 (&x) 1200 5 y=*px. /* variable entera */ int y. int y. x).

float *p1. float n2. float *p2. n2 = *p2. ¿Cuánto vale n1 y n2? 206 . p2 = p1.Ejercicio Dado el siguiente fragmento de código: float n1.0. n1 = *p1 + *p2. p1 = &n1. n1 = 4.

Incremento / Decremento
Los operadores ++ y -- actúan de modo diferente según el tipo apuntado por el puntero. Si p es un puntero a caracteres (char *p) la operación p++ incrementa el valor de p en 1. Si embargo, si p es un puntero a enteros (int *p), la misma operación p++ incrementa el valor de p en 2 para que apunte al siguiente elemento, pues el tipo int ocupa dos bytes. Del mismo modo, para el tipo float la operación p++ incrementa el valor de p en 4. Lo dicho para el operador ++ se cumple exactamente igual, pero decrementando, para el operador --.
207

Suma / Resta
Ocurre exactamente lo mismo que con las operaciones de incremento y decremento. Si p es un puntero, la operación p = p + 5; hace que p apunte 5 elementos más allá del actual. Si p estaba definido como un puntero a caracteres, se incrementará su valor en 5, pero si estaba definido como un puntero a enteros, se incrementará en 10.

208

Comparación
Pueden compararse punteros del mismo modo que cualquier otra variable, teniendo siempre presente que se comparan direcciones y NO contenidos. int *p, *q; if (p == q) puts ("p y q apuntan a la misma posición de memoria");

209

Puntero NULL
Cuando se asigna 0 a un puntero, este no apunta a ningún objeto o función. La constante simbólica NULL definida en stdio.h tiene el valor 0 y representa el puntero nulo. Es una buena técnica de programación asegurarse de que todos los punteros toman el valor NULL cuando no apuntan a ningún objeto o función. int *p = NULL; Para ver si un puntero no apunta a ningún objeto o función:
if (p == NULL) printf("El puntero es nulo\n"); else printf("El contenido de *p es\n", *p);
210

Arrays Conjunto de datos del mismo tipo a los que se da un nombre común y a los que se accede a través de un índice tipo_dato variable_array[num_elem]. int numeros[20].1} int numeros[]={0. float temperaturas[100]. En un vector de N elementos. el primero se referencia con el índice 0 y el último con el índice N-1 Inicialización int numeros[2]={0.1} el compilador asume array de 2 elementos El procesamiento se debe hacer elemento a elemento 211 .

} 212 . j++) vector_b[j] = vector_a[j]. } /* copiar el vector */ for (j = 0.h> #define TAM_VECTOR 10 main() { int vector_a[TAM_VECTOR]. j++) printf("El elemento %d es %d \n". /* escribir el vector b */ for (j = 0. j < TAM_VECTOR. &vector_a[j]). j < TAM_VECTOR. j < TAM_VECTOR. j++) { printf("Elemento %d: ". scanf("%d". int vector_b[TAM_VECTOR]. j). /* variable utilizada como indice */ /* leer el vector a */ for (j = 0. int j. j.Ejemplo arrays #include <stdio. vector_b[j]).

y permite almacenar num_car-1 caracteres y el carácter nulo '\0' de terminación. pues lo hace automáticamente el compilador. 213 . C permite la inicialización de cadenas de caracteres en la declaración. es apta para almacenar 20 caracteres y el nulo. en la que no es necesario añadir el nulo final ni indicar el tamaño. mediante sentencias del tipo char cadena[ ] = "Esto es una cadena de caracteres". Se declara: char nombre[num_car].Cadenas de caracteres Un caso particular de vector es la cadena de caracteres. char frase[21].

strcpy(cadena. "Hola"). 214 .Cadenas de caracteres Una forma de asignar un valor a una cadena es la siguiente: char cadena[10].

Devuelve 1 si ch es una letra mayúscula y 0 en caso contrario. Devuelve el carácter ch en minúscula. sobreescribiéndola. Elimina el nulo de terminación de cad1 inicial. int strlen (const char *cad) int isalnum (int ch) int isalpha (int ch) int isdigit (int ch) int islower (int ch) int isupper (int ch) int tolower (int ch) int toupper (int ch) Devuelve el número de caracteres que almacena cad (sin contar el nulo final). Devuelve la dirección de cad1. 215 .biblioteca estándar string. const char *cad2) Concatena cad2 a cad1 devolviendo la dirección de cad1. Devuelve 1 si ch es alfanumérico (letra del alfabeto o dígito) y 0 en caso contrario. const char *cad2) Copia la cadena cad2 en cad1. Devuelve 1 si ch es una letra del alfabeto y 0 en caso contrario. Si ch no es una letra minúscula la función devuelve ch sin modificación. Devuelve el carácter ch en mayúscula. El tamaño de cad1 debe ser suficiente para albergar a cad2. y 0 en caso contrario. Devuelve 1 si ch es un dígito del 0 al 9. char *strcpy (char *cad1.h char *strcat (char *cad1. Devuelve 1 si ch es un letra minúscula y 0 en caso contrario. Si ch no es una letra mayúscula la función devuelve ch sin modificación.

cadena). printf("La cadena es %s\n". 216 . cadena). solo se leerá Hola.Lectura y escritura de cadenas de caracteres #include <stdio. scanf("%s". printf("Introduzca una cadena: "). No es necesario el operador de dirección (&) ya que cadena representa de forma automática la dirección de comienzo. } scanf deja de buscar cuando encuentra un blanco ⇒ si se introduce Hola a todos.h> #define TAM_CADENA 80 main() { char cadena[TAM_CADENA].

printf("Introduzca una linea: \n"). es equivalente a: printf("La linea es: \n"). } puts("La linea es:"). puts(linea).Lectura y escritura de cadenas de caracteres (y 2) La función gets lee una línea completa hasta que encuentre el retorno de carro incluyendo los blancos. La función puts escribe una cadena de caracteres junto con un salto de línea. 217 . #include <stdio.h> #define TAM_LINEA 80 main() { char linea[TAM_LINEA]. gets(linea). puts("La linea es").

register int i. #include <stdio. clrscr (). else if (isdigit (cadena[i])) contador++.h> void main (void) { char cadena[100]. contador). int contador = 0.Ejemplo El programa siguiente hace uso de alguna de las funciones anteriores para examinar una cadena de caracteres y convertir las minúsculas a mayúsculas y viceversa.h> #include <conio. i <= strlen (cadena). Además cuenta cuántos caracteres son dígitos numéricos. printf ("\nTeclee una cadena de caracteres: "). } 218 .h> #include <ctype.h> #include <string. else if (islower (cadena[i])) cadena[i] = toupper (cadena[i]). for (i = 0. } printf ("\nLa cadena tiene %d dígitos numéricos\n". gets (cadena). puts (cadena). i++) { if (isupper (cadena[i])) cadena[i] = tolower (cadena[i]).

La función sizeof() Devuelve el tamaño en bytes que ocupa un tipo o variable en memoria. sizeof(double)). } 219 . sizeof(float)). sizeof(cadena)). #include <stdio. printf("un int ocupa %d bytes\n". sizeof(char)).h> main() { char cadena[10]. sizeof(int)). printf("un double ocupa %d bytes\n". printf(" cadena ocupa %d bytes\n". printf("un char ocupa %d bytes\n". printf("un float ocupa %d bytes\n".

El elemento de la fila i columna j es matriz[i][j] 220 .. [expN].Vectores multidimensionales Un vector multidimensional se declara: tipo_dato vector[exp1] [exp2] . define una matriz de 20 filas por 30 columnas.. Matrices o vectores de 2 dimensiones: int matriz[20][30].

float c[][DIMENSION]) { int i.Ejemplo Función que calcula el producto de dos matrices cuadradas. void multiplicar(float a[][DIMENSION]. } 221 . } return. for(i = 0. k++) c[i][j] += a[i][k] * b[k][j]. i++) for(j = 0. float b[][DIMENSION]. j. i < DIMENSION. for(k = 0.0. j++) { c[i][j] = 0. k. k < DIMENSION. j < DIMENSION.

Funciones y argumentos de tipo puntero Tema 16 222 .

Matrices como argumentos de funciones 2.Tema 16 Objetivos: Mostrar el paso de estructuras y arrays a funciones. Estructuras como argumentos de funciones 3. enfatizando la conveniencia de realizarlo por referencia. Contenidos: 1. Indicar cómo se pasan parámetros al programa principal. Argumentos de la función main() 223 .

media).h> #define MAX_TAM 4 void leer_vector(int vector[]). El tamaño no se especifica. El argumento formal correspondiente al vector se escribe con un par de corchetes cuadrados vacíos. El nombre representa la dirección del primer elemento del vector ⇒ los vectores se pasan por referencia y se pueden modificar en las funciones. leer_vector(v_numeros). int media_vector(int vector[]). main() { int v_numeros[MAX_TAM]. int media. printf("La media es %d\n". } 224 .Paso de vectores a funciones Un vector se pasa a una función especificando su nombre sin corchetes. Programa que calcula la media de los componentes de un vector. media = media_vector(v_numeros). #include <stdio.

} int media_vector(int vector[]) { int j. j++) media = media + vector[j]. } 225 . j++) { printf("Elemento %d: ". j<MAX_TAM. j<MAX_TAM. for(j=0. j). int media = 0. &vector[j]).Paso de vectores a funciones (y2) void leer_vector(int vector[]) { int j. scanf("%d". return(media/MAX_TAM). for(j=0. } return.

&x[i] y (x+i) representan la dirección del i-esimo elemento del vector x ⇒ x[i] y *(x+i) representan el contenido del i-esimo elemento del vector x. 226 .Punteros y vectores El nombre del vector representa la dirección del primer elemento del vector float vector[MAX_TAM]. vector == &vector[0] El nombre del vector es realmente un puntero al primer elemento del vector &x[0] &x[1] &x[2] &x[i] ⇒ ⇒ ⇒ ⇒ x (x+1) (x+2) (x+i) Es decir.

Si se quiere que float x se comporte como un vector ⇒ habrá que reservar memoria para los 10 elementos: x = (float *) malloc(10 * sizeof(float)). float x[10] define un vector compuesto por 10 números reales ⇒ reserva espacio para los elementos. float *x declara un puntero a float. malloc(nb) (stdlib.h) reserva un bloque de memoria de nb bytes. Para liberar la memoria asignada se utiliza free() (stdlib.Punteros y vectores (y 2) Cuando un vector se define como un puntero no se le pueden asignar valores ya que un puntero no reserva espacio en memoria. El uso de punteros permite definir vectores de forma dinámica. 227 .h) free(x).

int media. dimension). media = media_vector(v_numeros. main() { int *v_numeros. int media_vector(int vector[]. printf("Dimension del vector: "). printf("La media es %d\n". scanf("%d". leer_vector(v_numeros.h> void leer_vector(int vector[]. int dimension.h> #include <stdlib. &dimension). dimension). Programa que calcula la media de un vector de tamaño especificado de forma dinámica. media). free(v_numeros). int dim). #include <stdio. } 228 .Ejemplo. v_numeros = (int *) malloc(dimension*sizeof(int)). int dim).

int dim) { int j. } int media_vector(int vector[]. for(j=0. Programa que calcula la media de un vector de tamaño especificado de forma dinámica. j++) media = media + vector[j]. int media = 0. j<dim. return(media/dim). int dim) { int j. j).Ejemplo. (y 2) void leer_vector(int vector[]. } return. } 229 . scanf("%d". j<dim. for(j=0. j++) { printf("Elemento %d: ". &vector[j]).

char *fuente) { while (*fuente != '\0') { *destino = *fuente. } *destino = '\0'. } 230 .Vectores y cadenas de caracteres Una cadena de caracteres es un vector de caracteres ⇒ cada elemento del vector almacena un carácter. return. fuente++ . destino++. Ejemplo: Función que copia una cadena en otra: void copiar(char *destino.

} En una variable de tipo puntero a estructura los miembros se acceden con -> 231 . struct punto *punto_2. float y. }.0. main() { struct punto punto_1. printf("y = %f \n". punto_1. struct punto { float x. punto_1. printf("x = %f \n".0. punto_2->x).x = 2.y = 4.Punteros a estructuras Igual que con el resto de variables. punto_2->y). punto_2 = &punto_1.

printf("Anno: %d\n". printf("Mes: %d\n". por valor) Se pueden pasar miembros individuales y estructuras completas.Por valor o por referencia.Paso de estructuras a funciones (ej. return. Ejemplo: leer y escribir una fecha.anno).dia). } 232 . void imprimir_fecha(struct fecha f) { printf("Dia: %d\n". Una función puede devolver una estructura. f.mes). f. f.

printf("Dia: "). } 233 . scanf("%d". &(f. return(f). scanf("%d". scanf("%d". &(f.anno)). imprimir_fecha(fecha_de_hoy).Paso de estructuras a funciones (y 2) struct fecha leer_fecha(void) { struct fecha f. printf("Mes: "). fecha_de_hoy = leer_fecha(). printf("Anno: "). } main() { struct fecha fecha_de_hoy.dia)). &(f.mes)).

p1 = (struct punto *)malloc(sizeof(struct punto)). } 234 . leer_punto(p1). void imprimir_punto(struct punto p). por referencia) void leer_punto(struct punto *p). imprimir_punto(*p1). main() { struct punto *p1.Paso de estructuras a funciones (ej. free(p1).

&(p->x)). p.y). scanf("%f". p. &(p->y)).Paso de estructuras a funciones (ej. printf("y = "). } 235 . por referencia) (y 2) void leer_punto(struct punto *p) { printf("x = "). printf("y = %f\n".x). } void imprimir_punto(struct punto p) { printf("x = %f\n". scanf("%f".

Argumentos de la función main() Ejecutar un programa con parámetros de entrada (en línea de comandos) main (int argc. Cada uno de los elementos argv[i] es una cadena que almacena un argumento. argv[ ]: Matriz de cadenas de caracteres. char *argv[ ]) argc: Entero que indica el número de parámetros tecleados (incluye el nombre del programa). 236 .

. Los parámetros se identifican mediante argv de la siguiente manera: • argv[0] • argv[1] • argv[2] . cadena que almacena el primer parámetro.. vale cero (En realidad es un puntero nulo). puesto que se cuenta el nombre del programa.. • argv[argc] cadena que almacena el nombre del programa.. cadena que almacena el segundo parámetro. Para que los argumentos sean tratados como diferentes tienen que ir separados por uno o varios espacios blancos 237 . .Argumentos de la función main() La variable argc vale 1 como mínimo.

if (argc == 1) printf ("\nNo se han introducido parámetros").h> void main (int argc. printf ("\nNombre del programa: %s". #include <stdio. argv[i]). i. char *argv[ ]) { register int i. for (i = 1. i++) printf ("\n%d: %s". i < argc.Ejemplo Programa que lista los parámetros. } } 238 . else { printf ("\nParámetros en la línea de órdenes: "). si los hay. de la línea de órdenes. argv[0]).

You're Reading a Free Preview

Descarga
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->