Post on 26-Jan-2017
Sistemas Informáticos
Programación en C
Fede Pérez
TEMA - Lenguaje de Programación C
1. - Introducción
2. - Conceptos Básicos
2.1 – Tipos de Datos Base
2.2 – Funciones de Entrada/Salida
2.3 – Expresiones y Operadores
3. - Sentencias de Control
3.1 - Sentencias Selectivas
3.2 - Sentencias Repetitivas
4. - Funciones
5. – Datos Estructurados
5.1 – Arrays
5.2 – Cadenas de Caracteres
5.3 – Estructuras
6. – Ficheros
Índice
HistoriaNacimiento años 70 – laboratorios Bell Telephone – junto con UNIXUNIX – Ken Thompson y Dennis RitchieTransferencia PDP-7 ⇒ PDP-9, PDP-111970 (Ken Thompson) definición del lenguaje B (proviene del BCPL)1972 (Dennis Ritchie) definición del lenguaje C1973 (UNIX versión 5) 90% en C para PDP-11Años 80 ANSI C ⇒ estándar ISOMediados de los 80 C++ ⇒ estándar ISO 1998
Historia del Lenguaje C
CaracterísticasLenguaje de propósito generalPoco tipificadoCercano a la máquinaVariado juego de operadoresReemplaza ventajosamente al ensambladorRecursividad y reentrabilidadUtilización natural de las funciones primitivas del sistema de explotación
CarenciasManejo de tablas y cadenas de caracteresMultiprogramación, control de procesos, sincronizaciónEntrada/Salida, ficheros
Programoteca ⇒ Librería estándar
Solución
Características del Lenguaje C
Compilador: software que traduce a lenguaje de máquina el programa C contenido en uno o más ficheros fuente
Preprocesador: software que actúa siempre por delante del compilador facilitando su tarea y la del programador
Librería Estándar: funciones agrupadas en un conjunto de librerías de código objeto preprogramadas que se venden o se entregan junto con el compilador
Componentes del Lenguaje
Componentes del Lenguaje C
Ventajas de la Utilización de Funciones1. Modularización2. Ahorro de memoria y tiempo de desarrollo3. Independencia de datos y ocultamiento de información
ProgramaConjunto de instrucciones que se ejecutan –ordinariamente– de modo secuencial
FunciónDivisión un programa muy grande en una serie de módulos mucho más
pequeños y manejables. A estos módulos se les ha sólido denominar de distintas formas (subprogramas, subrutinas, procedimientos, funciones, etc.)
según los distintos lenguajes.
Programa PrincipalFunción concreta que juega el papel principal y que empieza a actuar
Esta función en el lenguaje C ha de llevar por titulo o nombre el de "main"
Estructura General de un Programa I
Funciones de Usuario - Definición de funciones
Programa Principal main()
Declaraciones Globales - Prototipos de funciones- Variables globales
Estructura General de un Programa II
Directivas de Preprocesador #include#define
#include <stdio.h>
main(){...f1(...);...
}
f1(...){...f2(...);...
}
f2(...){...
}
...
stdio.h principal.c
Ficheros Estándar Fichero Principal
Ficheros Fuente en C – Un Módulo
#include <stdio.h>
main(){...f1(...);f5(...);...
}f1(...){...f3(...);...
}
f2(...){...
}
#include ”aux3.c”
f3(...){...f4(...);...
}
f4(...){...f2(...);...
}
f5(...){...
}
...
stdio.h principal.c aux1.c
aux2.c
aux3.c
Ficheros Estándar Fichero Principal Ficheros Secundarios
Ficheros Fuente en C – Varios Módulos
Edito
r
principal.C
Com
pila
dor
.LIB Enla
zado
r(Li
nker
)
principal.EXE
Realización de un Programa en C – No Modular
Edito
r
.LIB
principal.C
auxiliar.C
objeto.O
libreria.LIBC
ompi
lado
r principal.O
auxiliar.O
Enla
zado
r(Li
nker
)
principal.EXE
Realización de un Programa en C – Modular
CaracterísticasSensible a mayúsculas y minúsculasIndentación y espacios en blancoSentencias (terminan en punto y coma “;” )Bloques (delimitados entre llaves “{}” )Elementos de un programa
Palabras reservadasFunciones de librería estándarVariables y funciones definidas por el programador
Características de Edición de un Programa C
Nombres de Ficheros y ExtensionesEl nombre de un fichero consta de dos partes: el nombre base y la extensión.
Extensiones más Comunes.c fichero fuente C.h fichero de cabeceras.o (.obj) fichero objeto resultante de la compilación de un fichero fuente. No es ejecutable.out (.exe) fichero ejecutable.lib librería estática.dll librerías dinámicas
Características de Edición de un Programa C
ErroresErrores de Sintaxis EdiciónErrores Lógicos Algoritmo incorrectoErrores de Regresión Solución de erroresErrores de Ejecución Situaciones imprevistas
Depuración de un Programa
Mensajes de ErrorError Fatal Sistema OperativoError de Sintaxis Compilador/enlazadorAdvertencias (warnings) Compilador/enlazador (no traba)
El Programa Principal
Declaraciones de la Función Mainmain()int main() void main() void main(void) int main(int argc, char *argv[])
Programa PrincipalFunción concreta que juega el papel principal y que empieza a actuar
Esta función en el lenguaje C ha de llevar por titulo o nombre el de "main"
argc representa el número total de argumentosargv es el puntero que señala una tabla en cuyos registros están
contenidos los argumentos bajo la forma de serie de caracteres
#include <stdio.h>
main(){printf(”Hola mundo!!\n”);
}
Edición (Fichero hola.c)
CompiladoEjecución
Primer Programa C
#include <stdio.h>
main(){printf(”Esto sí se ejecuta\n”);}
Ejemplo 1
1. Se llega al final del programa principal (función main)2. La función main realiza una llamada a la sentencia return()3. Cualquier función realiza una llamada a la función exit()
Modos de Finalización de un Programa
#include <stdio.h>
main(){printf(”Esto sí se ejecuta\n”);return(0);printf(”Esto no se ejecuta\n”);}
Ejemplo 2
#include <stdio.h>#include <stdlib.h> /* necesario para
exit() */main(){printf(”Esto sí se ejecuta\n”);exit(0);printf(”Esto no se ejecuta\n”);}
Ejemplo 3
Finalización de un Programa
Existen seis clases de componentes sintácticos o tokens en el vocabulario del lenguaje C:
1. Identificadores2. Palabras Reservadas3. Constantes4. Operadores5. Separadores6. Comentarios
Elementos Base
Elementos Base del Lenguaje C
1. Un identificador se forma con una secuencia de letras (minúsculas de la a a la z; mayúsculas de la A a la Z; y dígitos del 0 al 9).
2. El carácter subrayado o underscore (_) se considera como una letra más.
3. Un identificador no puede contener espacios en blanco, ni otros caracteres distintos de los citados, como por ejemplo (* , ; . : - + etc.)
4. El primer carácter de un identificador debe ser siempre una letra o un (_), es decir, no puede ser un dígito.
5. Se hace distinción entre letras mayúsculas y minúsculas. Así, Masa es considerado como un identificador distinto de masa y de MASA.
6. ANSI C permite definir identificadores de hasta 31 caracteres de longitud.
Reglas ANSI C
Los identificadores son nombres que permiten señalar, mencionar, hacer referencia a los diferentes objetos tratados por el programa. En particular a:
las variableslas funcioneslas constantes simbólicas
Definición
Identificadores I
EjemplosIdentificadores Correctos Identificadores Incorrectos I 8080 BUFFER 1er Direcci6n_Memoria Bus de datos cas_01 cas:01 Z80 CP/M
Identificadores II
Palabras clave necesarias para la sintaxis y semántica del lenguaje:
especificadores de tipo de objetoespecificadores de clase de memoriainstrucciones de controloperador simbólicoetiquetas de control
Definición
Lista de Palabras Reservadas
Tipo Clase Instrucción Operador Etiqueta
intcharshortlong
signedunsigned
floatdoublevoidstructunionenum
autoexternstatic
registervolatileconst
typedef
ifelse
whiledofor
switchbreak
continuegoto
return
sizeof casedefault
Palabras Reservadas
Valores que permanecen fijos durante la ejecución de un programa:
números enterosnúmeros realescaracteresserie de caracteresexpresiones con constantesconstantes simbólicas
Definición
1. Constantes numéricas. Son valores numéricos, enteros o de punto flotante. Se permiten también constantes octales (números enteros en base 8) y hexadecimales (base 16).
2. Constantes carácter. Cualquier carácter individual encerrado entre apóstrofos (tal como 'a', 'Y', ')', '+', etc.) es considerado por C como una constante carácter.
3. Cadenas de caracteres. Un conjunto de caracteres alfanuméricos encerrados entre comillas es también un tipo de constante del lenguaje C, como por ejemplo: "espacio", "Esto es una cadena de caracteres", etc.
4. Constantes simbólicas. Las constantes simbólicas tienen un nombre (identificador) y en esto se parecen a las variables. Sin embargo, no pueden cambiar de valor a lo largo de la ejecución del programa. En C se pueden definir mediante el preprocesador (#define) o por medio de la palabra clave const.
Tipos de Constantes
Constantes
Una expresión real puede darse en notación decimal (2.56) como científica (2.56E-4)En una expresión tipo long se añade una L al final (200L)Una expresión tipo carácter se define entre comillas simples (’A’)Una expresión de cadena de caracteres se define entre comillas dobles (”expresión”)
Base Decimal: Expresión en formato normal. Ejemplo: 230Base Octal: Comienza por cero. Ejemplo: 0346Base Hexadecimal: Comienza por cero-x. Ejemplo: 0xE6
Expresión de Números Enteros en Diferentes Bases
Tabla de Caracteres de Control
nueva líneatabulaci6nretrocesoretorno de carroavance de páginaantibarraap6strofecomillassonido de alertacarácter nuloocteto binario
NL o LFTAB o HTBSCRFF\‘“BELLNULLddd
\n\t\b\r\f\\\’\”\a\0\ddd
Es posible definir constantes asociadas a un identificador por medio de la directiva #defineEjemplo:#define PI 3.141593#define MAXIMO 255#define MAXINT 32767
Definición de Constantes Mediante Directiva de Preprocesador
Formato Básico de Expresiones Constantes
Expresiones Constantes
Los operadores pueden estar representados por uno o por dos caracteres especiales, por una palabra reservada, o por un especificador de tipo puesto entre paréntesis.
Definición
Operadores Monádicos o Unarios: preceden a un identificador, a una expresión o a una constanteOperadores Diádicos o Binarios: establecen la relación entre dos términos o expresionesOperadores Triádicos o Ternarios: ponen en relación tres términos o expresiones
Categorías de Operadores
Tabla de Operadores
Unarios Binarios Ternarios
-*&!~++--
(tipo)sizeof
+-*/%|&ˆ>><<.
==!=>>=<<=||&&
->
=+=-=*=/=%=|=&=ˆ=>>=<<=
? :
Operadores
Se puede considerar que los separadores están formados por:
delimitadoresespacios en blanco
Definición
Son signos especiales que permiten al compilador separar y reconocer las diferentes unidades sintácticas del lenguaje
Delimitadores
Principales Signos Delimitadores; termina una declaración de variable o una instrucci6n
, separa dos elementos consecutivos en una lista
( ) enmarca una lista de argumentos o de parámetros
[ ] enmarca la dimensi6n o el subíndice de una tabla
{ } enmarca un bloque de instrucciones o una lista de valores iniciales
Pueden estar constituidos por uno o varios caracteres "espacios" o "blancos"; de uno o varios caracteres de "TABulación", y del carácter de avance a la línea siguiente, denominado normalmente nueva línea (newline). Estos caracteres sirven para delimitar las diversas unidades sintácticas.
Espacios en Blanco
Separadores
Los llamados comentarios o memorandums, propiamente no forman parte de los elementos base del lenguaje, ya que son ignorados por el compilador y sólo reflejados en el listado fuente del programa.
Definición
1. Serie de caracteres que vaya encerrada entre los dos símbolos /* y */.Restricción: los comentarios no deben estar imbricados o anidados
2. ANSI C permite también otro tipo de comentarios, tomado del C++. Todo lo que va en cualquier línea del código detrás de la doble barra (//)
Tipos
#include <stdio.h>
main(){/* Comentario en varias
líneas */return(0); // comentario de línea}
Ejemplo
Comentarios
DefiniciónTres tipos fundamentales, que se expresan con la ayuda de palabras clave reservadas en el lenguaje:
1. Números enteros (int)2. Números reales (float)3. Caracteres (char)
ModificadoresCalificación para adaptarse mejor a los diversos tamaños de la palabra interna del microprocesador, con el fin de mejorar la precisión o de reducir el espacio ocupado en memoria :
1.short para un entero corto2.long para un entero largo3.unsigned para un entero sin signo4.double para un número real flotante de doble precisión
unsigned intsigned charlong intunsigned long int
Ejemplo
Tipos de Datos Básicos – Definición y Modificadores
Tipos de Datos Básicos – Notaciones
Tipos de datos fundamentales (notación completa)
char signed char unsigned char
signed short int signed int signed long int
Datos enteros
unsigned short int unsigned int unsigned long int
Datos reales float double long double
Tipos de datos fundamentales (notación abreviada)
char signed char unsigned char
short int long
Datos enteros
unsigned short unsigned unsigned long
Datos reales float double long double
Tipo Tamaño de palabra 16 bits 32 bits
char int short long unsigned float double
8 bits 16 bits 16 bits 32 bits 16 bits 32 bits 64 bits
8 bits 32 bits 16 bits 32 bits 32 bits 32 bits 64 bits
Operador sizeof()El operador sizeof se utiliza para determinar el número de bytes de un variable o un tipoint a;sizeof(a); sizeof(unsigned int);
Tipos de Datos Básicos – Tamaños y Rangos
Tipos de Datos Básicos – Rangos
Tipo Rango
char unsigned char
int short long
unsigned float double
long double
-128..127 0.255
-32768..32767 -32768..32767 -232..232-1 0..65535
3.4E-38..3.4E+38 1.7E-308..1.7E+308
3.4E-4932.. 1.1E+4932
Rangos para máquina de 16 bits
char ccar;unsigned int inum;float freal;
Declaración Simple
char ccar, cdat;unsigned int inum, icoorx;float freal, fnum;
Declaración Múltiple
char ccar = ’A’;unsigned int inum = 12432, icoorx = 5;float freal = 0.14, fnum = -4.2812e-4;
Declaración y Asignación
Tipos de Datos Básicos – Declaración de variables
Declaración<Clase de memoria> [tipo de dato] [[Identificador]<=Valor Inicial>, ...];
Las variable de tipo puntero representan direcciones donde almacenar valores. Es importante diferenciar entre puntero (espacio de memoria donde se almacena la dirección) y la propia dirección del puntero.
Se declaran con un asterisco delante del identificador de variable
main(){int *px, x = 3;
px = &x; // px apunta a x
*px = 5; // x vale 5}
DefiniciónSi px es un puntero (dirección): *px es el contenido del puntero (el valor almacenado en la dirección)
Si x es la variable: &x es la dirección de memoria donde está almacenada la variable
Operadores de Punteros
? ? ? ?px⇒35;0x⇒39;
?px
x0 0 3 3
Dirección Contenido Gráfica
0 0 0 39px⇒35;0x⇒39;
39 x0 0 3 3
0 0 0 39px⇒35;0x⇒39;
39 x0 0 5 5
px
px
int *px, x; /* px es un puntero a entero yx es un entero */
Ejemplo
La declaración de punteros genéricos a direcciones se asocian al tipo void
Declarar un variable que no sea puntero de tipo void no tiene sentido
El Tipo void
void *pv, v; /* La variable vestá mal declarada */
Ejemplo
Punteros
La declaración de las variables lleva asociado un ámbito, dentro del cual la variable es visible:
Ámbito Global: La variable es visible en todas las funciones del programa
Ámbito Local: La variable es visible dentro del bloque o función en el que encuentra definida. (Tiene prioridad sobre el ámbito global)
int x, y; // variables glogales
main(){float x, z; // variables locales
/* Aquí x, z son reales e y un entero */}
/* Aquí x e y son variables enteras *//* La variable z no existe fuera de la función
donde está definida */
Ejemplo
Ámbito de las Variables
A menudo es necesario convertir valores de variables o expresiones de un tipo a otro diferente. Hay dos tipos de conversiones:
Conversiones Implícitas (Promoción): Las realiza automáticamente el programa. Variables o expresiones de menor rango promocionan a rangos superiores.
Conversiones Explícitas (Casting): Conversión forzada por el programador. Se utiliza el tipo a convertir entre paréntesis.
int inum;float rnum;char ccar;
rnum = 65.0inum = (int)rnum; //inum vale 65ccar = (char)inum; //ccar vale 65 (código ASCII de ’A’)
Ejemplo de Casting
Definición
long double > double > float > unsigned long > long > unsigned int > int > char
Rangos de Conversiones Implícitas
Conversiones de Tipo – Casting
Código ASCII
American Standard Code Information Interchange
ASCII
Código ASCII – Caracteres imprimibles y no imprimibles
Código ASCII – Caracteres extendidos
Los operadores pueden estar representados por uno o por dos caracteres especiales, por una palabra reservada, o por un especificador de tipo puesto entre paréntesis.
Definición
Operadores Monádicos o Unarios: preceden a un identificador, a una expresión o a una constanteOperadores Diádicos o Binarios: establecen la relación entre dos términos o expresionesOperadores Triádicos o Ternarios: ponen en relación tres términos o expresiones
Categorías de Operadores
Tabla de OperadoresUnarios Binarios Ternarios
-*&!~++--
(tipo)sizeof
+-*/%|&ˆ>><<.
==!=>>=<<=||&&
->
=+=-=*=/=%=|=&=ˆ=>>=<<=
? :
Operadores aritméticosOperadores de manipulación de bitsOperadores de asignación
Tipos de OperadoresOperadores de incremento y decrementoOperadores de relaciónOperadores de dirección
Operadores
Operadores Aritméticos+ la adición
- la sustracción y el menos monádico
* la multiplicación
/ la división
% el residuo o resto de la división
#include <stdio.h>
main() /* comprobaciones de prioridad */ {int c = 2, d = 3, y = 4; printf(”c * d %%y = %d\n”, c * d % y);printf(”(c * d) %%y = %d\n”, (c * d) % y);printf(”c * (d %%y) = %d\n”, c * (d % y));}
Ejemplo
Depende de los operandos:
4 / 3 1 Entero4.0 / 3 1.3333 Real4/ 3.0 1.3333 Real4.0 / 3.0 1.3333 Real
División Entera vs Real
c * d % y = 2(c * d) % y = 2c * (d % y) = 6
Solución
El operador de asignación básico es el igual (=)Nota
Operadores Aritméticos
#include <stdio.h>
main(){long n = 0x12345678; // entero sobre 32 bits
printf(”%lx & 0X0F0F0F0F = %lx”, n, n & 0x0f0f0f0f);}
Ejemplo
Solución
Operadores de Manipulación de Bits& Y lógico inclusivo (AND)
| O lógico inclusivo (OR)
^ O lógico exclusivo (XOR)
˜ negación, complementos a uno
<< desplazamiento hacia la izquierda
>> desplazamiento hacia la derecha
12345678 & 0X0F0F0F0F = 02040608
Operadores de Manipulación de Bits
Operadores de Asignación= Asignación
+= Suma y asignación
–= Resta y asignación
*= Producto y asignación
/= División y asignación
%= Resto y asignación
|= OR y asignación
&= AND y asignación
^= XOR y y asignación
>>= Desplazamiento a izquierdas y asignación
<<= Desplazamiento a derechas y asignación
Operador Explicación Uso+= a = a + b a += b
*= a = a * b a *= b
-= a = a - b a -= b
/= a = a / b a /= b
%= a = a % b a %= b
Utilización de Operadores Combinados Asignación Múltiple
i = j = k = 0; /* primero k = 0 yluego j = 0 yluego i = 0 */
Asignación Anidada
car = 0x5f & (c = getchar()); // mayúscula
Operadores de Asignación
Utilización de Operadores Combinados
Operadores de Incremento y Decremento
++ Incremento de una unidad
-- Decremento de una unidad
Función Abreviatura Operador izda Operador dchax = x + 1 x += 1 ++x x++
x = x - 1 x -= 1 --x x--
a = 3; b = a++; // a = 4, b = 3a = 3; b = ++a; // a = 4, b = 4a = 3; b = a--; // a = 2, b = 3a = 3; b = --a; // a = 2, b = 2
Ejemplos
Operadores de Incremento y Decremento
Operadores de Comparación> Mayor que
>= Mayor o igual a
< Menor que
<= Menor o igual a
== Igual a, igualdad
!= Distinto de, desigualdadValores Booleanos
Verdadero 1
Falso 0
Operadores Lógicos! Negación monádica (NOT)
&& Intersección lógica (AND)
|| unión lógica (OR)
a = 3 > 7; // a vale 0 (falso)a = (3 > 2 || 5 == 4) && !1 // a vale 0 (falso)
(index < MAX - 1 && (c = getchar()) != '\n') && c != EOF)
Ejemplos
Operadores de Relación
Clasificación de los Operadores según sus Prioridades( ) [ ] -> .
! ˜ ++ -- - * & (type) sizeof
* / %
+ -
<< >>
< <= > >=
== !=
&
ˆ
|
&&
||
? :
= += -= *= /= %= >>= <<= &= |= ˆ=
,
Prioridad de Operadores
Las funciones de E/S en C no pertenecen a las palabras reservadas del lenguaje. Son funciones de la librería estándar cuyo formato se encuentra en el fichero de cabecera stdio.h.
Las funciones de E/S básicas recogen/insertan variables o constantes en los ficheros de E/S(stdin/stdout ⇒ teclado/monitor)
Definición
Funciones de E/S Básicas
TiposLas principales funciones de E/S se dividen por su propósito:
Funciones de E/S de caracteres: recoger/insertar un carácter del fichero de E/Sgetchar()/putchar()
Funciones de E/S de cadenas de caracteres: recoger/insertar una cadena de caracteres del fichero de E/Sgets()/puts()
Funciones de E/S con formato: leer/escribir con formato del fichero de E/Sscanf()/printf()
Leer un carácter desde techado: caracter = getchar();getchar()
Funciones de E/S Básicas – E/S de Caracteres
Presenta un carácter en pantalla: putchar(caracter);putchar()
#include <stdio.h> // necesario para utilizar funciones de E/S
main(){char ccar; // variable caracter
ccar = getchar(); // recoge carácter de tecladoputchar(ccar); // escribe carácter en monitorputchar(’A’); // escribe una A en monitorputchar(getchar()); // escribe lo leído}
Ejemplo de getchar/putchar
Leer una cadena de caracteres desde techado: gets(cadena);gets()
Funciones de E/S Básicas – E/S de Cadenas de Caracteres
Presenta una cadena de caracteres en pantalla: puts(cadena);puts()
#include <stdio.h> // necesario para utilizar funciones de E/S
main(){char cadena[100]; // variable cadena de caracteres
gets(cadena); // recoge la cadena de tecladoputs(cadena); // escribe la cadena en monitorputs(”Hola socio”); // escribe la cadena constante en monitorputs(gets(cadena)); // escribe lo leído}
Ejemplo de gets/puts
Escribir en pantalla con formato: printf (”formato”, arg1, arg2, ..., argn);
formato: cadena de formato de salida de datos.
argi : argumentos a incluir dentro del formato (pueden ser variables o expresiones).
printf()
Formato Expresión Resultado %d, %i entero Entero decimal con signo %u entero Entero decimal sin signo %o entero Entero octal sin signo %x, %X entero Entero hexadecimal sin signo %f real Real en notación punto %e, %E real Real en notación científica %g, %G real Real en notación más corta %c carácter Carácter %s string Cadena de caracteres %p puntero Dirección de memoria %ld, %lu, … entero largo Entero largo (distitos formatos)
Signo ”–”: ajuste a la izquierda.
número: longitud mínima en caracteres
punto decimal: precisión de la parte fraccionaria
Otras Opciones de Formato
#include <stdio.h>
#define PI 3.141593
main(){int inum = 3;char ccar = ’A’;
printf(”Hola mundo !!\n”);printf(”El número %8d\n”, inum);printf(”Un número %d y un carácter %c\n”,
inum + 2, ccar);printf(”El valor de PI es %6.4f\n”, PI);}
Ejemplo
Funciones de E/S Básicas – printf()
Leer de teclado con formato: scanf (”formato”, dir1, dir2, ..., dirn);
formato: cadena de formato de entrada de datos.
diri : argumentos a incluir dentro del formato (direcciones de variables donde se almacenaran valores leídos).
scanf()
#include <stdio.h>
main(){int inum, *pinum;float rnum;char ccar;
scanf(”%d”, &inum); // lee un entero y lo almacena en inumscanf(”%f %c”, &rnum, &ccar); // lee un rnum y ccarscanf(”%d”, pinum); // PELIGROSOpinum = &inum;scanf(”%d”, pinum); // CORRECTO, lee inum}
Ejemplo
Es importante destacar que los argumentos son direcciones. Cuando se utilizan variables base es necesario utilizar el operador de indirección &.
Nota
Funciones de E/S Básicas – scanf()
#include <stdio.h>
main(){char *pstr, str[100], cad[20];
scanf(”%s”, pstr); // PELIGROSOscanf(”%s”, str); // CORRECTO, lee str hasta blanco o fin de línea
pstr = str;scanf(”%s”, pstr); // CORRECTO, lee str hasta blanco o fin de línea
scanf(”%[^\n]”, str); // Lee toda la línea sobre str
scanf(”%s %*s %s”, cad, str); /* Lee cad hasta blanco, deja una palabra y lasiguiente palabra sobre str hasta blanco o fin de línea */
}
Ejemplo
Funciones de E/S Básicas – scanf() Lectura de strings
#include <stdio.h>
#define DIAS_ANIO 365
main(){char nombre[100];int dias, anios;
printf(”¿Cual es tu nombre? ”);scanf(”%s”, nombre);
printf(”¿Y tu edad? ”);scanf(”%d”, &anios);
dias = anios * DIAS_ANIO;
printf(”%s tienes aproximadamente %d días”, nombre, dias);}
Ejemplo
¿Cual es tu nombre? Jose¿Y tu edad? 20Jose tienes aproximadamente 7300 días
Solución
Funciones de E/S Básicas – printf()/scanf() Ejemplo
Las sentencias de control van a determinar la cadena de ejecución de las instrucciones.
Definición
Sentencias Condicionales o Selectivas: permiten la bifurcación de la cadena de ejecuciónSentencia ifSentencia if ... elseSentencia switch
Sentencias Repetitivas o Iterativas: permiten la repetición de un conjunto de instruccionesSentencia whileSentencia do ... whileSentencia for
Tipos de Sentencias de Control
Sentencias de Control
¿condición?
expresión(es)
falso
verdadero
#include <stdio.h>
#define MAXIMO 100
main(){int inum;
printf(”Dame un número -> ”);scanf(”%d”, &inum);
if(inum > MAXIMO){printf(”El número introducido es mayor que el máximo\n”);
}}
Ejemplo
if(condición){expresión(es)}
Ejecución
Diagrama de Flujo
Sentencia if
#include <stdio.h>
#define MAX_EDAD_JOVEN 25
main(){int edad;
printf(”Dime tu edad -> ");scanf(”%d”, &edad);
if(edad <= MAX_EDAD_JOVEN){printf(”Con %d años eres un chaval\n”, edad);
}else{printf(”Con %d años no estás para muchos trotes\n”, edad);
}}
Ejemplo
if(condición){expresión(es) if}else{expresión(es) else}
Ejecución
Diagrama de Flujo
¿condición?
expresión(es) if
falsoverdadero
expresión(es) else
Sentencia if...else
if(condición1){if(condición2){expresión(es) if condición 2
if(condición3){expresión(es) if condición 3
}}
else{expresión(es) else condición 2
}}
else{if(condición4){expresión(es) if condición 4
}else{expresión(es) else condición 4
}}
Ejemplo de Ejecución
Sentencia if...else Anidadas
#include <stdio.h>
main(){char letra;
printf(”Dame una inicial y te daré un animal -> ”);scanf(”%c”, &letra);
switch(letra){case ’a’:
printf(”antílope\n”);break;
case ’b’:printf(”buitre\n”);break;
case ’c’:printf(”cocodrilo\n”);break;
default:printf(”No se me ocurre…\n”);
}}
switch(variable_opción){case opcion_1:expresión(es) opcion_1;break;
case opcion_2:expresión(es) opcion_1;break;
...
case opcion_N:expresión(es) opcion_N;break;
default:expresión(es) default;
}
Ejecución
Ejemplo
Sentencia switch
Equivalencia a Sentencia Condicional if..else
#include <stdio.h>
main(){float num, abs;
printf(”Dame un número -> ”);scanf(”%f”, &num);
abs = num > 0 ? num : -num;
printf(”El valor absoluto de %6.4f es %6.4f\n”, num, abs);}
Ejemplo
Operador Condicional
? : Condicionalidad
si (expresión1) entonces expresión2 en_caso_contrario expresión3
expresión1 ? expresión2 : expresión3
if(num > 0){abs = num;
}else{abs = -num;
}equivalen
te
El Operador Condicional
#include <stdio.h>
#define TOPEMINIMO 250
main(){int total = 0, nuevas;
while(total < TOPEMINIMO){printf(”Tienes %d piezas acumuladas\n”, total);printf(”Cuantas piezas nuevas tienes -> ”);scanf(”%d”, &nuevas);total += nuevas;
}
printf(”Has acumulado %d piezas.\n”, total);}
Ejemplo
while(condición){expresión(es)}
EjecuciónDiagrama de Flujo
¿condición?
expresión(es)
falso
verdadero
Sentencia while
#include <stdio.h>
#define ESCAPE ’\x1b’ //escape = ASCII(27), octal(33)//hexadecimal(1b)
main(){char caracter;
do{printf(”Dame un caracter -> ”);caracter = getchar();
}while(caracter != ESCAPE)
}
Ejemplo
do{expresión(es)}while(condición)
EjecuciónDiagrama de Flujo
¿condición?
expresión(es)
falso
verdadero
Sentencia do...while
for(expresión inicial; condición; expresión bucle){expresión(es)
}
EjecuciónDiagrama de Flujo
¿condición?
expresión(es)
falso
verdaderoexpresión bucle
expresión inicial
#include <stdio.h>
main(){int i;
for(i = 0; i < 10; i++){printf(”Número -> %5d Cuadrado -> %5d\n”,
i, i * i);}
}
Ejemplo
Sentencia for
break: permiten la salida del bucle sin tener en cuenta la expresión que lo controlacontinue: permiten la vuelta a la cabecera del bucle sin ejecutar las sentencias restantes
#include <stdio.h>
main(){char car;
while((car = getchar()) != ’X’){if(car == ’\x1b’){break;
}printf(”Has introducido %c\n”, car);
}}
Ejemplo break
#include <stdio.h>
main(){char car;
while((car = getchar()) != ’X’ &&ccar != ’\x1b’)
{printf(”Has introducido %c\n”, car);
}}
Solución estructurada
#include <stdio.h>
main(){char car;
while((car = getchar()) != ’X’){if(car == ’\x1b’){continue;
}printf(”Has introducido %c\n”, car);
}}
Ejemplo continue
#include <stdio.h>
main(){char car;
while((car = getchar()) != ’X){if(car != ’\x1b’){printf(”Has introducido %c\n”, car);
}}
}
Solución estructurada
Sentencias break, continue
#include <stdio.h>
main(){int i;
for(i = 0;(i < 100) && (i % 17 != 0);i++)
{if(i % 2 != 0){printf(”Nuestro número es %d\n”, i);
}}
}
Solución estructurada#include <stdio.h>
main(){int i;
for(i = 0; i < 100; i++){if(i % 2 == 0){continue; // comienza la iteración
}
if(i % 17 == 0){break; // sale del bucle
}
printf(”Nuestro número es %d\n”, i);}
}
Ejemplo break/continue
Sentencias break, continue – Ejemplo
for(expresión inicial; condición1; expresión bucle){while(condición2){expresión(es) while condición 2
for(expresión inicial;condición3;expresión bucle)
{expresión(es) for condición 3
do{expresión(es) do..while condición 4
}while(condición4)
}}
expresión(es) for condición 1}
Ejemplo de Ejecución
Sentencias Repetitivas Anidadas
#include <stdio.h>
main(){int base, linea, columna;
printf(”Número de asteriscos en base -> ”);scanf(”%d”, &base);
linea = 0;
while(linea < base){for(columna = 0;
columna < linea;columna++)
{printf(”*”);
}
printf(”\n”);linea++;
}}
Ejemplo
#include <stdio.h>
main(){int base, linea, columna;
printf(”Número de asteriscos en base -> ”);scanf(”%d”, &base);
for(linea = 0; linea < base; linea++){for(columna = 0; columna < linea; columna++){printf(”*”);
}printf(”\n”);
}}
Ejemplo
Generar un triángulo de asteriscos, indicando el número de asteriscos en la base:
***************
Enunciado
Los dos ejemplos expuestos son equivalentesNota
Sentencias Repetitivas Anidadas – Ejemplo
SubrutinasProcedimientos: son módulos de programa que no ofrecen ningún tipo de valor asociado al nombre de la subrutina
Funciones: son módulos de programa que ofrecen un valor asociado al nombre de la subrutina
FunciónParte de código independiente, que puede ser llamada enviándole unos datos (o sin enviarle nada), para que realice una determinada tarea y/o proporcione unos resultados
Definición, Declaración y Llamada de una FunciónDefinición: cuerpo de la función en donde reside el código de la misma.
Declaración: presentación de la función donde se expresa su nombre, parámetros y tipo de valor devuelto.
Llamada: utilización de la función desde un punto de programa referenciada por su nombre, indicando el valor de los parámetros de trabajo y utilización del valor devuelto.
Parámetros Formales vs. Parámetros ActualesParámetros Formales: lista de declaraciones de variables, precedidas por su tipo correspondiente y separadas por comas (,) declarados en el encabezamiento de la función.
Parámetros Actuales: lista de constantes, variables y expresiones de un tipo determinado, que aparecen en la llamada a una función.
Funciones
Una función se invoca provocando valores a los argumentos de la llamada.
Los argumentos se pasan siempre por valor
El valor se devuelve por medio de la sentencia return()
Los procedimientos son funciones de tipo void
El control del número y tipo de argumentos es mínimo
Las funciones en C permiten recursividad y reentrabilidad
#include <stdio.h>
int factorial(int numero);
main(){int factor;
printf("Introduzca un número -> ");scanf("%d", &factor);
printf("El factorial de %d es %d\n",factor, factorial(factor));
}
Ejemplo
int factorial(int numero){int i, out;
for(i = 1, out = 1; i <= numero; i++)out *= i;
return out;}
definiciónllamada
declaración
Funciones – Uso de una Función
Definición de una FunciónConsiste en la definición del código necesario para que ésta realice las tareas para las que ha sido prevista. La definición de una función se debe realizar en alguno de los ficheros que forman parte del programa.
La primera línea recibe el nombre de encabezamiento (header) y el resto de la definición –encerrado entre llaves– es el cuerpo (body) de la función.
Formato General[clase] [tipo] nombre_funcion([lista de argumentos con tipos]){[declaración de variables y/o de otras funciones]codigo ejecutable // sentenciasreturn (expresión); // optativo}
clase: define el ámbito de la función, esto es, desde dónde puede ser llamada. La clase puede ser extern o static.
tipo: indica el tipo de valor devuelto por la función.
nombre: es el identificador que indica el nombre de la función.
lista de argumentos: secuencia de declaración de parámetros separados por comas y encerrados entre paréntesis. Son los llamados parámetros formales.
Funciones – Definición de una Función
Declaración de una FunciónToda función debe ser declarada antes de ser utilizada en la función o programa que realiza la llamada.
Formato General[clase] [tipo] nombre_funcion([lista de tipos de argumentos]);
Formas de Declarar una Función
Mediante una llamada a la función: Se supone int como tipo del valor de retorno, y el tipo de los argumentos actuales como tipo de los argumentos formales
Mediante una definición previa de la función
Mediante una declaración explícita, previa a la llamada
Ejemploint factorial(int numero);
int factorial(int);
int factorial();
Funciones – Declaración de una Función
Llamada de una FunciónLa llamada a una función se hace incluyendo su nombre en una expresión o sentencia del programa principal o de otra función. Este nombre puede ir seguido de una lista de argumentos separados por comas y encerrados entre paréntesis, los parámetros actuales.
Cuando se llama a una función se ejecuta el código correspondiente a la función hasta que se llega a una sentencia return o al final del cuerpo de la función, y entonces se devuelve el control al programa que realizó la llamada, junto con el valor de retorno si es que existe.
Formato Generalvariable = expresión([parámetros actuales]);
variable: especifica la variable en donde va a ser almacenado el valor devuelto por la función. La llamada puede prescindir del valor devuelto por la función.
expresión: especifica la dirección que referencia a la función. En general se corresponde con el nombre de la función.
parámetros actuales: lista de expresiones separadas por comas. Las expresiones son evaluadas, pasadas a la función y asignadas a los parámetros formales. El número de parámetros actuales coincide con el parámetros formales, a no ser que especifique un número variable de parámetros.
Funciones – Llamada de una Función
#include <stdio.h>
double valor_abs(double); /* declaración */
void main (void){double z, y;
y = -30.8;z = valor_abs(y) + y * y; /* llamada en
una expresión */
printf("El valor calculado es %g\n", z);}
double valor_abs(double x){if (x < 0.0)
return -x;else
return x;}
Ejemplo Cálculo de una expresión absoluta
#include <stdio.h>#include <math.h>
double logaritmo(float numero, int base);
void main (void){float numero;int base;
printf("Introduce un número -> ");scanf("%f", &numero);printf("Introduce la base -> ");scanf("%d", &base);
printf("El logaritmo de %lg es %lg\n",numero, logaritmo(numero, base));
}
double logaritmo(float numero, int base){return log(numero)/log(base);
}
Ejemplo Cálculo de un logaritmo
Funciones – Ejemplos
#include <stdio.h>
void permutar(double *, double *);
main(){double a=1.0, b=2.0;
printf("a = %lf, b = %lf\n", a, b);permutar(&a, &b);printf("a = %lf, b = %lf\n", a, b);
}
void permutar(double *x, double *y){double temp;
temp = *x;*x = *y;*y = temp;
}
Ejemplo Permutar dos Números
Paso por ReferenciaEl lenguaje C no tiene en si en paso por referencia. En su lugar se pasa por valor la dirección de la variable a modificar. Pero por correspondencia con los diferentes textos, llamaremos a este paso por dirección paso por referencia.
#include <stdio.h>
void permutar(double, double);
main(){double a=1.0, b=2.0;
printf("a = %lf, b = %lf\n", a, b);permutar(a, b);printf("a = %lf, b = %lf\n", a, b);
}
void permutar(double x, double y){double temp;
temp = x;x = y;y = temp;
}
Ejemplo Permutar dos Números
Incorrecto Correcto
a = 1.000000, b = 2.000000a = 1.000000, b = 2.000000
Solucionesa = 1.000000, b = 2.000000a = 2.000000, b = 1.000000
Funciones – Paso por Referencia
Argumentos de la Función mainargc: es una variable int que contiene el número de palabras que se teclean a continuación del nombre del programa cuando éste se ejecuta.
argv: es un vector de punteros a carácter que contiene las direcciones de la primera letra o carácter de dichas palabras.
#include <stdio.h>
int main(int argc, char *argv[]){int cont;
for (cont=0; cont<argc; cont++)printf("El argumento %d es: %s\n", cont, argv[cont]);
printf("\n");
return 0;}
Ejemplo Mostrar Argumentos de Entrada
Prototipo de la Función mainint main(int argc, char *argv[]);
Funciones – La Función main con Argumentos
La declaración de las variables lleva asociado un ámbito, dentro del cual la variable es visible:
Ámbito Global: Las variables son visibles en todas las funciones del programa. Se declaran al principio de módulo.
Ámbito Local: Las variables son visibles dentro del bloque o función en el que encuentra definida. (Tiene prioridad sobre el ámbito global)
Ámbito de las Variables
Permanente: Se crean al comienzo de programa y permanecen hasta el final.
Volátil: Su duraciones están unidas con las de las ejecuciones de los bloques en las que están definidas.
Duración de las Variables
Ámbito y Duración de Variables
Auto: Método de almacenamiento por defecto, se crean sobre la pila de programa. Se crean al comenzar a ejecutarse el bloque y dejan de existir cuando el bloque se termina de ejecutar. Sonvariables locales. No son inicializadas por defecto.
Extern: Se definen fuera de cualquier bloque o función. Son variables globales. Por defecto, son inicializadas a cero. Para utilizarlas en otros módulos deben ser declaradas como extern.
Static: Conservan su valor entre distintas ejecuciones del bloque en que están definidas. Por defecto, son inicializadas a cero. Las variables definidas como static extern son visibles sólo para las funciones y bloques comprendidos desde su definición hasta el fin del fichero. Una función puede también ser definida como static, y entonces sólo es visible para las funciones que están definidas después de dicha función y en el mismo fichero.
Register: Es un modo de recomendación para el compilador, para que –si es posible– ciertas variables sean almacenadas en los registros de la CPU y los cálculos con ellas sean más rápidos.
Métodos de Almacenamiento
Modo de Almacenamiento Palabra Reservada Duración Ámbito
Automático auto volátil local
Registro register volátil local
Estático static permanente local
Externo extern permanente global
Almacenamiento de Variables
#include <stdio.h>
int var_global = 1;
void test_static();
main(){int var_local;
for(var_local = 1; var_local <= 3; var_local++){printf(”Main: global = %d, local = %d\n”,
var_global++, var_local);test_static();
}}
void test_static(void){int var_local = 1;static int var_static = 1;
printf(”Función: global = %d, local = %d, estática = %d\n”,var_global++, var_local++, var_static++);
}
Ejemplo
Main: global = 1, local = 1Función: global = 2, local = 1, estática = 1Main: global = 3, local = 2Función: global = 4, local = 1, estática = 2Main: global = 5, local = 3Función: global = 6, local = 1, estática = 3
Solución
Almacenamiento de Variables – Ejemplo
DefiniciónPara definir los arrays es necesario indicar el tipo de datos se quiere almacenar en el array, el nombre del array y la cantidad de elementos
int numeros [30]; /* un array para guardar 30 números enteros */char alfabeto [26]; /* un array para guardar 26 caracteres */long largos [500]; /* un array para guardar 500 números enteros
tipo long */float temp_semana [7]; /* un array para guardar 7 números reales */
InicializaciónLos arrays se pueden inicializar directamente en la definición.
int numeros[3] = {2, 7, 11};float temp[7] = {12.3, 13.4, 11.7, 10.2, 9.1, 10.8, 11.0};char cadena[10] = {’A’, ’n’, ’o’, ’n’, ’i’, ’m’, ’o’, ’\0’};
Arrays – Definición e Inicialización
#include <stdio.h>
#define MESES 12
void main (void){int cont = 0;static int meses[MESES] = {3l,28,3l,30,31,30,3l,31,30,3l,30,31};for (cont = 0; cont < MESES; cont++){printf ( "el mes %2d tiene %2d días\n", cont + l, meses[cont]);
}}
Ejemploel mes 1 tiene 31 días.el mes 2 tiene 28 días.el mes 3 tiene 31 días.
...el mes 11 tiene 30 días.el mes 12 tiene 31 días.
Solución
IndexaciónPara identificar cada elemento de un array se utiliza un número denominado índice.El índice obligatoriamente debe ser un número entero.El valor del índice correspondiente al primer elemento es 0.
int a[6];a[0] = 23;a[2] = a[0] + 5;
for(i=0; i < 6; i++){printf(”%d”, a[i]);
}
23 28a[0] a[1] a[2] a[3] a[4] a[5]
a
Arrays – Indexación
DefiniciónEs posible declarar arrays de varias dimensiones. Por cada dimensión habrá un índice.Mientras que los arrays de una dimensión pueden asemejarse a vectores, los arrays de dos dimensiones se pueden asemejar a matrices.
foat matriz[10]10];
static float lluvia[4][12] ={
{10.2,4.1,12.2,2.4,7.7,6.8,7.0,8.7,11.5,8.3,4.7,9.2},{11.2,10.1,11.2,6.4,7.9,9.3,9.0,8.7,11.5,8.3,4.7,9.2},{13.2,8.6,12.3,3.4,7.8,9.8,8.0,8.7,11.5,8.3,4.7,9.2},{1.2,8.9,42.2,9.4,7.8,4.8,10.0,8.7,11.5,8.3,4.7,9.2},
};
static int tres_dimen[3][2][4] ={
{{1, 2, 3, 4},{5, 6, 7, 8}
},{{7, 9, 3, 2},{4, 6, 8, 3}
},{{7, 5, 6, 8},{0, 1, 9, 4}
}};
Arrays – Arrays Multidimensionales
DefiniciónUn puntero puede referenciar un array o elemento de un array.El nombre de un array es la dirección del mismo array.
int meses[12] ;meses == &meses[0];
#include <stdio.h>
void main (void){static int fechas [4] = {10, 20, 30, 40};int *entero_ptr;int i;
entero_ptr = fechas;
for (i = 0; i < 4; i++){printf ("fechas [%d] = %d, dirección: %lu\n",
i, *(entero_ptr + i), (entero_ptr + i));}
}
Ejemplo
#include <stdio.h>
void main (void){static int fechas [4] = {10, 20, 30, 40};int i;
for (i = 0; i < 4; i++){printf ("fechas [%d] = %d, dirección: %lu\n",
i, fechas[i], &fechas[i]);}
}
Ejemplo
fechas [0] = 10, dirección: 70478fechas [1] = 20, dirección: 70480fechas [2] = 30, dirección: 70482fechas [3] = 40, dirección: 70484
Solución
Arrays – Arrays y Punteros
#include <stdio.h>
#define CANTIDAD 20
void inicializa (int lista [], int *cuanto);int el_mayor (int lista [], int cuanto);
void main (void){int lista[CANTIDAD];int longitud, num;
inicializa(lista, &longitud);num = el_mayor(lista, longitud);
printf("El mayor número introducido es: %d\n",num);
}
Ejemplovoid inicializa(int lista [], int *cuanto){int i;
for (i = 0; i < CANTIDAD; i++){printf("Introduzca el número[%d]: ", i);scanf("%d", &lista[i]);
}
*cuanto = CANTIDAD;}
int el_mayor(int lista[], int cuanto){int mayor, i;
mayor = lista[0];
for (i = l; i < cuanto; i++){if (mayor < lista[i]){mayor = lista[i];
}}
return (mayor);}
Arrays – Arrays y Funciones
DefiniciónLas cadenas de caracteres son un tipo de arrays especiales cuya función principal es la manipulación de caracteres.
Una cadena de caracteres o un string, es un array formado por caracteres que tiene al final un carácter especial: '\0'.
Los strings son arrays que almacena datos tipo char y como tales se declaran:
char cadenadecaracteres [20] = "Esto es una cadena de caracteres";
InicializaciónLa inicialización de una cadena de caracteres puede hacerse de la siguiente manera:
char animales[] = {'g', 'a', 't', 'o', '\0'};char animales[] = "gato";char animales[10] = "gato";char *animales = "gato";
animales = "gato"; // error de compilación
Pueden inicializarse mediante una constante tipo string.No es necesario saber la longitud, para detectar él final basta con buscar el carácter '\0'.Se encuentran formatos especiales para las cadenas (printf, scanf).Se dispone en la librería estándar de un grupo de funciones específicas para procesar cadenas de caracteres.
Strings – Cadenas de Caracteres
Funciones de Lectura y Escriturachar *gets (char *cadena);Lee una línea desde la entrada estándar (stdin) y la almacena en la variable especificada
int puts (char *cadena);Escribe una cadena en la salida estándar (stdout)
<stdio.h>
Funciones de Manipulaciónint strlen (char *cadena);Devuelve la longitud en bytes de la cadena parámetro.
int strcmp (char *cadena1, char *cadena2);Compara cadena1 y cadena2, y devuelve 0 si son iguales <0 si cadena1<cadena2 y >0 al contrario
char *strcpy (char *destino, char *origen);Copia la cadena origen en la posición de la cadena destino.
char *strcat (char *destino, char *origen);Añade la cadena origen en tras la cadena destino.
char *strchr (char *cadena, char caracter);Devuelve un puntero a la primera ocurrencia del carácter en la cadena. NULL si no se encuentra.
char *strstr (char *cadena1, char *cadena2);Devuelve un puntero a la primera ocurrencia de cadena2 en la cadena1. NULL si no se encuentra.
<string.h>
Strings – Funciones de Librería Estándar I
Funciones de Conversión de Datosdouble atof (char *cadena);Convierte una cadena a valor real doble
int atoi (char *cadena);Convierte una cadena a entero
long atol (char *cadena);Convierte una cadena a entero largo
char *fcvt (double valor, int decs, int *pdec, int *signo);Convierte un número real en una cadena de caracteres.
<stdlib.h>
Funciones de Conversión de Caracteresint toascii (int numero);Convierte un número a un valor ASCII.
int tolower (int caracter);Convierte un carácter a minúscula, si procede.
int toupper (int caracter);Convierte un carácter a mayúscula, si procede.
<ctype.h>
Strings – Funciones de Librería Estándar II
DefiniciónEs un tipo de datos complejo conformado por un conjunto de campos de otros tipos (básicos o complejos) asociados a un identificador.
struct [etiqueta]{tipo campo1;tipo campo2;...
} [variable];
Declaración e Inicialización de VariablesLas variables de tipo estructuras se pueden inicializar en su declaración.
struct tsagente agente1 = {"Mortadelo", 001};struct tsagente agente2 = {"Filemón", 002};
Declaración del TipoCuando realizamos la declaración de tipo de la estructura también es posible definir variables que van a almacenar ese nuevo tipo de dato .
struct tsagente{char nombre[100];int numero;
} agente, agentes[10];
Estructuras – Definición, Declaración e Inicialización
Acceso a los CamposVariable normal: se utiliza el operador punto (•).Variable puntero: se utiliza el operador flecha (->).
struct tsagente{char nombre[100];int numero;
} agente, *pagente;
strcpy(agente.nombre, ”Mortadelo”);agente.numero = 001;
pagente = &agente;
printf(“Nombre: %10s Numero :%3d\n”,pagente->nombre, pagente->numero);
Asignación de EstructurasEs posible la asignación directa entre estructuras.
struct tsagente agente1, agente2 = {”Mortadelo”, 001};
agente1 = agente2;
Las Estructuras como Parámetro de FuncionesLas estructuras de datos son tipos complejos y (aunque ciertos compiladores lo admiten) no deben ser pasados como argumentos, ni devueltos por funciones. En su lugar se usan punteros a dichas estructuras.
struct tsagente *leer_agente();void mostrar_agente(struct tsagente *agente);
Estructuras – Acceso, Asignación y Parámetro de Funciones
Anidación de EstructurasLos campos de las estructuras pueden ser otras estructuras.
struct tspersona{char nombre[100];int numero;
};
struct tsagencia{char nombre[100];char pais[30];
};
struct tsagente{struct tspersona persona;struct tsagencia agencia;
};
struct tsagente agente;
strcpy(agente.persona.nombre, ”Mortadelo”);strcpy(agente.agencia.nombre, ”TIA”);
Arrays de EstructurasLos componentes de un array pueden ser estructuras.
struct tsagente agentes[10];
strcpy(agentes[0].persona.nombre, ”Mortadelo”);agentes[0].persona.numero = 001;
Estructuras – Anidación y Arrays de Estructuras
ConceptoEl concepto de fichero en el lenguaje C es general; se incluyen en él tanto dispositivos (pantalla, impresora, teclado), cómo ficheros que se almacenan en memoria.
entrada/salida estándar (standard I/O).
entrada/salida a nivel de sistema (system-level I/O) .
Tipos de E/S de Ficheros
Modo carácter: Los datos se leen y escriben carácter a carácter.
Modo cadena: Los datos se leen y escriben como cadenas de caracteres.
Modo formateado: Los datos se leen y escriben en modo formato.
Modo bloque: Se utiliza para leer y escribir una cantidad fija de datos.
Formas de Leer y Escribir Datos en Ficheros
Ficheros de Texto: Datos se encuentran estructurados en modo texto. Contienen caracteres ASCII.
Ficheros Binarios: Datos en formato de almacenamiento en memoria. Contienen todo tipo de datos.
Tipos de Ficheros de Datos
Ficheros – Concepto y Tipos
Apertura de un ficheroPara acceder a un fichero es necesario abrirlo.
Al abrir el fichero la información de control de acceso al fichero se guarda en una estructura denominada FILE (definida en el fichero stdio.h) y que se utiliza mediante un puntero.
FILE *fopen(char *nombre, char *modo);
nombre: nombre del fichero con su path correspondientemodo: modo de apertura del fichero.
Al modo de apertura hace falta añadir si se abre en modo texto (t) o en modo binario (b).
La función devuelve el puntero al fichero abierto. Si se produce un error en la apertura devuelve un puntero nulo (NULL).
Modo Operaciones admitidas
r Lecturas
w escrituras (crea fichero o lo sobrescribe)
a escritura en el final del fichero (de no haber fichero lo crea)
r+ lecturas + escrituras (fichero creado)
w+ lecturas + escrituras (crea fichero o lo sobrescribe)
a+ lecturas + escrituras a final de fichero (de no haber fichero lo crea)
FILE *fich;fich = fopen(“\\ejemplos\\texto. txt", "w");
Ficheros – Apertura de Fichero
Cierre de un ficheroTodo fichero abierto debe ser cerrado.
int fclose(FILE *fichero);
Fin de un ficheroint feof(FILE * fichero);
Devuelve un valor distinto de cero si no se encuentra al final de fichero (EOF).
#include <stdio.h>
void main (void){FILE *fich;
if((fich = fopen("texto.txt", "r")) != (FILE *) NULL){printf("El fichero \"texto.txt\" puede abrirse.\n");fclose(fichero_ptr);
}else{printf("El fichero \"texto.txt\" no puede abrirse.\n");
}}
Ejemplo
<stdio.h>
<stdio.h>
Ficheros – Cierre y Fin de Fichero
#include <stdio. h>
void main (void){FILE *fich;char caracter;
if((fich = fopen("texto.txt ", "r")) != (FILE *) NULL){while ((caracter = fgetc(fich)) != EOF){printf("%c", caracter);
}
fclose(fich);}
else{printf("\nEl fichero \"texto.txt\" no puede abrirse.");
}}
Ejemplo
Funciones de E/S Carácter a Caracterint fputc (int caracter, FILE *fichero);Introduce un carácter en el fichero.
int fgetc (FILE *fichero);Leer un carácter del fichero.
<stdio.h>
Ficheros – E/S Carácter a Carácter
#include <stdio.h>#define CARACTERES 100
void main (void){FILE *fich;char cadena[CARACTERES];
if((fich = fopen ("texto.txt", "r")) != (FILE *)NULL){while (fgets(cadena, CARACTERES, fich) != (char *)NULL){printf ("%s", cadena);
}fclose (fich);
}else{printf("\nEl fichero \"texto.txt\" no puede abrirse.");
}}
Ejemplo
Funciones de E/S de Cadenas de Caracteresint fputs (char *cadena, FILE *fichero);Introduce una cardena en el fichero.
char *fgets (char *cadena, int longitud, FILE *fichero);Lee una cadena de caracteres de un fichero de cómo máximo longitud – 1 caracteres.
<stdio.h>
Ficheros – E/S en Modo Cadena
#include <stdio.h>#include <string.h>
#define CARACTERES 100
void main (void){FILE *fich;char nombre[CARACTERES];int codigo;float longitud;
if((fich = fopen("texto.txt", "r")) != (FILE *)NULL){while(fscanf (fich, "%s %d %f", nombre, &codigo, &longitud) != EOF){printf("\n%10s %10d %10.2f", nombre, codigo, longitud);
}fclose (fich);
}else{printf ("n\El fichero \"texto.txt\" no puede abrirse");
}}
Ejemplo
Funciones de E/S con Formatoint fprintf (FILE *fichero, char *formato[,arg]…);Escribe los argumentos en el formato especificado en el fichero.
int fscanf (FILE *fichero, char *formato[,arg]…);Lee los argumentos en el formato especificado del fichero.
<stdio.h>
Ficheros – E/S en Modo Formateado
#include <stdio.h>
#define CARACTERES 40
struct tspieza{char nombre[CARACTERES];int numero;float peso;
};
void main (void){struct tspieza pieza;FILE *fich;
if((fich = fopen("piezas.dat", "rb")) != (FILE *)NULL){while(fread(&pieza, sizeof (struct tspieza), 1, fich) == 1){printf("\nNombre : %s", pieza.nombre);printf("\nNúmero : %d", pieza.numero);printf("\nPeso : %f", pieza.peso);
}
Ejemplo
Funciones de E/S Utilizando Registros o Bloquessize_t fwrite (void *buffer, size_t tamanio, size_t numero, FILE *fichero);Escribe un buffer de numero de elementos de un tamaño en el fichero.
size_t fread (void *buffer, size_t tamanio, size_t numero, FILE *fichero);Lee un buffer de numero de elementos de un tamaño del fichero.
<stdio.h>
fclose (fich);}
else{printf ( "\nEl fichero piezas.dat no puede abrirse");
}}
Ficheros – E/S en Modo Bloque
Funciones de Acceso Aleatorio a un Ficheroint fseek(FILE *fichero, long offset, int modo);Posiciona el puntero interno del fichero.
int ftell(FILE *fichero);Devuelve la posición relativa respecto del comienzo de fichero mediante un número entero.
void rewind(FILE *fichero);Coloca el puntero de fichero al comienzo del mismo, desactivando errores y fin de fichero.
<stdio.h>
Modo Offset Definición
0 Desde el comienzo del fichero SEEK_SET
1 Desde la posición actual SEEK_CUR
2 Desde el final de fichero SEEK_END
#include <stdio.h>
void main (void){FILE *fich;int posicion;
if((fich = fopen("datos.dat", "rb")) != (FILE *)NULL){fseek(fich, 0L, SEEK_END); // ó fseek(fich, 0L, 2); Coloca al final de ficherorewind(fich); // Coloca al principio de ficheroposicion = ftell(fich); // La posición se cooresponde con el inicio de ficherofclose (fich);
}
Ejemploelse{printf ("n\El fichero \"datos.dat\" no puede abrirse");
}}
Ficheros – Acceso Aleatorio a un Fichero
#include <stdio.h>
void main(void){char nombre[100];int entero;float real;
printf("Dame un nombre un entero y un real\n");scanf("%s %d %f", nombre, &entero, &real);printf("Nombre = %s, entero = %d, real = %f\n",
nombre, entero, real);}
Ejemplo 1 Paso 1
#include <stdio.h>
void main(void){char nombre[100];int entero;float real;FILE *fich;
printf("Dame un nombre un entero y un real\n");scanf("%s %d %f", nombre, &entero, &real);
fich = fopen("fichero.txt", "wt");
#include <stdio.h>
void main(void){char nombre[100];int entero;float real;FILE *fich;
fich = fopen("fichero.txt", "rt");
if(fich != (FILE *) NULL){fscanf(fich, "%s %d %f", nombre, &entero, &real);printf("Nombre = %s, entero = %d, real = %f\n",nombre, entero, real);fclose(fich);
}else{printf("No se puede abrir fichero\n");
}}
Ejemplo 1 Paso 3
if(fich != (FILE *) NULL){fprintf(fich, "%s %d %f", nombre, entero, real);fclose(fich);
}else{printf("No se puede crear fichero\n");
}}
Ejemplo 1 Paso 2
Ficheros – Ejemplo 1
#include <stdio.h>
#define MAXARRAY 100
struct rgarticulo{char nombre[100];int unidades;float precio;
};
void leer_array(struct rgarticulo articulos[], int *longitud);void mostrar_array(struct rgarticulo articulos[], int longitud);void leer_registro(struct rgarticulo *articulo);void mostrar_registro(struct rgarticulo *articulo);
void main(void){struct rgarticulo articulos[MAXARRAY];int longitud = 0;
leer_array(articulos, &longitud);mostrar_array(articulos, longitud);
}
Declaraciones, Tipos y Programa Principal
Ficheros – Ejemplos 2 y 3 Paso 1 (Programa Principal)
Función mostrar_array
void leer_array(struct rgarticulo articulos[], int *longitud){char opcion;
do{printf("Introducir elemento [s/n]? ");opcion = getchar();if(opcion == 'S' || opcion == 's'){leer_registro(&articulos[*longitud]);(*longitud)++;
}} while (opcion != 'N' && opcion != 'n');
}
Función leer_array
void mostrar_array(struct rgarticulo articulos[], int longitud){int i;
for(i = 0; i < longitud; i++){printf("\nRegistro %d\n", i + 1);mostrar_registro(&articulos[i]);
}}
Función leer_registrovoid leer_registro(struct rgarticulo *articulo){struct rgarticulo articulin;
printf("Nombre : ");scanf("%s", articulin.nombre);printf("Unidades : ");scanf("%d", &articulin.unidades);printf("Precio : ");scanf("%f", &articulin.precio);
*articulo = articulin;}
Función mostrar_registrovoid mostrar_registro(struct rgarticulo *articulo){printf("Nombre : %s\n", articulo->nombre);printf("Unidades : %d\n", articulo->unidades);printf("Precio : %f\n", articulo->precio);
}
Ficheros – Ejemplos 2 y 3 (Funciones varias)
Función array_fichero
#include <stdio.h>
#define MAXARRAY 100#define NOMFICH "Articuls.txt"
struct rgarticulo{char nombre[100];int unidades;float precio;
};
void leer_array(struct rgarticulo articulos[],int *longitud);
void leer_registro(struct rgarticulo *articulo);void array_fichero(char *nomfich,
struct rgarticulo articulos[],int longitud);
void main(void){struct rgarticulo articulos[MAXARRAY];int longitud = 0;
leer_array(articulos, &longitud);array_fichero(NOMFICH, articulos, longitud);
}
void array_fichero(char *nomfich,struct rgarticulo articulos[],int longitud)
{int i;FILE *fich;
if((fich = fopen(nomfich, "wt")) != (FILE *) NULL){for(i = 0; i < longitud; i++){fprintf(fich, "%s %d %f\n",
articulos[i].nombre,articulos[i].unidades,articulos[i].precio);
}fclose(fich);
}else{printf("No se ha podido crear el fichero %s\n",
nomfich);}
}
Declaraciones, Tiposy Programa Principal
Ficheros – Ejemplo 2 Paso 2 (E/S Modo Formateado)
Función fichero_array
#include <stdio.h>
#define MAXARRAY 100#define NOMFICH "Articuls.txt"
struct rgarticulo{char nombre[100];int unidades;float precio;
};
void mostrar_array(struct rgarticulo articulos[],int longitud);
void mostrar_registro(struct rgarticulo *articulo);void fichero_array(char *nomfich,
struct rgarticulo articulos[],int *longitud);
void main(void){struct rgarticulo articulos[MAXARRAY];int longitud = 0;
fichero_array(NOMFICH, articulos, &longitud);mostrar_array(articulos, longitud);
}
void fichero_array(char *nomfich,struct rgarticulo articulos[],int *longitud)
{struct rgarticulo articulin;FILE *fich;
*longitud = 0;
if((fich = fopen(nomfich, "rt")) != (FILE *) NULL){while(fscanf(fich, "%s %d %f",
articulin.nombre,&articulin.unidades,&articulin.precio) != EOF)
{articulos[*longitud] = articulin;(*longitud)++;
}fclose(fich);
}else{printf("No se ha podido abrir el fichero %s\n",
nomfich);}
}
Declaraciones, Tiposy Programa Principal
Ficheros – Ejemplo 2 Paso 3 (E/S Modo Formateado)
#include <stdio.h>
#define MAXARRAY 100#define NOMFICH1 "Articuls.txt"#define NOMFICH2 "Articul2.txt"#define PTSEURO 166.386
struct rgarticulo{char nombre[100];int unidades;float precio;
};
void mostrar_array(struct rgarticulo articulos[],int longitud);
void mostrar_registro(struct rgarticulo *articulo);void transformar_array(struct rgarticulo articulos[],
int longitud);void array_fichero(char *nomfich,
struct rgarticulo articulos[],int longitud);
void fichero_array(char *nomfich,struct rgarticulo articulos[],int *longitud);
void main(void){struct rgarticulo articulos[MAXARRAY];int longitud = 0;
fichero_array(NOMFICH1, articulos, &longitud);transformar_array(articulos, longitud);mostrar_array(articulos, longitud);array_fichero(NOMFICH2, articulos, longitud);
}
Declaraciones, Tiposy Programa Principal
Función transformar_arrayvoid transformar_array(struct rgarticulo articulos[],
int longitud){int i;
for(i = 0; i < longitud; i++){articulos[i].precio = articulos[i].precio / PTSEURO;
}}
Ficheros – Ejemplo 2 Paso 4 (E/S Modo Formateado)
Función array_fichero
#include <stdio.h>
#define MAXARRAY 100#define NOMFICH "Articuls.dat"
struct rgarticulo{char nombre[100];int unidades;float precio;
};
void leer_array(struct rgarticulo articulos[],int *longitud);
void leer_registro(struct rgarticulo *articulo);void array_fichero(char *nomfich,
struct rgarticulo articulos[],int longitud);
void main(void){struct rgarticulo articulos[MAXARRAY];int longitud = 0;
leer_array(articulos, &longitud);array_fichero(NOMFICH, articulos, longitud);
}
void array_fichero(char *nomfich,struct rgarticulo articulos[],int longitud)
{int i;FILE *fich;
if((fich = fopen(nomfich, "wb")) != (FILE *) NULL){for(i = 0; i < longitud; i++){fwrite(&articulos[i],
sizeof(struct rgarticulo),1,fich);
}fclose(fich);
}else{printf("No se ha podido crear el fichero %s\n",
nomfich);}
}
Declaraciones, Tiposy Programa Principal
Ficheros – Ejemplo 3 Paso 2 (E/S Modo Bloque)
Función fichero_array
#include <stdio.h>
#define MAXARRAY 100#define NOMFICH "Articuls.dat"
struct rgarticulo{char nombre[100];int unidades;float precio;
};
void mostrar_array(struct rgarticulo articulos[],int longitud);
void mostrar_registro(struct rgarticulo *articulo);void fichero_array(char *nomfich,
struct rgarticulo articulos[],int *longitud);
void main(void){struct rgarticulo articulos[MAXARRAY];int longitud = 0;
fichero_array(NOMFICH, articulos, &longitud);mostrar_array(articulos, longitud);
}
void fichero_array(char *nomfich,struct rgarticulo articulos[],int *longitud)
{FILE *fich;
*longitud = 0;
if((fich = fopen(nomfich, "rb")) != (FILE *) NULL){while(fread(&articulos[*longitud],
sizeof(struct rgarticulo),1,fich) == 1)
{(*longitud)++;
}fclose(fich);
}else{printf("No se ha podido abrir el fichero %s\n",
nomfich);}
}
Declaraciones, Tiposy Programa Principal
Ficheros – Ejemplo 3 Paso 3 (E/S Modo Bloque)
#include <stdio.h>
#define MAXARRAY 100#define NOMFICH1 "Articuls.dat"#define NOMFICH2 "Articul2.dat"#define PTSEURO 166.386
struct rgarticulo{char nombre[100];int unidades;float precio;
};
void mostrar_array(struct rgarticulo articulos[],int longitud);
void mostrar_registro(struct rgarticulo *articulo);void transformar_array(struct rgarticulo articulos[],
int longitud);void array_fichero(char *nomfich,
struct rgarticulo articulos[],int longitud);
void fichero_array(char *nomfich,struct rgarticulo articulos[],int *longitud);
void main(void){struct rgarticulo articulos[MAXARRAY];int longitud = 0;
fichero_array(NOMFICH1, articulos, &longitud);transformar_array(articulos, longitud);mostrar_array(articulos, longitud);array_fichero(NOMFICH2, articulos, longitud);
}
Declaraciones, Tiposy Programa Principal
Función transformar_arrayvoid transformar_array(struct rgarticulo articulos[],
int longitud){int i;
for(i = 0; i < longitud; i++){articulos[i].precio = articulos[i].precio / PTSEURO;
}}
Ficheros – Ejemplo 3 Paso 4 (E/S Modo Bloque)