Download Facultad de Ingeniería - FI

Document related concepts
no text concepts found
Transcript
Universidad Nacional Autónoma
de México
Facultad de Ingeniería
Lenguaje C
Autor:
Ing. Israel Durán Martínez
Creado en Octubre 2007
Última actualización: Agosto 2010
ÍNDICE
ÍNDICE ............................................................................................................................... 2
CAPÍTULO 1:
INTRODUCCIÓN AL LENGUAJE C ....................................... 5
1.1 ORÍGENES DEL LENGUAJE C ........................................................................................... 5
1.2 UN LENGUAJE DE NIVEL MEDIO ...................................................................................... 5
1.3 UN LENGUAJE ESTRUCTURADO ...................................................................................... 6
1.4 COMPILADORES FRENTE A INTÉRPRETES ........................................................................ 7
1.5 LA BIBLIOTECA Y EL ENLAZADO .................................................................................... 8
1.6 ENTORNOS DE DESARROLLO .......................................................................................... 9
CAPÍTULO 2:
LENGUAJE C: ELEMENTOS BÁSICOS .............................. 10
2.1 ESTRUCTURA GENERAL DE UN PROGRAMA EN C .......................................................... 10
2.1.1 Directivas del preprocesador .............................................................................. 11
2.1.2 Declaraciones globales ....................................................................................... 11
2.1.3 Función main( ) ................................................................................................... 11
2.1.4 Funciones definidas por el usuario ..................................................................... 11
2.2 COMENTARIOS ............................................................................................................. 13
2.3 IDENTIFICADORES ........................................................................................................ 13
2.4 PALABRAS RESERVADAS .............................................................................................. 14
2.5 TIPOS DE DATOS ........................................................................................................... 14
2.6 VARIABLES .................................................................................................................. 17
2.6.1 Variables locales ................................................................................................. 17
2.6.2 Variables globales ............................................................................................... 18
2.6.3 Inicialización de variables .................................................................................. 19
2.6.4 Constantes ........................................................................................................... 20
2.6.5 Constantes de carácter de barra invertida .......................................................... 21
CAPÍTULO 3:
OPERADORES Y EXPRESIONES ......................................... 23
3.1 OPERADORES ARITMÉTICOS ......................................................................................... 23
3.2 OPERADORES RELACIONALES Y LÓGICOS ..................................................................... 23
3.3 OPERADORES A NIVEL DE BITS ..................................................................................... 24
3.4 PRECEDENCIA DE LOS OPERADORES DE C .................................................................... 25
CAPÍTULO 4: INSTRUCCIONES DE CONTROL ............................................ 26
4.1 INSTRUCCIONES DE SELECCIÓN .................................................................................... 26
IF .................................................................................................................................. 26
SWITCH ........................................................................................................................ 26
4.2 INSTRUCCIONES DE ITERACIÓN .................................................................................... 27
FOR .............................................................................................................................. 27
WHILE .......................................................................................................................... 28
DO WHILE ................................................................................................................... 29
4.3 INSTRUCCIONES DE SALTO ........................................................................................... 29
acultad de Inge
return ............................................................................................................................ 29
break ............................................................................................................................. 30
continue ........................................................................................................................ 30
CAPÍTULO 5: FUNCIONES ..................................................................................... 31
5.1 FORMA GENERAL DE UNA FUNCIÓN.............................................................................. 31
5.2 PROTOTIPOS DE LAS FUNCIONES .................................................................................. 32
5.3 PARÁMETROS DE UNA FUNCIÓN ................................................................................... 32
5.4 ARGUMENTOS DE MAIN() ............................................................................................. 35
CAPÍTULO 6: ARRAYS Y CADENAS................................................................... 38
6.1 ARRAYS UNIDIMENSIONALES ....................................................................................... 38
6.2 ALMACENAMIENTO EN MEMORIA DE LOS ARRAYS ....................................................... 39
6.3 TAMAÑO DE ARRAYS ................................................................................................... 39
6.4 INICIALIZACIÓN DE UN ARRAY ..................................................................................... 40
6.5 CADENAS ..................................................................................................................... 41
6.6 ARRAYS BIDIMENSIONALES ......................................................................................... 41
6.7 INICIALIZACIÓN DE ARRAYS BIDIMENSIONALES ........................................................... 42
CAPÍTULO 7: PUNTEROS........................................................................................ 43
7.1 ¿QUÉ SON LOS PUNTEROS? ........................................................................................... 43
7.2 DECLARACIÓN DE APUNTADORES ................................................................................ 43
7.3 PUNTEROS Y ARRAYS .................................................................................................. 45
7.4 PUNTEROS DE CADENAS ............................................................................................... 46
7.5 PUNTEROS A FUNCIONES .............................................................................................. 46
CAPÍTULO 8: ESTRUCTURAS ............................................................................... 48
8.1 DEFINICIÓN .................................................................................................................. 48
8.2 ACCESO A LOS MIEMBROS DE LA ESTRUCTURA ............................................................ 49
8.3 ASIGNACIÓN DE VALORES ............................................................................................ 49
8.4 PUNTEROS A ESTRUCTURAS ......................................................................................... 50
CAPÍTULO 9: ARCHIVOS ........................................................................................ 53
9.1 MANEJO DE ARCHIVOS ................................................................................................ 53
fopen()........................................................................................................................... 54
fclose() .......................................................................................................................... 54
putc()............................................................................................................................. 54
fputc() ........................................................................................................................... 54
getc() ............................................................................................................................ 55
fgetc() ........................................................................................................................... 55
fgets() ........................................................................................................................... 56
fputs() ........................................................................................................................... 56
fseek() .......................................................................................................................... 57
fwrite() ......................................................................................................................... 60
fflush() ......................................................................................................................... 61
9.2 EL PUNTERO A ARCHIVO .............................................................................................. 61
9.3 APERTURA DE UN ARCHIVO ......................................................................................... 66
acultad de Inge
9.4 CIERRE DE UN ARCHIVO ............................................................................................... 67
BIBLIOGRAFÍA ............................................................................................................ 71
acultad de Inge
CAPÍTULO 1:
INTRODUCCIÓN AL LENGUAJE C
1.1 Orígenes del lenguaje C
El lenguaje C fue inventado e implementado por primera vez por Dennis Ritchie
en DEC PDP-11 usando UNIX como sistema operativo. C es el resultado de un proceso
de desarrollo comenzando con un lenguaje anterior denominado BCPL. BCPL fue
desarrollado por Martín Richards e influenció otro lenguaje denominado B, inventando
por Ken Thompson, que en los años sesenta llevó al desarrollo del C.
Durante muchos años el estándar de C fue realmente la versión proporcionada
con la versión V del sistema operativo UNIX. Aparece descrito en el libro The C
Programming Language de Brian Kernighan y Dennis Ritchie. Con la popularidad de las
microcomputadoras se crearon muchas implementaciones de C. En lo que se podría
decir que era un milagro, los códigos fuente aceptados por la mayoría de esas
implementaciones eran altamente compatibles. Sin embargo, como no existía ningún
estándar, aparecieron discrepancias. Para remediar la situación, el Instituto Nacional
de Estándares Americano (ANSI) estableció un comité a principios del verano de 1983
para crear un estándar que definiera de una vez por todas el lenguaje C. Finalmente,
el estándar fue adoptado en diciembre de 1989, comenzando a estar disponibles las
primeras copias a principios de 1990. El estándar también fue adoptado por la ISO
(Organización Internacional de Estándares), siendo habitual que el estándar se refiera
como estándar ANSI/ISO.
Durante los años noventa, el desarrollo del estándar de C++ acaparó casi toda
la atención de los programadores. Sin embargo, el trabajo sobre C continuó, siendo
desarrollado un nuevo estándar terminado en 1999 y que comúnmente se le llama
C99. En general, C99 mantiene prácticamente todas las características de C89.
1.2 Un lenguaje de nivel medio
A menudo se denomina al lenguaje C como un lenguaje de computadora de
nivel medio. Esto no significa que sea menos potente, más difícil de usar o menos
evolucionado que lenguajes de alto nivel como BASIC o Pascal; ni implica que C sea
acultad de Inge
similar al lenguaje ensamblador y por tanto presente al usuario sus problemas
asociados. C se presenta como un lenguaje de nivel medio porque combina elementos
de lenguajes de alto nivel con la funcionalidad del lenguaje ensamblador.
Como lenguaje de nivel medio, C permite la manipulación de bits, bytes y
direcciones – los elementos básicos con los que funciona la computadora-. El código de
C es muy portable.
Todos los lenguajes de alto nivel soportan el concepto de tipos de datos. Un tipo
de datos define un conjunto de valores que pueden tener una variable junto con un
conjunto de operaciones que se pueden realizar sobre esa variable. Algunos tipos de
datos comunes son los enteros, los caracteres y los reales. Aunque el lenguaje C tiene
cinco tipos de datos básicos incorporados, no se trata de un lenguaje fuertemente
tipificado en el sentido de Pascal o Ada. C permite casi todas las conversiones de tipos.
Por ejemplo, los tipos entero y de carácter pueden ser entremezclados libremente en la
mayoría de las expresiones. C no lleva a cabo la comprobación de errores en el tiempo
de ejecución como pueden ser el sobrepasar los límites de los arrays o la
compatibilidad de tipos de los argumentos. Esas comprobaciones quedan enteramente
como responsabilidad del programador.
1.3 Un lenguaje estructurado
El lenguaje C se denomina normalmente lenguaje estructurado, ya que tiene
similitudes estructurales con ALGOL, Pascal y Modula-2. Técnicamente, un lenguaje
estructurado en bloques permite declarar procedimientos o funciones dentro de otros
procedimientos o funciones. De esta forma, se extienden los conceptos de globalidad y
localidad mediante el uso de reglas de alcance, que gobiernan la visibilidad de las
variables o de los procedimientos. Dado que C no permite la creación de funciones
dentro de funciones, no puede ser formalmente denominado lenguaje estructurado en
bloques.
La
característica
distintiva
de
un
lenguaje
estructurado
es
la
compartimentalización de código y datos. Se trata de la capacidad de un lenguaje de
seccionar y esconder el resto del programa toda la información y las instrucciones
necesarias para llevar a cabo una determinada tarea. Una forma como se consigue la
acultad de Inge
compartimentalización es mediante el uso de subrutinas que empleen variables locales.
Con el uso de variables locales es posible escribir subrutinas de forma que lo que
ocurra en su interior no provoque efectos secundarios en otras partes del programa.
Esta posibilidad hace que sea muy fácil que los programas en C compartan secciones
de código. Al desarrollar funciones compartimentalizadas sólo es necesario conocer que
es lo que la función hace, no cómo lo hace. El excesivo uso de variables globales puede
hacer que los errores proliferen en el programa, al permitir los efectos secundarios no
deseados.
La componente estructural principal de C es la función; una subrutina
independiente. En C, las funciones son los bloques constitutivos en los que se
desarrolla toda la actividad de los programas. Son las que permiten definir las tareas
de un programa y codificarlas por separado, permitiendo así que los programas sean
modulares. Una vez que se ha creado una función se puede aprovechar funcionando
perfectamente en distintas situaciones, sin crear efectos secundarios en otras partes
del
programa.
El
hecho
de
poder
crear
funciones
independientes
es
algo
extremadamente crítico en grandes proyectos donde es importante que el código de un
programador no afecte accidentalmente al de otro.
Otra forma de estructuración y compartimentalización de código en C viene
dada por el uso de bloques de código. Un bloque de código es un grupo de
instrucciones de un programa conectadas de forma lógica que es tratado como una
unidad. En C se crean bloques de código colocando una serie de instrucciones entre
llaves.
Ejemplo:
if(x < 10)
{
printf(“Demasiado bajo \n”);
}
1.4 Compiladores frente a intérpretes
Los términos compilador e intérprete se refieren a la forma en que se ejecuta
un programa. En teoría, cualquier lenguaje de programación puede ser compilado o
interpretado, pero algunos se suelen ejecutar en una forma o en la otra. Por ejemplo,
acultad de Inge
Java fue diseñado para ser interpretado y C para ser compilado. La forma en que se
ejecuta un programa no viene definida por el lenguaje en que se haya escrito. Los
intérpretes y los compiladores con simplemente programas que trabajan sobre el
código fuente del programa.
Un intérprete lee el código fuente de un programa línea a línea, realizando las
instrucciones específicas contenidas en esa línea. Un compilador lee el programa
entero y lo convierte en código objeto, que es una traducción del código fuente del
programa a una forma que puede ser ejecutada directamente por la computadora. El
código objeto también se suele denominar código binario o código máquina. Una vez
que el programa está compilado las líneas del código fuente dejan de tener sentido en
la ejecución del programa. Cuando se usa un intérprete, el código fuente debe estar
presente cada vez que se quiere ejecutar el programa. Por el contrario, un compilador
convierte el programa en código objeto que puede ser directamente ejecutado por la
computadora. Como el compilador traduce el programa de una vez, todo lo que hay
que hacer es ejecutarlo directamente, normalmente mediante el simple proceso de
escribir su nombre. Por tanto, la compilación sólo cuesta una vez, mientras que el
código interpretado lleva esa carga cada vez que se ejecuta un programa.
1.5 La biblioteca y el enlazado
Técnicamente hablando, es posible crear un programa en C que sea funcional y
útil y que consista solamente en las sentencias realmente creadas por el programador.
Sin embargo, esto es bastante raro, ya que C no proporciona, dentro de la definición
real del lenguaje, ningún método para llevar a cabo las operaciones de entrada/salida.
Por ello la mayoría de los programadores incluyen llamadas a varias funciones
contenidas en la biblioteca estándar del lenguaje C.
Las funciones que se encuentran en la biblioteca lo están en formato reubicable.
Esto significa que las direcciones de memoria de las diferentes instrucciones de código
máquina no han sido definidas de forma absoluta; solo se mantiene información sobre
desplazamientos. Cuando se enlaza un programa con funciones de la biblioteca
estándar, se usan esos desplazamientos de memoria para definir las direcciones
reales.
acultad de Inge
1.6 Entornos de desarrollo
La mayoría de los compiladores modernos se proporcionan en dos formas. La
primera forma es el compilador autónomo de línea de órdenes. Con esta forma se
utiliza un editor aparte para crear los programas, luego se compila el programa y,
finalmente, se ejecuta el programa. Esto se lleva a cabo mediante órdenes
independientes dadas en la línea de comandos. Esta es la forma tradicional de
implementación de los compiladores.
La segunda forma de un compilador se encuentra en un entorno integrado de
desarrollo (IDE), como Visual C++ o Dev C++. En esta forma, el compilador esta
integrado con un editor, un depurador, un administrador de proyectos y un sistema de
soporte para tiempo de ejecución. Con un IDE se edita, compila y ejecuta el programa
sin salir del entorno. Actualmente los IDEs que distribuyen los principales fabricantes
de compiladores tienen mucho que ofrecer a los programadores. Si se emplea un poco
de tiempo en ajustar las opciones del entorno para que esté optimizado a las
necesidades propias, se puede comprobar que el uso del IDE ayuda mucho en el
proceso de desarrollo.
acultad de Inge
CAPÍTULO 2:
LENGUAJE C: ELEMENTOS BÁSICOS
2.1 Estructura general de un programa en C
Todos los programas en C consisten en uno o más módulos llamados funciones.
La única función que debe estar absolutamente presente es la denominada main(),
siendo la primera función que es llamada cuando comienza la ejecución del programa.
En código C bien escrito, main() en esencial, esboza lo que el programa hace. Ese
esbozo está compuesto por llamadas a funciones. Aunque técnicamente main() no es
una palabra clave, se le trata como si lo fuera. No se debe usar main() como nombre
para una variable ya que el compilador se confundirá.
La forma general de un programa en C se muestra a continuación:
Directivas del preprocesador
Prototipos de funciones
Declaraciones globales
/*Función main*/
int main(void)
{
variables locales
sentencias
llamadas a funciones
}
/*Funciones definidas por el usuario*/
f1()
{
variables locales
sentencias
secuencia de sentencias
}
f2()
{
variables locales
sentencias
secuencia de sentencias
}
.
.
.
fN()
{
variables locales
sentencias
secuencia de sentencias
}
acultad de Inge
2.1.1 Directivas del preprocesador
El preprocesador consta de directivas que son instrucciones al compilador.
Todas las directivas del preprocesador comienzan con el signo de libro o de
<<almohadilla>> (#) y no terminan en punto y coma, ya que son instrucciones del
lenguaje C.
La directiva #include indica al compilador que lea el archivo fuente (archivo
cabecera o de inclusión) que viene a continuación de ella y su contenido lo inserte en
la posición donde se encuentra dicha directiva. Estas instrucciones son de la forma
#include <nombrearchivo.h> o bien #include “nombrearchivo.h”.
La directiva #define indica al preprocesador que defina un ítem de datos u
operación para el programa C. Por ejemplo, la directiva #define TAM 10 sustituirá el
valor de 10 cada vez que TAM aparezca en el programa.
2.1.2 Declaraciones globales
Las declaraciones globales indican al usuario que las constantes o variables así
declaradas son comunes a todas las funciones de su programa. Se sitúan antes de la
función main( ). La zona de declaraciones globales puede incluir declaraciones de
variables además de declaraciones de prototipos de función.
2.1.3 Función main( )
Cada programa C tiene una función main( ) que es un punto inicial de entrada
al programa. Su estructura es:
int main()
{
. . .
Bloque de sentencias
return 0;
}
2.1.4 Funciones definidas por el usuario
acultad de Inge
Un programa C es una colección de funciones. C proporciona funciones
predefinidas que se denominan funciones de biblioteca y otras definidas por el usuario.
Se invocan por su nombre y los parámetros opcionales que tenga. Después de que la
función sea llamada, el código asociado con la función se ejecuta y, a continuación, se
retorna a la función llamadora. En C, las funciones definidas por el usuario requieren
una declaración o prototipo en el programa, que indica al compilador el nombre por el
que ésta será invocada.
#include<stdio.h>
//Prototipo de la función
void prueba();
int main()
{
prueba();
return 0;
}
//Función definida por el usuario
void prueba()
{
printf(“Mis primeros pasos \n”);
}
Ejemplo: Mi primer programa en C
NOTA: Todos los programas están compilados en Dev C++
/*Directivas del preprocesador*/
#include<stdio.h>
/*Prototipos de funciones*/
void hola(void);
/*Función main*/
int main(void)
{
printf("Mi primer programa en C\n");
hola();
getchar();
return 0;
}
/*Funciones definidas por el usuario*/
void hola(void)
{
printf("Hola a todos\n");
}
acultad de Inge
2.2 Comentarios
Los comentarios de una sola línea comienzan con // y terminan al final de la
línea. Por ejemplo:
//Este es un comentario de una sola línea
Los comentarios multilínea empiezan con un /* y terminan con */. No debe
haber espacios entre el asterisco y la barra. El compilador ignora cualquier texto entre
los símbolos de comienzo y fin de comentario.
Los comentarios multilínea no se pueden anidar. Es decir, un comentario no
puede contener otro comentario. Por ejemplo:
/* Comentario externo
/*Comentario interno que provoca un error*/
*/
2.3 Identificadores
Los nombres usados para referirse a las variables, funciones, las etiquetas y
otros objetos definidos por el usuario se conocen como identificadores. El primer
carácter debe ser una letra o un símbolo de subrayado y los caracteres siguientes
pueden ser letras, números o símbolos de subrayado.
En C las minúsculas y las mayúsculas se tratan como distintas. Así, cuenta,
Cuenta y CUENTA son tres identificadores distintos. Además de que un identificador no
puede ser igual que una palabra clave y no debe tener el nombre de una función ya
escrita.
Ejemplo:
a) Identificadores válidos
X
y21
suma_1
_temperatura
nombres
area
porc_imp
TABLA
b) Identificadores no válidos
4num
El primer carácter debe ser letra.
“x”
Caracteres ilegales (“)
acultad de Inge
orden-no
Carácter ilegal (-)
indicador error
Carácter ilegal (espacio en blanco)
Convenciones

Los identificadores deben ser descriptivos: deben hacer referencia al significado
de aquello a lo que se refieren.


int n1, n2
//MAL
int anchura, altura;
//BIEN
Los identificadores asociados a las variables se suelen poner en minúsculas
int ConTADoR;
//MAL
int contador;
//BIEN
Cuando el identificador está formado por varias palabras, la primera palabra va
en minúsculas y el resto de palabras se inician con una letra mayúscula (o bien
se separan las distintas palabras por guiones de subrayado.
int mayorvalor;
//MAL
int mayor_valor;
//BIEN
int mayorValor;
//BIEN
2.4 Palabras reservadas
Las siguientes palabras no pueden usarse como identificadores, es decir, no
debe servir como nombre de variable o de función.
auto
double
int
struct
break
else
long
switch
case
enum
register
typedef
char
extern
return
union
const
float
short
unsigned
continue
for
signed
void
default
goto
sizeof
volatile
do
if
static
while
Todas las palabras van en minúsculas.
2.5 Tipos de datos
acultad de Inge
Existen cinco tipos de datos atómicos en C: carácter, entero, coma flotante,
coma flotante de doble precisión y sin valor
Tipo
Tamaño en bytes
Rango
char
1
-128 a 127
int
2
-32768 a 32767
float
4
1.17549e–38 a 3.40282e+38
double
8
2.22507e–308 a 1.79769e+308
void
0
Sin valor
Los valores de tipo char se usan normalmente para guardar valores definidos en
el juego de caracteres ASCII, así como cualquier cantidad de 8 bits. Las variables de
tipo int se usan para guardar cantidades enteras. Las variables de tipo float o double
se usan para guardar números reales.
El tipo void tiene tres usos. El primero es para declarar explícitamente una
función
como
que
no
devuelve
valor
alguno;
el
segundo
es
para
declarar
explícitamente una función sin parámetros; el tercero es para crear punteros
genéricos.
Modificadores de tipos
A excepción del tipo void, los tipos de datos básicos pueden tener distintos
modificadores precediéndolos. Un modificador se usa para alterar el significado del tipo
base para que se ajuste más precisamente a las necesidades de cada momento. A
continuación se muestra la lista de modificadores:

signed – Aplicable a los tipos char, short, int y long.

unsigned – Aplicable a los tipos char, short, int y long.

long

short
Los modificadores signed, unsigned, short y long se pueden aplicar a los tipos
base entero y de carácter. Sin embargo, long también se puede aplicar a double.
acultad de Inge
Tipo
Tamaño en bytes
Rango
char
1
-128 a 127
unsigned char
1
0 a 255
signed char
1
-128 a 127
int
2o4
-32,768 a 32,767
unsigned int
2o4
0 a 65,535
signed int
2o4
Igual que int
short int
2
-32,768 a 32,767
unsigned short int
2
0 a 65,535
signed short int
2
Igual que short int
long int
4
-2,147,483,648 a 2,147,483,647
long long int
8
-(263-1) a 263-1 (Para C99)
signed long int
4
Igual que long int
unsigned long int
4
0 a 4,294,967,295
unsigned long long int
8
0 a 264-1 (Para C99)
float
4
1.17549e–38 a 3.40282e+38
double
8
2.22507e–308 a 1.79769e+308
long double
10 o 12
3.4e–4932 a 1.2e+4932
limits.h
Librería que contiene parámetros de entorno, información sobre limitaciones y
rangos para tipos enteros.
Constante
Significado
CHAR_BIT
Número de bits del tipo char
CHAR_MIN
Valor mínimo del tipo char
CHAR_MAX
Valor máximo del tipo char
INT_MIN
Valor mínimo del tipo int
INT_MAX
Valor máximo del tipo int
LONG_MIN
Valor mínimo del tipo long
LONG_MAX
Valor máximo del tipo long
SCHAR_MIN
Valor mínimo del tipo char con signo
SCHAR_MAX
Valor máximo del tipo char con signo
SHRT_MIN
Valor mínimo del tipo short
SHRT_MAX
Valor máximo del tipo short
UCHAR_MAX
Valor máximo de unsigned char
USHRT_MAX
Valor máximo unsigned short
acultad de Inge
UINT_MAX
Valor máximo unsigned int
ULONG_MAX
Valor máximo unsigned long
2.6 Variables
Una variable es una posición de memoria con nombre que se usa para
mantener un valor que puede ser modificado por el programa. Todas las variables han
de estar declaradas antes de poder ser utilizadas. La forma general de la declaración
es:
tipo lista_de_variables;

tipo - debe ser un tipo de datos válido con algún modificador.

lista_de_variables - puede consistir en uno o más nombres de identificadores
separados por comas.
2.6.1 Variables locales
Las variables locales son aquellas que se declaran dentro de una función. Este
tipo de variables pueden ser utilizadas sólo en las instrucciones que estén dentro del
bloque en el que han sido declaradas. Un bloque de código comienza con una llave de
apertura y termina con una llave de cierre.
Las variables locales sólo existen mientras se está ejecutando el bloque de
código en el que son declaradas. O sea, la variable local se crea al entrar en el bloque
y se destruye al salir de él. Más aún, una variable declarada dentro de un bloque de
código no tiene que ver con otra variable con el mismo nombre que se haya declarado
en otro bloque de código distinto.
Ejemplo: Variables locales
#include<stdio.h>
int main()
{
/*Declaración de una variable local*/
int x=10;
if(x == 10)
{
/*Declaración de una variable local.
Pierde su valor cuando sale de este bloque*/
acultad de Inge
int x;
x=99;
printf("x interna: %d\n",x);
}
printf("x externa: %d\n",x);
getchar();
return 0;
}
2.6.2 Variables globales
Las variables globales se conocen a lo largo de todo el programa y se pueden
usar en cualquier parte del código. Además, mantienen sus valores durante toda la
ejecución del programa. Las variables globales se crean al declararlas en cualquier
parte
fuera
de
la
función.
Pueden
ser
accedidas
por
cualquier
expresión,
independientemente de la función en la que se encuentre la expresión.
Si una variable global y una variable local tienen el mismo nombre, todas las
referencias a ese nombre de variable dentro de la función donde se ha declarado la
variable local se refieren a esa variable local y no tienen efecto sobre la variable global.
Ejemplo: Variables globales
#include<stdio.h>
//Declaracion de la variable global
int cuenta;
//Prototipo de la funcion
void funcion1(void);
int main(void)
{
//Inicializa la variable global
cuenta = 100;
//Impresión de la variable global
printf("Variable global cuenta: %d\n",cuenta);
//Llamada a la función "funcion1()"
funcion1();
//Impresión de la variable global
printf("Variable global cuenta: %d\n",cuenta);
getchar();
return 0;
acultad de Inge
}
//Creación de una función
void funcion1(void)
{
//Declaracion de una variable local
int cuenta = 20;
printf("Variable local cuenta: %d\n", cuenta);
}
2.6.3 Inicialización de variables
Colocando el signo igual y una constante después del nombre de un variable se
puede dar a la mayoría de las variables un valor a la vez que se declaran. La forma
general de inicialización es:
tipo nombre_de_variable = valor;
Ejemplo: Inicialización de variables
#include<stdio.h>
int main()
{
//Declaración e inicialización de variables
char c = '&', c2;
int y, x = 10;
double d = 12.7655, d2;
float f=2, f2;
char cad[] = "Hola a todos";
//Impresión de las variables
printf("Valor del caracter c: %c y c2: %c\n",c,c2);
printf("Valor del entero x: %d e y: %d\n",x,y*2);
printf("Valor del numero real f: %g y f2: %g\n",f,f2);
printf("Valor del numero real d: %g y d2: %g\n",d,d2);
printf("Valor del arreglo cad: %s\n",cad);
getchar();
return 0;
}
#include
#include
#include
#include
<stdio.h>
<limits.h>
<float.h>
<stdlib.h>
int main()
acultad de Inge
{
//Declaracion de variables
char a=1;
unsigned char e;
int c, r1=33000;
unsigned int r=33000;
unsigned int g;
short int b;
unsigned short int f;
long int d;
unsigned long int h;
float i;
double j;
long double k;
//Impresion del tama¤o de las variables en bytes
printf("Longitud de cada uno de los tipos basicos (bytes)\n\n");
printf("La longitud de char a= %d\n",sizeof(a));
printf("La longitud de unsigned char e= %d\n",sizeof(e));
printf("La longitud de int c= %d\n",sizeof(c));
printf("La longitud de unsigned int g= %d\n",sizeof(g));
printf("La longitud de short int b= %d\n",sizeof(b));
printf("La longitud de unsigned short int f= %d\n",sizeof(f));
printf("La longitud de long int d= %ld\n",sizeof(d));
printf("La longitud de unsigned long int: %d\n",sizeof(h));
printf("La longitud de float: %d\n",sizeof(i));
printf("La longitud de double: %d\n",sizeof(j));
printf("La longitud de long double: %d\n",sizeof(k));
//Impresion del rango de algunos tipos de datos
printf("\nValores minimos y maximos de cada uno de los tipos\n\n");
printf("Valores minimo y maximo de char: %d a %d\n",CHAR_MIN,CHAR_MAX);
printf("Valor maximo de unsigned char: %u\n",UCHAR_MAX);
printf("Valor minimo y maximo de int: %d a %d\n",INT_MIN,INT_MAX);
printf("Valor maximo de unsigned int: %u\n",UINT_MAX);
printf("Valor minimo y maximo de short int: %d a %d\n",SHRT_MIN,SHRT_MAX);
printf("Valor maximo de unsigned short int: %u\n",USHRT_MAX);
printf("Valor minimo y maximo de long int: %d a %d\n",LONG_MIN,LONG_MAX);
printf("Valor maximo de unsigned long int: %u\n",ULONG_MAX);
printf("Valor minimo y maximo de float: %g a %g\n",FLT_MIN,FLT_MAX);
printf("Valor minimo y maximo de double: %g a %g\n",DBL_MIN,DBL_MAX);
getchar();
return (EXIT_SUCCESS);
}
2.6.4 Constantes
Las constantes refieren valores
fijos que no pueden ser modificados por el
programa. Pueden ser de cualquier tipo de datos básico. Para marcar que queremos
acultad de Inge
que una variable sea constante se utiliza la palabra reservada const y por convención
el nombre de la constante se escribe en mayúsculas.
const tipo NOMBRE_CONSTANTE = valor;
Ejemplo: Constantes
#include<stdio.h>
/*Prototito de la función*/
void funcion1(void);
/*Declaración de una constante global*/
const float PI=3.1415;
int main()
{
const float PI = 3.1416;
printf("Constante local (dentro del main): %f\n",PI);
/*La expresión de abajo no es válida debido*/
/*a que a una constante no se le puede cambiar su valor*/
/*PI = 3.1415;*/
if(4)
{
const float PI= 3.14;
printf("Constante local (dentro del if): %f\n",PI);
}
/*Llamada a la función*/
funcion1();
printf("Constante local (dentro del main): %f\n",PI);
system("PAUSE");
}
void funcion1(void)
{
/*Impresión de la constante global*/
printf("Constante Global PI = %f\n",PI);
}
2.6.5 Constantes de carácter de barra invertida
Código
Significado
\b
Espacio atrás
\f
Salto de página
acultad de Inge
\n
Salto de línea
\r
Retorno de carro
\t
Tabulación horizontal
\”
Comillas dobles
\’
Comilla simple
\\
Barra invertida
\v
Tabulador vertical
\a
Alerta
\?
Signo de interrogación
\0N
Constante octal (donde N es una constante octal)
\xN
Constante hexadecimal (donde N es una constante hexadecimal)
acultad de Inge
CAPÍTULO 3:
OPERADORES Y EXPRESIONES
C es un lenguaje muy rico en operadores incorporados. De hecho, dota de un
mayor significado a los operadores que la mayoría de los demás lenguajes de
computadora. Hay cuatro clases principales de operadores: aritméticos, relacionales,
lógicos y a nivel de bits
3.1 Operadores aritméticos
Operador
Acción
-
Resta, además de menos monario
+
Suma
*
Multiplicación
/
División
%
Módulo
--
Decremento
++
Incremento
3.2 Operadores relacionales y lógicos
En C, verdadero es cualquier valor distinto de cero. Falso es cero. Las
expresiones que utilizan los operadores relacionales y lógicos devuelven 1 para cierto y
0 para falso.
Operadores relacionales
Operador
acultad de Inge
Acción
>
Mayor que
>=
Mayor o igual que
<
Menor que
<=
Menor o igual que
==
Igual
!=
Distinto
Operadores lógicos
Operador Acción
&&
Y
||
O
!
NO
Tabla de verdad
p q p && q p || q !p p^q
0 0
0
0
1
0
0 1
0
1
1
1
1 0
0
1
0
1
1 1
1
1
0
0
3.3 Operadores a nivel de bits
Dado que C se diseñó para sustituir al lenguaje ensamblador en muchas tareas
de programación, era importante permitir todas las operaciones que se pueden realizar
en ensamblador. Las operaciones a nivel de bits se refieren a la comprobación,
asignación o desplazamiento de los bits reales que componen un byte o una palabra,
que corresponden a los tipos estándar char e int con sus variantes. Estas operaciones
no se pueden usar sobre float, double, long, double, void u otros tipos más complejos.
Operador
acultad de Inge
Acción
&
Y
|
O
^
O exclusiva(XOR)
~
Complemento a uno
>>
Desplazamiento a la derecha
>>
Desplazamiento a la izquierda
3.4 Precedencia de los operadores de C
Mayor () [] -> .
! ~ ++ -- - (tipo) * & sizeof
* / %
+ << >>
< <= > >=
== !=
&
^
|
&&
||
?:
= += -= *= /=
Menor ,
acultad de Inge
CAPÍTULO 4: INSTRUCCIONES DE CONTROL
4.1 Instrucciones de selección
IF
La forma general de la instrucción if es:
if(expresión)
{
instrucciones;
}
else
{
instrucciones;
}
donde la cláusula else es opcional.
Si la expresión es cierta (cualquier valor que no sea 0), se ejecuta la instrucción
o el bloque de instrucciones que constituye el objetivo del if; en caso contrario se
ejecuta la instrucción o el bloque de instrucciones que constituyen el objetivo de else,
si existe. Sólo se ejecuta el código asociado al if o al else, nunca ambos.
SWITCH
C incorpora una instrucción de selección múltiple, denominada switch, que
compara sucesivamente el valor de una expresión con una lista de constantes enteras
o de caracteres. Cuando se encuentra una correspondencia, se ejecutan las
instrucciones asociadas con la constante. La forma general de la instrucción switch es:
switch(expresion)
{
case constante1:
secuencia de instrucciones
break;
case constante2:
secuencia de instrucciones
break;
case constante3:
secuencia de instrucciones
acultad de Inge
break;
.
.
.
default:
secuencia de instrucciones
}
La expresión debe dar como resultado un valor entero. Por tanto, se pueden
utilizar valores enteros o de carácter, mientras que las expresiones reales en coma
flotante, no están permitidas. Se comprueba el valor de la expresión, por orden, con
los valores de las constantes especificadas en las instrucciones case. Cuando se
encuentra una correspondencia, se ejecuta la secuencia de instrucciones asociada con
ese case, hasta que se encuentra la instrucción break o el final de la instrucción switch.
La instrucción default se ejecuta si no se ha encontrado ninguna correspondencia. La
instrucción default es opcional y si no está presente no se ejecuta ninguna acción al
fallar todas las comprobaciones.
La instrucción break es una de las instrucciones de salto de C. Se puede usar en
bucles además de en la instrucción switch. Cuando se encuentra un break en una
instrucción switch, la ejecución del programa salta a la línea de código que sigue a la
instrucción switch.
Hay tres cosas importantes que se deben saber sobre la instrucción switch:

La instrucción switch se diferencia de la instrucción if en que switch sólo puede
comprobar la igualdad, mientras que if puede evaluar expresiones relacionales
o lógicas.

No puede hacer dos constantes case en el mismo switch que tengan los mismos
valores.

Si se utilizan constantes de tipo carácter en la instrucción switch, se convierten
automáticamente a sus valores enteros.
4.2 Instrucciones de iteración
FOR
acultad de Inge
El formato general del bucle for de C se encuentra de una forma u otra en todos
los lenguajes de programación procedimentales. En C, sin embargo, proporciona una
potencia y flexibilidad sorprendentes.
La forma general para la instrucción for es:
for(inicializacion(es);condicion(es);incremento(s))
{
instrucciones;
}
El
bucle
for
admite
muchas
variantes.
Sin
embargo,
la
inicialización
normalmente es una instrucción de asignación que se utiliza para iniciar la variable de
control del bucle. La condición es una expresión relacional que determina cuándo
finaliza el bucle. El incremento define cómo cambia la variable de control cada vez que
se repite el bucle. Estas tres secciones principales deben estar separadas por punto y
coma. El bucle for continúa ejecutándose mientras que la condición sea cierta. Una vez
que la condición se hace falsa, la ejecución del programa continúa con la instrucción
inmediata siguiente saliendo del for.
En los bucles for, la prueba de la condición se hace siempre al principio del
bucle. Esto supone que el código dentro del bucle puede no ejecutarse si la condición
es falsa al comienzo
WHILE
El segundo bucle disponible en C es el bucle while. Su forma general es:
[inicializar]
while(expresión)
{
instrucciones;
[incrementos]
}
La condición puede ser cualquier expresión y cualquier valor distinto de 0 es
cierto. El bucle itera mientras la condición es cierta. Cuando la condición se hace falta,
el control del programa pasa a la línea inmediatamente siguiente al código del bucle.
acultad de Inge
DO WHILE
A diferencia de los bucles for y while, que analizan la condición del bucle al
principio, el bucle do-while comprueba la condición al final. Esto significa que el bucle
do while siempre se ejecuta al menos una vez. La forma general del bucle do while es:
[inicialización]
do
{
instrucciones;
[incrementos]
}
while(expresión);
Aunque las llaves no son necesarias cuando sólo hay una instrucción, se utilizan
normalmente para evitar confusiones con el while. El bucle itera hasta que la condición
se hace falsa.
4.3 Instrucciones de salto
C tiene cuatro instrucciones que llevan a cabo un salto incondicional: return,
goto, break y continue. De ellas se pueden usar return y goto en cualquier parte
dentro de una función. Las instrucciones break y continue se usan junto con
instrucciones de bucle y además también se puede usar break junto con switch.
return
La función return se usa para volver de una función. Se trata de una instrucción
de salto porque hace que la ejecución vuelva al punto en que se hizo la llamada a la
función. Un return puede tener o no un valor asociado. Sólo se puede utilizar un return
con un valor asociado en una función con valor de vuelta de tipo distinto de void. En
ese caso, el valor asociado con return es el valor de vuelta de la función. Un return sin
valor de vuelta se utiliza para volver de las funciones de tipo void.
La forma general de la instrucción return es:
return expresión;
acultad de Inge
La expresión estará presente sólo si se ha declarado la función como
devolviendo un valor. En este caso, el valor de la expresión se convertirá en el valor
devuelto por la función.
Se pueden usar tantas instrucciones return como se quiera en una función. Sin
embargo, la función termina tan pronto como encuentra el primer return. La llave }
que termina el código de la función también hace que se vuelva de ella. Equivale a un
return sin valor específico. Si esto ocurre en una función declarada de un tipo distinto
de void, entonces el valor de vuelta de la función queda indeterminado.
Una función declarada como void no puede contener una instrucción return que
especifique un valor. Dado que las funciones void no devuelven valor, parece lógico
que no contengan ninguna instrucción return que devuelva un valor.
break
La instrucción break tiene dos usos. Se puede usar para finalizar un case en una
instrucción switch. También se puede usar para forzar la terminación inmediata de un
bucle, saltando la evaluación condicional normal del ciclo.
Cuando se encuentra la instrucción break dentro de un bucle, el bucle finaliza
inmediatamente y el control pasa a la instrucción que sigue al bucle.
continue
La instrucción continue funciona de una forma algo similar al break. Sin
embargo, en vez de forzar la terminación, continue fuerza una iteración del bucle y
salta cualquier código que exista entre medias. Para el bucle for, continue hace que se
ejecuten las partes de prueba condicional y de incremento del bucle. Para los bucles
while y do-while, el control del programa pasa a la prueba condicional.
acultad de Inge
CAPÍTULO 5: FUNCIONES
Las funciones son bloques constructores de C y el lugar donde se produce toda la
actividad del programa. Las funciones contienen varias sentencias bajo un solo
nombre, que un programa puede utilizar una o más veces para ejecutar dichas
sentencias. Las funciones ahorran espacio, reduciendo repeticiones y haciendo más
fácil la programación, proporcionando un medio de dividir un proyecto grande en
módulos pequeños más manejables. La división del código en funciones hace que las
mismas se puedan reutilizar en su programa y en otros programas.
5.1 Forma general de una función
La forma general de una función es:
tipo_dato_retorno nombreFunción(lista de parámetros)
{
cuerpo de la función
return expresión;
}
El tipo de dato de retorno especifica el tipo de dato que devuelve la función.
Una función puede devolver cualquier tipo de dato excepto un array. La lista de
parámetros es una lista de nombres separados por comas con sus tipos asociados. Los
parámetros reciben los valores de los argumentos cuando se llama a la función. Una
función puede no tener parámetros, en cuyo caso la lista de parámetros vacía se
puede especificar explícitamente como tal colocando la palabra clave void entre los
paréntesis.
En las declaraciones de variables se pueden declarar múltiples variables del
mismo tipo mediante una lista con los nombres de las variables separadas por comas.
En cambio, en las funciones todos los parámetros deben declararse individualmente,
incluyendo para cada uno tanto el tipo como el nombre.
f(tipo var1, tipo var2, …, tipo varN)
acultad de Inge
5.2 Prototipos de las funciones
La declaración de una función se denomina prototipo. Específicamente un prototipo
consta de los siguientes elementos: nombre de la función, una lista de parámetros
encerados entre paréntesis y un punto y coma. En C no es obligatorio incluir el
prototipo aunque sí es recomendable para que el compilador pueda hacer chequeos en
las llamadas a funciones. Los prototipos se sitúan normalmente al principio de un
programa, antes de la definición de la función main(). Cuando se usan prototipos, el
compilador puede encontrar e informar sobre conversiones de tipos ilegales entre el
tipo de los argumentos usados en la llamada a la función y las definiciones de tipos de
sus parámetros. El compilador también detectará diferencias entre el número de
argumentos usados en la llamada a la función y el número de parámetros de la misma.
5.3 Parámetros de una función
C siempre utiliza el método de parámetros por valor para pasar variables a funciones.
Para que una función devuelva un valor a través de un argumento hay que pasar la
dirección de la variable, y que el argumento correspondiente de la función sea un
puntero; es la forma de conseguir en C un paso de parámetros por referencia. C
permite utilizar punteros para implementar parámetros por referencia, ya que por
defecto, en C el paso de parámetros es por valor. Los parámetros por valor reciben
copias de los valores de los argumentos que se les pasan. La asignación a parámetros
por valor de una función no cambia el valor del argumento original pasado a los
parámetros. Los parámetros por referencia (declarados con *, punteros) reciben la
dirección de los argumentos pasados; a estos les debe preceder el operador &, excepto
los arrays. En una función, las asignaciones a parámetros por referencia (punteros)
cambian los valores de los argumentos originales. Con el objeto de añadir seguridad
adicional a las funciones, se puede añadir a la descripción de un parámetro la palabra
const, que indica al compilador que son sólo para pasar información al interior de la
función. Si se intenta modificar este parámetro se producirá un mensaje de error.
acultad de Inge
Ejemplos: Funciones
/*
Calcula el factorial por medio de una función
*/
#include<stdio.h>
/*Prototipo de la función*/
float factorial(int numero);
int main(void)
{
int num;
printf("Dame un numero para calcular el factorial: ");
scanf("%d",&num);
printf("\nEl factorial de %d es: %.1f",num,factorial(num));
fflush(stdin);
getchar();
}
/* Función que calcula el factorial*/
float factorial(int numero)
{
int i;
float factorial = 1;
for(i=1;i <= numero;i++)
factorial = factorial * i;
return factorial;
}
/*
Función que identifica si un número es primo
Hace la suma de los primos comprendidos entre 1 y 100
*/
#include<stdio.h>
/*Prototipo de la función*/
char primo(int numero);
int main()
{
int i, suma=0;
for(i=1;i <= 100;i++)
if(primo(i) == 's')
suma = suma + i;
acultad de Inge
printf("La suma de los números primos comprendidos\n");
printf("entre 1 y 100 es: %d",suma);
getchar();
}
/*Función que identifica si un número es o no primo*/
char primo(int numero)
{
int i;
for(i=2;i < numero;i++)
if(!(numero%i))
return 'n';
return 's';
}
/*
Suma el valor ascii de los elementos de un arreglo de caracteres
*/
#include<stdio.h>
/*Prototipo de la función*/
int sumaArreglo(char arr[]);
int main()
{
char cadena[] = "Hola a todos";
printf("La suma de los
%d",sumaArreglo(cadena));
respectivos
ascii
getchar();
}
/*Función que suma los elementos de un arreglo*/
int sumaArreglo(char arr[])
{
int i, sumaAscii = 0;
for(i=0;arr[i] != '\0';i++)
sumaAscii = sumaAscii + arr[i];
return sumaAscii;
}
/*
Convierte cadena a mayúsculas
*/
#include<stdio.h>
#include<ctype.h>
acultad de Inge
de
la
cadena
es:
/*Prototipo de la función*/
char *cadenaUpper(char *cadena);
int main()
{
char *apuntadorCadena, cad[] = "Hola, como estan?";
int *ap;
apuntadorCadena = cadenaUpper(cad);
printf("%s",apuntadorCadena);
getchar();
}
/*
Función que convierte cadena a mayúsculas
Paso de parámetros por referencia (apuntadores)
La función regresa un apuntador a char
*/
char *cadenaUpper(char *cadena)
{
int i;
for(i=0;*(cadena+i) != '\0';i++)
if(!isupper(*(cadena+i)))
*(cadena+i) = toupper(*(cadena+i));
return cadena;
}
5.4 Argumentos de main()
Algunas veces resulta útil pasar información al programa cuando se ejecuta. El método
general es pasar información a la función main() mediante el uso de argumentos desde
la línea comandos. Un argumento de este tipo es la información que sigue al nombre
del programa en la línea de comandos del sistema operativo. Por ejemplo, cuando se
compila un programa, puede que se escriba algo como lo siguiente:
gcc nombrePrograma
donde nombrePrograma es el programa que se va a ejecutar.
Hay dos argumentos ya incorporados, argc y argv, que se utilizan para argumentos
desde la línea de comandos. El parámetro argc contiene el número de argumentos y es
acultad de Inge
un entero. Siempre vale 1 por lo menos, ya que el nombre del programa cuenta como
el primer argumento. El parámetro argv es un puntero a un array de punteros a
caracteres. Cada elemento del array apunta a un argumento de línea de comandos.
Todos los argumentos son cadenas; si se necesita un valor numérico, tendrá que ser
convertido manualmente por el programa.
int main(int argc, char *argv[])
Ejemplo: Argumentos al main
#include<stdio.h>
int main(int argc, char *argv[])
{
printf("Valor de argc: %d\n\n",argc);
while(argc != 0)
{
printf("Argumento argv[%d]: %s\n",argc-1,argv[argc-1]);
argc--;
}
getchar();
return 0;
}
El programa anterior tiene el nombre de argumentosMain.c. Desde la línea de
comandos se compila de la siguiente manera:
gcc argumentosMain.c –o argumentosMain
y se ejecuta como:
argumentosMain uno dos tres
acultad de Inge
En donde uno, dos y tres son las cadenas pasadas al programa desde la línea de
comandos.
acultad de Inge
CAPÍTULO 6: ARRAYS Y CADENAS
Un array es una colección de variables del mismo tipo que se referencian por un
nombre común. A un elemento específico de un array se accede mediante un índice.
En C, todos los arrays constan de posiciones de memoria contiguas. La dirección más
baja corresponde al primer elemento y la dirección más alta al último elemento. Los
arrays pueden tener de una a varias dimensiones. El array más común es la cadena,
que simplemente es un array de caracteres terminado por un nulo.
6.1 Arrays unidimensionales
La forma general de declaración de un array unidimensional es:
tipo nombre_variable[tamaño];
Como en otros lenguajes, los arrays tienen que declararse explícitamente para
que así el compilador pueda reservar espacio de memoria para ellos. Aquí tipo declara
el tipo base del array, que es el tipo de cada elemento del array. El valor de tamaño
indica cuantos elementos mantendrá el array.
Ej.
char cadena[10];
int n[5];
Un elemento se puede acceder indexando el nombre del array. Esto se hace
colocando el índice del elemento entre corchetes justo detrás del nombre del array.
Ej.
cadena[2] = ‘s’;
// Asigna el valor de ‘s’ al elemento 2 del arreglo.
En C, todos los arrays tienen el 0 como índice de su primer elemento.
acultad de Inge
6.2 Almacenamiento en memoria de los arrays
Los elementos de los arrays se almacenan en bloques contiguos de memoria.
Se pueden referenciar elementos del array utilizando formulas o expresiones enteras
para los subíndices.
Ejemplo:
Si a es un array de números reales y si a[0] ocupa la dirección x, el elemento
a[i] ocupa la dirección de memoria x+(i-1)*4
6.3 Tamaño de arrays
El operador sizeof devuelve el número de bytes necesarios para contener su
argumento. Si se usa sizeof para solicitar el tamaño de un array, esta función devuelve
el número de bytes reservados para el array completo. Si se conoce el tipo de dato
almacenado en el array y su tamaño, tenemos que la longitud del array, mediante el
cociente sizeof/tamaño (dato).
Ejemplo:
#include <stdio.h>
int main()
{
char c; /* crea el dato de tipo char */
short s;
/* crea el dato de tipo short */
int i;
/* crea el dato de tipo int */
long l;
/* crea el dato de tipo long */
float f;
/* crea el dato de tipo float */
double d;
/* crea el dato de tipo double */
long double ld;
/* crea el dato de tipo long double */
int arreglo[ 20 ];
/* crea el arreglo de 20 elementos int */
int *ptr = arreglo; /* crea el apuntador al arreglo int */
printf("\n char = %d \n", sizeof (c));
printf("\n short = %d \n", sizeof (s));
printf("\n int = %d \n", sizeof (i));
acultad de Inge
printf("\n long = %d \n", sizeof (l));
printf("\n float = %d \n", sizeof (f));
printf("\n double = %d \n", sizeof (d));
printf("\n long double = %d \n", sizeof (ld));
printf("\n arreglo = %d \n", sizeof (arreglo));
printf("\n puntero = %d \n", sizeof (ptr));
getch();
return 0;
}
6.4 Inicialización de un array
Se pueden asignar valores a los arrays antes de ser utilizados. Para asignarlos a
cada elemento del array de enteros p, se hace lo siguiente:
p[0] = 10; p[1] = 20; p[2] = 30; p[3] = 40; p[4] = 50;
Sin embargo, este método no es practico cuando el array contiene muchos
elementos, se utiliza normalmente inicializar el array completo en una sola sentencia.
Cuando
se
inicializa
un
array
el
tamaño
del
array
se
puede
determinar
automáticamente por las constantes de inicialización. Estas constantes se separan por
comas y se encierran entre llaves.
Ejemplo:
int num [6] = {10, 20, 30, 40, 50, 60};
int x [ ] = {1, 2, 3};
/* Declara un array de 3 elementos */
char ch [ ] = {‘P’, ‘A’, ‘Y’, ‘M’, ‘N’}; /* Declara un array de 5 elementos*/
acultad de Inge
6.5 Cadenas
El uso más común de los arrays unidimensionales, con mucho, es como cadenas
de caracteres. En C, una cadena es un array de caracteres terminado en nulo. Por
tanto, una cadena contiene los caracteres que la conforman seguidos de un nulo. La
cadena terminada en nulo es el único tipo de cadena definido en C.
C incluye una gran variedad de funciones de manipulación de cadenas. Algunas
de estas son:
Nombre
strcpy(c1,c2)
Función
Copia c2 en c1
char *strcpy(char *s1, const char *s2);
strcat(c1,c2)
Concatena c2 al final de c1
char *strcat(char*s1, const char *s2);
strlen(c1)
Devuelve la longitud de c1
size_t strlen(const char *s);
strcmp(c1,c2) Devuelve 0 si c1 y c2 son iguales; menor que 0 si c1 < c2; mayor que
0 si c1 > c2.
int strcmp(const char *s1, const char *s2);
strchr(c1,car) Devuelve un puntero a la primera ocurrencia de car en c1
char *strchr(char *s, int c);
strstr(c1,c2)
Devuelve un puntero a la primera ocurrencia de c2 en c1.
char *strstr(const char *s1, const char *s2);
Estas funciones usan el archivo de cabecera estándar <string.h>.
6.6 Arrays bidimensionales
acultad de Inge
C admite arrays multidimensionales. La forma más simple de un array
multidimensional es el array bidimensional.
tipo_dato nombre_del_arreglo[r][c];
Ej.
int x[3][4]; //Declaración de un arreglo bidimensional de 3 renglones y 4
columnas
Los arrays bidimensionales se almacenan en matrices fila-columna, en las que
el primer índice indica la fila y el segundo indica la columna.
6.7 Inicialización de arrays bidimensionales
Los arrays bidimensionales se pueden inicializar, al igual que los de una
dimensión, cuando se declaran. La inicialización consta de una lista de constantes
separadas por comas y encerradas entre llaves.
Ejemplo:
int arreglo [2],[3] = {1, 2, 3, 4, 5, 6};
acultad de Inge
CAPÍTULO 7: PUNTEROS
7.1 ¿Qué son los punteros?
Un puntero es una variable que contiene una dirección de memoria. Esa
dirección es la posición de otro objeto (normalmente otra variable) en memoria. Por lo
tanto se dice que si una variable (puntero) contiene la dirección de otra variable la
primera variable apunta a la segunda. Los punteros están muy relacionados con los
arrays y proporcionan una vía alternativa de acceso a los elementos individuales del
array.
Adicionalmente debemos de tomar en cuenta que dentro de la memoria de la
computadora, cada dato almacenado ocupa una o más celdas contiguas de memoria,
es decir, bytes adyacentes. El número de celdas de memoria requeridas para
almacenar un dato depende de su tipo. Por ejemplo, un carácter se almacenará
normalmente en un byte (8 bits) de memoria; un entero usualmente necesita 4 bytes
contiguos al igual que un tipo flotante; y una cantidad en doble precisión puede
requerir ocho bytes contiguos.
7.2 Declaración de apuntadores
Si una variable va a ser puntero, entonces antes de ser utilizada debe de
declararse como tal. Una declaración de puntero consiste en un tipo de dato, un * y el
nombre de la variable. Además, debe seguir las convenciones para nombres de
variables.
La sintaxis general de declaración es:
tipo_dato *nombreApuntador;
Ejemplos:
1. int *apunEntero;
2. float *apunReal;
acultad de Inge
3. char *apunCaracter;
El apuntador apunEntero es un apuntador a int, el apuntador apunReal es un
apuntador a float y el apuntador apunCaracter es un apuntador a char, el tipo de dato
del puntero define el tipo de variables a las que puede apuntar el apuntador.
Los operadores de puntero
Hay dos operadores de punteros: & y *. & es un operador monario que devuelve la
dirección de memoria de su operando. Por ejemplo:
int x  10,*apunEntero;
apunEntero  & x;
pone en apunEntero la dirección de memoria en donde está almacenada la variable
x.
Por lo tanto se puede pensar en el operador & como devolviendo “la dirección de”. Por
lo tanto la instrucción de asignación anterior significa “ apunEntero recibe la dirección
de
x ”.
Para entender bien la asignación anterior, supongamos que la variable
x utiliza
la posición de memoria AFFB para guardar el valor de 10. Entonces, después de la
asignación,
apunEntero contiene el valor de AFFB.
El segundo operador de punteros, *, es el complemento de &. Es un operador
monario que devuelve el valor que se encuentra en la dirección que le sigue. Por
ejemplo,
#include<stdio.h>
int main()
{
int x=2,y=3;
int *apunEntero; /*Declaracion de un puntero tipo entero*/
/*Impresion de los valores de las variables*/
acultad de Inge
printf("x=%d, y=%d, apunEntero=%p\n\n",x,y,apunEntero);
apunEntero
=
&x;
/*Se
le
asigna
la
dirección
de
x
al
puntero
apunEntero*/
/*Imprime
los
valores
de
las
direcciones
de
memoria
de
x
y
el
apuntador. En
este caso son iguales*/
printf("Dir x: %p, Dir apuntador: %p\n\n",&x,apunEntero);
/*Se le asigna a y el valor localizado en la direccion del apuntador
apunEntero */
y = *apunEntero;
printf("x=%d, y=%d\n\n",x,y);
/*Se almacena el valor de 5 en la direccion de memoria de apunEntero*/
*apunEntero = 5;
printf("Lo
que
hay
en
la
direccion
%p:
%d\n\n",apunEntero,*apunEntero);
system("PAUSE");
}
7.3 Punteros y Arrays
Los arrays y los punteros mantienen una estrecha relación en el lenguaje C. El
nombre de un array es un puntero, contiene la dirección en memoria de comienzo de
la secuencia de los elementos que forma el array. Es un puntero constante ya que no
se puede modificar, solo se puede acceder para indexar a los elementos del array.
Consideremos el siguiente fragmento como ejemplo:
char cad[80], *p1;
p1 = cad;
A p1 le ha sido asignada la dirección del primer elemento del array cad. Para acceder
al quinto elemento de cad se escribe:
acultad de Inge
cad[4]
o bien,
*(p1+4);
Se puede declarar un array de punteros, como array que contiene como elementos
punteros, cada uno de los cuales apuntará a otro dato especifico. Por ejemplo:
int *p[10];
en la lineal anterior se reserva un array de diez variables punteros a enteros.
7.4 Punteros de cadenas
La siguiente declaración es un array de caracteres que contiene las veintiséis
letras del alfabeto internacional.
char alfabeto[27] = “ABCDEFGHIJKLMNOPQRSTUVWXYZ”;
si p es un puntero a char:
p = &alfabeto[0];
/* Se obtiene la dirección de letra A */
p = &alfabeto[4];
/* Se obtiene la dirección de la letra E */
p = &alfabeto[8];
/* Se obtiene la dirección de la letra I */
p = &alfabeto[14];
/* Se obtiene la dirección de la letra O */
p = &alfabeto[20];
/* Se obtiene la dirección de la letra U */
7.5 Punteros a funciones
Es posible también crear punteros que apunten a funciones. En lugar de
direccionar datos, los punteros de funciones apuntan a código ejecutable. Al igual que
los datos, las funciones se almacenan en memoria y tienen direcciones iniciales. Tales
funciones se pueden llamar en un modo indirecto, es decir, mediante un puntero cuyo
valor es igual a la dirección inicial de la función en cuestión.
acultad de Inge
La sintaxis general para la declaración de un puntero a una función es:
tipo_de_retorno (*PunteroFuncion) (<lista de parámetros>);
Este formato indica al compilador que PunteroFuncion es un puntero a una función que
devuelve el tipo Tipo_dato_retorno y tiene una lista de parámetros. Un puntero a una
función es un puntero cuyo valor es la dirección del nombre de la función.
acultad de Inge
CAPÍTULO 8: ESTRUCTURAS
8.1 Definición
Una estructura es una colección de variables que se referencia bajo un mismo
nombre, proporcionando un medio conveniente de mantener junta una información
relacionada. Una declaración de estructura forma una plantilla que puede utilizarse
para crear objetos estructuras (ejemplares de una estructura). Las variables que
componen a la estructura se llaman miembros de la estructura.
La forma general para declarar una estructura es la siguiente:
struct nombreEstructura
{
tipo miembro1;
tipo miembro2;
tipo miembro3;
…
…
…
tipo miembro n-1;
tipo miembro n;
}[variables de estructura];
La palabra clave struct indica al compilador que se está declarando una
estructura. Y la declaración termina con un punto y coma. Para declarar una estructura
que represente a una persona sería como sigue:
struct persona
{
char nombre[70];
char direccion[120];
unsigned int edad;
float ingresoMensual;
char sexo;
};
En este momento tenemos una estructura llamada persona, con 5 miembros,
pero todavía no se tienen las variables que representen a diferentes personas. Para
eso hacemos lo siguiente:
acultad de Inge
struct persona estudiante, obrero, empresario;
Ya hemos declarado tres variables del tipo estructura las cuales son: estudiante,
obrero y empresario. Cada variable mantiene “dentro” de ella los 5 miembros de la
estructura persona. Por ejemplo, el miembro nombre de estudiante está aparte y es
distinto del miembro nombre para obrero y empresario. Lo anterior lo podemos hacer
en un solo paso:
struct persona
{
char nombre[70];
char direccion[120];
unsigned int edad;
float ingresoMensual;
char sexo;
} estudiante, obrero, empresario;
8.2 Acceso a los miembros de la estructura
Los miembros individuales de la estructura se acceden a través del operador
.
(denominado usualmente operador punto). Para tener acceso a los miembros de las
variables de estructura hacemos lo siguiente:
variableDeEstructura.miembro
8.3 Asignación de valores
Usando la variable estudiante de la estructura persona:

strcpy(estudiante.nombre,”Israel Duran Martinez”);

strcpy(estudiante.direccion,”Calle 11 numero 14-A”);

estudiante.edad = 32;

estudiante.ingresoMensual = 10.21;

estudiante.sexo = ‘M’;
Usando la variable obrero de la estructura persona:

strcpy(obrero.nombre,”Israel Duran Martinez”);

strcpy(obrero.direccion,”Calle 11 numero 14-A”);
acultad de Inge

obrero.edad = 32;

obrero.ingresoMensual = 10.21;

obrero.sexo = ‘M’;
8.4 Punteros a estructuras
C permite punteros a estructuras igual que permite punteros a cualquier otro
tipo de variables. Sin embargo, hay algunos aspectos especiales que afectan a los
punteros a estructuras.
Declaración de un puntero a una estructura
Al igual que los demás punteros, los punteros
a estructuras se declaran
escribiendo * delante del nombre de la variable de una estructura. Por ejemplo,
asumiendo la estructura dir previamente definida, lo siguiente declara puntero_dir
como un puntero a un dato de ese tipo:
struct dir *puntero_dir;
Uso de punteros a estructuras
Existen dos usos principales de los punteros a estructuras: generar un paso por
referencia de una estructura a una función y crear listas enlazadas y otras estructuras
de datos dinámicas utilizando el sistema de asignación dinámica de memoria.
Cuando se pasa a una función un puntero a una estructura, solo se introduce en
la pila la dirección de memoria. Esto significa que la llamada a la función es muy
rápida. Para encontrar la dirección de una variable de estructura se coloca el operador
& antes del nombre de la estructura.
acultad de Inge
Ejemplo:
struct bal
{
float balance;
char nombre[80];
} persona;
struct bal *p;
/* declaración de un puntero a estructura */
en la siguiente línea se obtiene la dirección de memoria de la estructura
persona en el puntero p:
p = &persona;
En el siguiente ejemplo se puede apreciar claramente el funcionamiento de los
operadores en punteros:
#include<stdio.h>
int main()
{
int x=10,y;
int *punteroEntero;
printf("x=%d\n",x);
printf("punteroEntero=%p\n",punteroEntero);
//Asignar la direccion de x a punteroEntero
punteroEntero = &x;
y=*punteroEntero;
printf("x=%x\n",y);
//Imprime la direcion de memoria de x y de punteroEntero
printf("punteroEntero=%p\n",punteroEntero);
printf("Direccion de x=%p\n",&x);
//Imprime el contenido asignado al puntero
acultad de Inge
*punteroEntero = 15;
printf("Contenido del puntero=%d\n",*punteroEntero);
printf("x=%d\n",x);
getchar();
return 0;
}
acultad de Inge
CAPÍTULO 9: ARCHIVOS
En C, un archivo puede ser cualquier cosa, desde un archivo de disco hasta una
terminal o una impresora. Mediante una operación de apertura se asocia una secuencia
con un archivo específico. Una vez que el archivo está abierto, se puede intercambiar
información entre éste y el programa.
9.1 Manejo de Archivos
Cada secuencia asociada a un archivo tiene una estructura de control de tipo
FILE. La librería en donde se encuentran las funciones para manejar archivos es
<stdio.h>
Nombre
Función
fopen( )
Abre un archivo.
fclose( )
Cierra un archivo.
putc( )
Escribe un carácter en un archivo.
fputc( )
Lo mismo que putc().
getc( )
Lee un carácter de un archivo.
fgetc( )
Lo mismo que getc().
fgets( )
Lee una cadena de un archivo.
fputs( )
Escribe una cadena en un archivo.
fseek( )
Localiza un byte específico de un archivo.
ftell( )
Devuelve la posición actual en el archivo.
fprintf( )
Hace lo mismo que printf( ) solo que sobre el archivo.
fscanf( )
Hace lo mismo que scanf( ) solo que sobre el archivo.
feof( )
Devuelve verdadero si se ha llegado al final del archivo.
ferror( )
Devuelve verdadero si se ha producido algún error.
rewind( )
Coloca el indicador de posición del archivo al inicio del mismo.
remove( ) Elimina un archivo.
fread()
Lee de un archivo
fwrite()
Escribe en un archivo
fflush( )
acultad de Inge
Vacía un archivo.
A continuación se presenta cada función con su prototipo y un pequeño
ejemplo.
fopen()
La función fopen() abre una secuencia para que pueda ser utilizada y
vincula un archivo con la misma. Después devuelve el puntero al archivo asociado con
ese archivo. La función fopen() tiene este prototipo:
FILE *fopen(const char *Archivo,
const char *Modo);
fclose()
La función fclose() cierra una secuencia que haya sido abierta con una
llamada a fopen(). Escribe en el archivo toda la información que todavía se encuentre
en el búfer del disco y realiza un cierre formal del archivo a nivel sistema operativo. La
función fclose() tiene este prototipo:
int fclose(FILE
*Archivo);
putc()
Permite escribir un carácter Car en el flujo asociado a archivo. Tiene el
siguiente prototipo:
int putc(int Car, FILE *ARCHIVO);
Ejemplo:
putc(Car, Archivo);
fputc()
Permite escribir un carácter en el flujo asociado a Archivo. Tiene el
siguiente prototipo:
int fputc(int Car, FILE *ARCHIVO)
acultad de Inge
Ejemplo:
fputc(Car, Archivo);
getc()
Proporciona el siguiente carácter de flujo de entrada asociado a Archivo,
avanzando el apuntador del archivo al siguiente carácter. Si el apuntador ha
llegado al final proporciona EOF. Tiene el siguiente prototipo:
int getc(FILE *Archivo)
Ejemplo:
FILE *Archivo;
Car=getc(Archivo);
while(Car!=EOF);
printf(“%c, Car”);
Car=getc(Archivo);
fgetc()
Proporciona el siguiente carácter de flujo de entrada asociado a Archivo,
avanzando el apuntador del archivo al siguiente carácter. Si el apuntador ha
llegado al final proporciona EOF. Tiene el siguiente prototipo:
int fgetc(FILE *Archivo);
Ejemplo:
FILE *Archivo;
Car = fgetc(Archivo);
while(Car!=EOF)
printf(“%c, Car”);
Car=fgetc(Archivo);
acultad de Inge
fgets()
Permite leer hasta Numero-1 caracteres del flujo de entrada asociado a
Archivo; y los coloca en el arreglo de caracteres apuntado por Cadena. Archivo y
Cadena están cualificados por restrict. Si no tiene éxito devuelve el valor NULL.
Tiene el siguiente prototipo:
char *fgets(char *Cadena, int Numero, FILE *Archivo)
Ejemplo:
FILE *Archivo;
fgets(Cadena, 20, Archivo)
while(Cadena!=NULL)
printf("%s",Cadena);
fgets(Cadena, 20, Archivo)
fputs()
Permite escribir el contenido del arreglo de caracteres apuntado por Cadena;
en el flujo asociado a Archivo. En C99; Archivo y Cadena están cualificados por
restrict. Tiene el siguiente prototipo:
int fputs(const char *Cadena,
Ejemplo:
fputs(Cadena, Archivo);
acultad de Inge
FILE *Archivo);
fseek()
Permite colocar el apuntador del archivo asociado al nombre Archivo a
cuantos bytes de Origen. Donde Origen puede ser desde el principio del archivo (0
ó SEEK_SET); desde la posición actual (1 ó SEEK_CUR) o desde el final del archivo
(2 ó SEEK_END). Tiene el siguiente prototipo:
int fseek(FILE *Archivo,
long int Cuantos,
int Origen);
Ejemplo:
FILE *pfile;
fseek (pfile, 5, SEEK_CUR);
ftell()
Proporciona el número de byte donde se encuentra el apuntador del
archivo asociado al nombre Archivo. Proporciona -1 si hay error. Tiene el siguiente
prototipo:
l on g i nt ftell (FILE *Arch i vo);
Ej empl o:
FILE *Archivo;
if( (comienzo=ftell(archivo) ) < 0 )
printf( "ERROR: ftell no ha funcionado" );
else
printf( "Posicion del fichero: %d", comienzo );
fprintf()
Permite escribir en el archivo asociado al nombre físico Archivo, los
elementos indicados por los formatos; mismos que son iguales a los que se usan
en la función printf. Tiene el siguiente prototipo:
int fprintf(FILE *Archivo,
acultad de Inge
const char *Formato)
fscanf()
Permite leer del flujo asociado a Archivo, los elementos indicados por los
formatos; mismos que son iguales a los que se usan en la función scanf. Tiene el
siguiente prototipo:
int fscanf(FILE *Archivo, const char *Formato) ;
feof()
Proporciona un valor diferente de cero si el apuntador del archivo asociado al
flujo Archivo está al final; en caso contrario proporciona el valor cero. Tiene el
siguiente prototipo:
int feof(FILE *Archivo);
Ejemplo:
FILE *Archivo;
while(!feof(Archivo))
/* Procesa */
ferror()
Proporciona el valor cero si no se ha producido error asociado al flujo
Archivo, en caso contrario, proporciona un número diferente de cero. Tiene el
siguiente prototipo:
int ferror(FILE *Archivo);
Ejemplo:
FILE *Archivo;
if(ferror(Archivo))
printf(“Error en el Archivo”);
exit(1);
acultad de Inge
rewind()
Permite colocar el apuntador del archivo identificado por Archivo en el
byte cero. Tiene el siguiente prototipo:
void rewind(FILE *Archivo);
Ejemplo:
FILE *Archivo;
rewind(Archivo);
rename()
Permite cambiar el nombre del archivo identificado
especificado por NuevoArch. Tiene el siguiente prototipo:
e(const
int
rena
char *Archivo,
t char *NuevoArch);
Ejemplo:
FILE *Archivo
rename(Archivo, NuevoArch);
remove()
Permi
eliminar el archivo identificado por
rchivo.
ene el siguien
e prototipo:
i
remove(const char *Archivo);
acultad de Inge
por
Archivo
al
Ejemplo:
FILE *Archivo;
Remove(Archivo);
fread()
Permite leer Cuantos elementos, cada uno de Tamaño bytes, del archivo asociado
nombre físico Archivo; y los coloca en Datos. Tiene el siguiente proto
po:
Si
_t fread(void
Datos, size_Tamaño, siz
_t Cuantos, FILE *Archivo);
Ejemplo:
FILE
*fi chero;
stru ct agenda registro;
fread(&registro,sizeof(registro),1,fichero)
fwrite()
Permite escribir Cuantos elementos, cada uno de tamaño bytes de Datos
el archivo asociado al nombre físico Ar chivo. Tiene el siguiente prototipo:
Si
_t fwrit
(const void *Datos, size_t Tamaño, size_t Cuantos, FILE *Archivo);
Ejemplo:
FILE *fich
acultad de Inge
str
t
agenda registro;
fwrite(&registro,sizeof(registro),1,fichero);
fflush()
Escribe físicame
e en Archivo el contenido de
búfer de s alida. Tiene el siguiente prototipo:
int fflush(FILE *Archivo);
Ejemplo:
FILE *Archivo;
fflush(Archivo);
9.2 El puntero a archivo
El puntero a archivo es el hilo conductor que unifica el sistema de E/S de C. Un
puntero a archivo es un puntero a una estructura de tipo FILE. Apunta a información
que define varias cosas sobre el archivo, incluyendo su nombre, su estado y la posición
actual dentro de él. En esencia, el puntero a archivo identifica un archivo específico y
es utilizado por la secuencia asociada para dirigir el funcionamiento de las funciones de
E/S. Para leer o escribir sobre archivos, los programas tienen que utilizar punteros.
Para di
oner de una
variable
acultad de Inge
unte
ro a
arch
ivo
e
utili
za
una
inst
cció
n
com
o
e
ta:
FIL
E
*arc
h;
Eje
mpl
:
#inc
lude
<std
io.h
>
#inc
acultad de Inge
lude
std
lib
.h>
int
mai
n()
{
//P
unt
ero
s
arc
hiv
o
FIL
E
*le
c
ura
,
*es
cri
tur
a;
cha
r
c,
lin
ea[
100
acultad de Inge
0];
int
i,
con
t=0
//A
bri
mos
arc
hiv
os
if(
(le
ctu
ra=
fop
en(
"
rch
ivo
Sal
ida
txt","r")) == NULL)
{
printf("No se puede abrir el archivo");
getchar();
exit(1);
}
if((escritura=fopen("copia
rchivoSalida
acultad de Inge
txt","w"))
==
ULL)
{
printf("No s
p
ede abrir el archivo");
getchar
);
exit(1);
}
while(!fe
f(lectura))
{
//Leemos las line
s de
arc
ivo
fgets(linea,1000
lectura);
fpr
ntf(escritura,"%s",
inea);
}
//Ce
r
mos
archivos
fclose(lectura);
fclose(escritura);
//getchar();
return 0;
}
acultad de Inge
9.3 Apertura de un archivo
La función fopen() abre una secuencia para que pueda ser utilizada y vincula un
archivo con la misma. Después devuelve el puntero al archivo asociado con ese
archivo. A menu
el archivo es un archivo de disco. La función fop
() tiene este prototipo:
FILE *fopen(const char *nombre, const char *modo);
Donde nombre es un puntero a una cadena de caracteres que representa un
nombre válido de archivo y puede incluir una especificación de r
a. La cadena a la que apunta modo determina de qué forma se abre el
archivo.
Ejem
lo:
FILE *pfile;
pfile = fopen ( "ejemplo.txt" , "w" )
if(pfile == N
LL)
{
rint
ROR, no se puede abrir el archivo");
getchar();
exit(1);
}
acultad de Inge
9.4 Cierre de un archivo
La función fclose( ) cierra una secuencia que haya sido abierta con una llamada
a fopen( ). Escribe en el archivo toda la información que todavía se encuentre en el
búfer del disco y realiza el cierre formal del archivo a nivel del sistema operativo. Un
error en el cierre de una secuencia puede generar todo tipo de problemas, incluyendo
la pérdida de datos, destrucción del archivo y otros posibles errores intermitentes en el
programa. Como existe un límite en el número de archivos que pueden estar abiertos
si
ltáneamente, puede re
ltar nec
sar
io
cer
rar
un
arc
hiv
o
ant
es
de
abr
ir
otr
o.
int
fc
ose
(FI
LE
acultad de Inge
*fp
)
Eje
m
lo:
FIL
E
*pf
ile
;
pfi
le
=
fop
en
(
"ej
emp
lo.
txt
"
,
"w"
)
if(
pfi
le
==
N
LL)
{
rin
t
("E
acultad de Inge
RRO
R,
no
se
ede abrir el archivo");
getchar();
exit(1);
}
fclose (pfile);
Modo de apertura de archivos:
Nombre
Función
R
A
bre
un archivo de texto para lectura.
W
Crea un archivo de texto para escritura.
A
A
bre
un
arch
i
o de texto para añadir información.
Rb
Abre un archivo binario para lectura.
w
acultad de Inge
b
Cre
a un
arch
iv
binario para escritura.
ab
Abre un archivo binario para añadir información.
r+
A
bre
un
arch
ivo
de
text
para lectura/escritura.
w+
Crea un archivo de texto para lectura/escritura.
Ab
e un archivo de
texto en modo
lectura/escritura
para añadir información.
r+b
Abre un archivo binario para lectura/escritura.
w
+b
Cr
ea
un
arch
acultad de Inge
ivo
bina
rio
par
a
lect
ura/
escr
itur
a.
a
+b
A
br
o crea un archivo binario en modo lectura/escritura para añadir información.
ibliograf
SCHILDT HERBERT
Manual de referencia C
España, McGraw-Hill, 2001
709 págs.
JOYANES

IS
Programación
en C Libro de Pro
lemas
España, McGraw-Hill
2004
390
á
.
acultad de Inge
T
RIED BYRON
Programación en C
España
ll, 2005
659 págs.
acultad de Inge
McGraw-H