Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Lenguaje C
Lenguaje C
El lenguaje de programacin C
Tema 1 - Introduccin.
El lenguaje de programacin C fue creado por Brian Kernighan y Dennis
Ritchie a mediados de los aos 70. La primera implementacin del mismo la realiz
Dennis Ritchie sobre un computador DEC PDP-11 con sistema operativo UNIX. C es
el resultado de un proceso de desarrollo que comenz con un lenguaje anterior, el
BCPL, el cual influy en el desarrollo por parte de Ken Thompson de un lenguaje
llamado B, el cual es el antecedente directo del lenguaje C. El lenguaje C es un
lenguaje para programadores en el sentido de que proporciona una gran flexibilidad de
programacin y una muy baja comprobacin de incorrecciones, de forma que el
lenguaje deja bajo la responsabilidad del programador acciones que otros lenguajes
realizan por si mismos. As, por ejemplo, C no comprueba que el ndice de referencia
de un vector (llamado array en la literatura informtica) no sobrepase el tamao del
mismo; que no se escriba en zonas de memoria que no pertenecen al rea de datos del
programa, etc.
El lenguaje C es un lenguaje estructurado, en el mismo sentido que lo son otros
lenguajes de programacin tales como el lenguaje Pascal, el Ada o el Modula-2, pero
no es estructurado por bloques, o sea, no es posible declarar subrutinas (pequeos
trozos de programa) dentro de otras subrutinas, a diferencia de como sucede con otros
lenguajes estructurados tales como el Pascal. Adems, el lenguaje C no es rgido en la
comprobacin de tipos de datos, permitiendo fcilmente la conversin entre diferentes
tipos de datos y la asignacin entre tipos de datos diferentes, por ejemplo la expresin
siguiente es vlida en C:
float a; /*Declaro una variable para numeros reales*/
int b; /*Declaro otra variable para numero enteros*/
b=a; /*Asigno a la variable para entera el numero real*/
break
double
if
case
else
int
char
enum
long
const
extern
register
continue
float
return
default
for
short
El lenguaje de programacin C
signed
unsigned
sizeof
void
static
volatile
struct
while
switch
typedef
union
El lenguaje de programacin C
Descripcin.
Carcter o entero pequeo (byte)
Entero
Punto flotante
Punto flotante (mayor rango que
float)
Sin tipo (uso especial)
Tabla 2.2.1: Tipos de datos en C.
El lenguaje de programacin C
Existen, adems, cuatro modificadores de tipo, los cuales se aplican sobre los
tipos de datos anteriormente citados. Los modificadores de tipo permiten cambiar el
tamao, etc., de los tipos de datos anteriormente especificados. Estos modificadores,
que sintcticamente anteceden a la declaracin del tipo de dato, son:
Modificador Tipos de actuacin
Descripcin
Con signo (por defecto)
Sin signo
Largo
Corto
Tabla 2.2.2: Modificadores de los tipos de datos en C.
signed
unsigned
long
short
char
char
int
int
int
int
double
El lenguaje de programacin C
Modificador
const
volatile
Efecto
Variable de valor constante
Variable
cuyo
valor
es
modificado
externamente
Tabla 2.2.4: Modificadores de acceso en C.
Fuera de todas las funciones del programa, son las llamadas variables globales,
accesibles desde cualquier parte del programa.
Dentro de una funcin, son las llamadas variables locales, accesibles tan solo
por la funcin en las que se declaran.
Dentro de un bloque de cdigo del programa, accesible tan solo dentro del
bloque donde se declara. Esta forma de declaracin puede interpretarse como
una variable local del bloque donde se declara.
El lenguaje de programacin C
#include <stdio.h>
int sum; /* Variable global, accesible desde cualquier parte */
/* del programa*/
void suma(int x) /* Variable local declarada como parmetro, */
/* accesible solo por la funcin suma*/
{
sum=sum+x;
return;
}
void intercambio(int *a,int *b)
{
if (*a>*b)
{
int inter; /* Variable local, accesible solo dentro del */
/* bloque donde se declara*/
inter=*a;
*a=*b;
*b=inter;
}
return;
}
int main(void) /*Funcin principal del programa*/
{
int contador,a=9,b=0; /*Variables locales, accesibles solo */
/* por main*/
sum=0;
intercambio(&a,&b);
for(contador=a;contador<=b;contador++) suma(contador);
printf(%d\n,suma);
return(0);
}
Efecto
Variable
local
(por
defecto)
extern
Variable externa
static
Variable esttica
register
Variable registro
Tabla 2.4.1: Especificadores de almacenamiento en C.
El lenguaje de programacin C
El especificador auto se usa para declarar que una variable local existe
solamente mientras estemos dentro de la subrutina o bloque de programa donde se
declara, pero, dado que por defecto toda variable local es auto, no suele usarse.
El especificador extern se usa en el desarrollo de programas compuestos por
varios mdulos. El modificador extern se usa sobre las variables globales del mdulo,
de forma que si una variable global se declara como extern, el compilador no crea un
almacenamiento para ella en memoria, sino que, tan solo tiene en cuenta que dicha
variable ya ha sido declarada en otro modulo del programa y es del tipo de dato que se
indica.
El especificador static acta segn el alcance de la variable:
Para variables locales, el especificador static indica que dicha variable local
debe almacenarse de forma permanente en memoria, tal y como si fuera una
variable global, pero su alcance ser el que correspondera a una variable local
declarada en la subrutina o bloque. El principal efecto que provoca la
declaracin como static de una variable local es el hecho de que la variable
conserva su valor entre llamadas a la funcin.
Para variables globales, el especificador static indica que dicha variable global
es local al mdulo del programa donde se declara, y, por tanto, no ser
conocida por ningn otro mdulo del programa.
2.5 - Constantes.
En C, las constantes se refieren a los valores fijos que el programa no puede
alterar. Algunos ejemplos de constantes de C son:
Tipo de dato
char
int
long int
short int
Constantes de ejemplo
a
9
'Q'
1
-34
21000
-34
67856L 456
10
-12
1500
El lenguaje de programacin C
unsigned int
float
double
45600U 345
3
12.45
4.34e-3 -2.8e9
-34.657 -2.2e-7 1.0e100
Tabla 2.5.1: Tipos de constantes en C.
Significado
Retroceso
Alimentacin de hoja
Nueva lnea
Retorno de carro
Tabulador horizontal
Doble comilla
Simple comilla
Nulo
Barra invertida
Tabulador vertical
Alerta
Constante octal
Constante
hexadecimal
Tabla 2.5.2: Constantes de barra invertida en C.
\b
\f
\n
\r
\t
\
\
\0
\\
\v
\a
\o
\x
El lenguaje de programacin C
Operador
Operador
Incremento
-Decremento
Menos unario
Multiplicacin. /
Divisin
%
Suma
Resta
Tabla 3.1.1: Operadores aritmticos en C.
Mdulo
Los operadores ++, -- y % solo pueden usarse con datos de tipo int o char. El
operador incremento (++), incrementa en una unidad el valor de la variable sobre la
que se aplica, el operador decremento (--), decrementa en una unidad el valor de la
variable, y el operador mdulo (%), calcula el resto de una divisin de dos variables de
tipo entero o carcter.
Un aspecto que conviene explicar es el hecho de que los operadores incremento
y decremento pueden preceder o posceder a su operando, lo cual permite escribir, si x
es una variable de tipo int, las expresiones ++x o x++. Usado de forma aislada no
presenta ninguna diferencia, sin embargo, cuando se usa en una expresin existe una
diferencia en el orden de ejecucin del mismo. Cuando el operador incremento (o
decremento) precede al operando, C primero realiza el incremento (o decremento), y
despus usa el valor del operando, realizndose la operacin al contrario si el operador
poscede al operando. As, considrense el siguiente cdigo de un programa:
int var1=10,var2;
var2=++var1; /* Pone 11 en var2, pues primero incrementa var1,*/
/* y luego asigna su valor a var2 */
El lenguaje de programacin C
Operador
>=
Operador
Mayor o <
igual
que
No igual
Operador
Menor
que
<=
Menor
o igual
que
Igual
!=
And
Or
Tabla 3.2.1: Operadores relacionales y lgicos en C.
Los operadores relacinales y lgicos tiene menor prioridad que los operadores
aritmticos antes descritos, as , escribir 10>3+9 es equivalente a escribir 10>(3+9).
El lenguaje de programacin C
El lenguaje C posee operadores que actan a nivel de bits sobre los datos, estos
operadores son:
Operador
<<
>>
&
^
|
Nombre
Operacin
Not
Complemento a uno (NOT)
Desplazamiento izquierda
Desplazamiento izquierda
Desplazamiento derecha
Desplazamiento derecha
And
Y
Xor
O exclusivo (XOR)
Or
O
Tabla 3.5.1: Operadores sobre bits en C.
Los operadores &, | y ^ actan sobre dos operandos, mientras que ,<< y >>
actan sobre un solo operando. Veamos su actuacin sobre dos valores cualquiera:
Operador
<<3
>>2
&
^
|
Operando 1
Operando 2
Resultado
0xB2
0x4D
0xB2
0x90
0xB2
0x2C
0xB2
0x79
0x30
0xB2
0x79
0xCB
0xB2
0x79
0xFB
Tabla 3.5.2: Ejemplos de operaciones sobre bits en C.
Donde los nmeros que acompaan a los operadores << y >> indican cuantas
posiciones se desplaza el operando. La prioridad de los operadores sobre bits es:
Los operadores << y >> tienen la prioridad situada entre los operadores
aritmticos y los operadores relacinales y lgicos.
3.6 - El operador ?.
El operador ? se usa para reemplazar las sentencias if/else (que veremos con
posterioridad) de formato general:
if (condicin)
expresin;
else
expresin;
El lenguaje de programacin C
Exp1 ? Exp2 : Exp3;
El lenguaje de programacin C
Todos los char y short int se convierten a int. Todos los float a double.
ch / i )
char
int
f * d )
float double
f + i );
float int
ch
int
i )
int
( f * d )
double double
( f + i );
double int
Al ser los dos operandos de igual tipo, realizamos la primera operacin, (ch / i),
y el resultado es de tipo int. De igual forma, para la segunda operacin, (f * d), y el
resultado es de tipo double.
Para la tercera operacin, y dado que las variables no son del mismo tipo, se
aplica la segunda regla, convirtindose el int en double, realizndose la suma (f + i)
como dos datos de tipo double, y siendo por tanto el resultado un double.
El lenguaje de programacin C
Ahora procedemos a realizar la suma de los dos primeros resultados (ch / i) + (f
* d), como uno de ellos es de tipo int, y el otro de tipo double, el int se convierte en
double por la segunda regla, y el resultado es un double.
Y por ltimo, realizamos la resta final, siendo los dos operandos de tipo double
y el resultado final, por tanto, de tipo double.
La operacin asigna a c el valor 1.0 en vez de el valor 1.5, ello se debe a que al
ser a y b variables de tipo entero, se realiza una divisin entre enteros, y el resultado de
3/2 es 1. A continuacin ese valor 1 se convierte a un valor en coma flotante para
realizar la asignacin (valor 1.0), y se asigna a c. Si lo que se desea es que la divisin
se realice en punto flotante, debe escribirse la operacin de la siguiente forma:
c=(float)a/b;
El lenguaje de programacin C
El lenguaje de programacin C
else printf(2);
Donde variable debe ser de tipo char o int, y donde const1, const2, ..., indican
constantes de C del tipo de datos de la variable. Dichas constantes no pueden repetirse
dentro del switch. El default es opcional y puede no aparecer, as como los break de los
case. La sentencia switch se ejecuta comparando el valor de la variable con el valor de
cada una de las constantes, realizando la comparacin desde arriba hacia abajo. En
caso de que se encuentre una constante cuyo valor coincida con el valor de la variable,
se empieza a ejecutar las sentencias hasta encontrar una sentencia break. En caso de
que no se encuentre ningn valor que coincida, se ejecuta el default (si existe). Veamos
algunos ejemplos:
int valor;
switch(valor)
{
case 0: cont++;
break;
case 5: cont--;
break;
default: cont=-10; /* Se ejecuta si valor no es 0 o 5 */
}
char d;
El lenguaje de programacin C
int cont=0;
switch(d)
{
case \r: cont++; /* Si d es un retorno de carro, se */
/* ejecuta este cont++ y el siguiente*/
/* al no aparecer un break */
case \x1B: cont++;
break;
default: cont=-1;
}
Las sentencias switch pueden aparecer unas dentro de otras, igual que suceda
con las sentencias if. Vemoslo con un ejemplo:
char d,e;
switch(d)
{
case a:
case A: switch(e)
{
case 1: d=z;
e=+;
break;
case 2: d=Z;
e=-;
}
break;
case b:
case B: switch(e)
{
case 0: d=2;
default: e=+;
}
}
En primer lugar, conviene destacar el hecho de la gran flexibilidad del bucle for
de C. En C, el bucle for puede no contener inicializacin, condicin o incremento, o
incluso pueden no existir dos e incluso las tres expresiones del bucle. El bucle for se
ejecuta siempre que la condicin sea verdadera, es por ello que puede llegar a no
ejecutarse.
Veamos algunos ejemplos de bucles for:
int i,suma=0;
for(i=1;i<=100;i++)
suma=suma+i;
int i,j;
El lenguaje de programacin C
for(i=0,j=100;j>i;i++,j--)
{
printf(%d\n,j-i);
printf(%d\n,i-j);
}
float a=3e10;
for(;a>2;a=sqrt(a)) /* sqrt() calcula la raz cuadrada */
printf(%f,a);
char d;
for(;getc(stdin)!=\x1B;); /* Bucle que espera hasta que se */
/* pulsa la tecla Esc */
char d;
for(;;)
{
d=getc(stdin);
printf(%c,d);
if (d==\x1B)
break;
}
Donde la sentencia puede no existir (sentencia vaca), pero siempre debe existir
la condicin. El bucle while se ejecuta mientras la condicin sea verdad. Veamos
algunos ejemplos de bucles while:
int i=1,suma=0;
while (i<=100)
{
suma=suma+i;
i++;
}
while (getc(stdin)!=\x1B); /* Bucle que espera hasta que se */
/* pulse la tecla Esc */
while (1) /* Recordar que en C lo que no es cero es verdad */
{
d=getc(stdin);
printf(%c,d);
if (d==\x1B)
break;
}
El lenguaje de programacin C
El lenguaje de programacin C
if (x%2)
continue;
printf(%d\n,x);
}
El lenguaje de programacin C
El lenguaje de programacin C
Como toda cadena debe terminar en el carcter \0, es por ello que si se quiere
usar una cadena de 20 caracteres, debe declararse de tamao 21 (20 caracteres +
carcter terminador).
Por lo dems, puede usarse una cadena como si fuera un array unidimensional,
pues se puede referenciar uno cualquiera de sus elementos, etc. Para manejar las
cadenas, existen un gran nmero de funciones de biblioteca que proporciona el
standard ANSI-C, para ms informacin referirse al apendice A o a cualquier libro de
C.
La declaracin de arrays de ms de una dimensin se realiza de forma parecida
a la de una dimensin, la sintaxis de la declaracin de un array multidimensional es:
tipo nombre[tam1][tam2]...[tamN];
6.2 Punteros.
Los punteros son una de las poderosas herramientas que ofrece el lenguaje C a
los programadores, sin embargo, son tambin una de las ms peligrosas, el uso de
punteros sin inicializar, etc., es una fuente frecuente de errores en los programas de C,
y adems, suele producir fallos muy difciles de localizar y depurar.
El lenguaje de programacin C
Un puntero es una variable que contiene una direccin de memoria.
Normalmente esa direccin es una posicin de memoria de otra variable, por lo cual se
suele decir que el puntero apunta a la otra variable.
La sintaxis de la declaracin de una variable puntero es:
tipo *nombre;
Y hacemos:
a=&b;
Si hacemos:
b=15;
a=&b;
c=*a;
El lenguaje de programacin C
int *a,*b,c;
a=&c;
b=a;
Aritmtica de punteros. Sobre las variables de tipo puntero es posible utilizar los
operadores +, -, ++ y --. Estos operadores incrementan o decrementan la posicin
de memoria a la que apunta la variable puntero. El incremento o decremento se
realiza de acuerdo al tipo base de la variable de tipo puntero, de ah la importancia
del tipo del que se declara la variable puntero. Veamos esto con la siguiente tabla:
Operacin
++
-+9
-5
Variable Direccin actual Nueva
direccin
int *a;
3000
3002 2998 3018 2990
float *b 3000
3004 2996 3036 2980
Tabla 6.2.1: Ejemplos de aritmtica de punteros en C.
Por lo tanto, si tenemos:
tipo *a;
Y hacemos:
a=a+num;
int *a,*b;
if (a<b)
printf(a apunta a una direccin ms baja que b);
Existe una estrecha relacin entre los punteros y los arrays. Consideremos el
siguiente fragmento de cdigo:
char str[80],*p;
p=str;
El lenguaje de programacin C
en cuenta que el nombre del array sin ndice es la direccin de comienzo del array, y, si
adems, se tiene en cuenta que un puntero puede indexarse como un array
unidimensional, por lo cual, en el ejemplo anterior, podramos referenciar ese elemento
como p[4].
Es posible obtener la direccin de un elemento cualquiera del array de la
siguiente forma:
int str[80],*p;
p=&str[4];
Entonces, el puntero p contiene la direccin del quinto elemento del array str.
Hasta ahora hemos declarado variables puntero aisladas. Es posible, como con
cualquier otro tipo de datos, definir un array de variables puntero. La declaracin para
un array de punteros int de tamao 10 es:
int *a[10];
Para asignar una direccin de una variable entera, llamada var, al tercer
elemento del array de punteros, se escribe:
x[2]=&var;
El lenguaje de programacin C
Tema 7 - Funciones.
El formato general de una funcin de C es:
tipo nombre(lista de parmetros)
{
cuerpo de la funcin
}
Las funciones son simulares a las de cualquier otro lenguaje, pero, tal y como
citamos en la introduccin, al no ser un lenguaje estructurado por bloques, no es
posible declarar funciones dentro de otras funciones.
b)
a es mayor que b */
a es menor que b */
a y b son iguales */
Esa funcin es equivalente a otra que tuviera como ltima lnea una sentencia
return, y funcionara de igual forma.
El lenguaje de programacin C
necesario declarar variables que acepten los argumentos de la funcin. Veamos un
ejemplo:
int EstaEn(char *cad,char c) /* Devuelve 1 si el carcter c */
{
/* esta en el string cad */
while (*cad!=\0)
{
if (*cad==c)
return 1;
cad++;
}
return 0;
}
Esta funcin, podra ser llamada desde otra funcin de la siguiente forma:
char cadena[]=Esta es una cadena de prueba;
if (EstaEn(cadena,a))
printf(Esta);
else
printf(No esta);
El lenguaje de programacin C
Al principio valen a=6 b=9.87
Despus de Alfa valen a=5 b=9.87
Despus de Beta valen a=5 b=14.7
Ello es, pues a Alfa se le pasa la variable a por "referencia" (se le pasa &a, o
sea, un puntero a la variable a), y la variable b por valor, mientras que en Beta sucede
al revs.
El lenguaje de programacin C
#include <stdio.h>
int main(int argc,char *argv[],char *env[])
{
int i;
printf(El valor de argc es: %d\n,argc);
for(i=0;i<argc;i++)
printf(El argumento %d es: %s\n,i,argv[i]);
for(i=0;env[i]!=NULL;i++)
printf("La variable de ambiente %d es: %s\n",i,env[i]);
return 0;
}
Este_es_el_argumento_1
Este_es_el_argumento_2
Escribir en pantalla:
El
El
El
El
La
La
La
7.5 - Recursividad.
Una funcin de C puede llamarse a si misma. Este proceso recibe el nombre de
recursividad. Los ejemplos de recursividad abundan, siendo uno de los mas habituales
la funcin factorial:
unsigned Factorial(unsigned num)
{
if (num==0) return 1;
return num*Factorial(num-1);
}
El lenguaje de programacin C
La recursividad es una poderosa herramienta de programacin, sin embargo,
presenta dos problemas:
El lenguaje de programacin C
El lenguaje de programacin C
As, podamos referenciar los elementos de las estructuras anteriores de la
siguiente forma:
var_lista.tam;
var_list.cadena;
var_list.cadena[7];
memo[2].a;
memo[6].cadena[3];
variable.alfa.a;
variable.c;
El lenguaje de programacin C
PasoDeElementos(a.val,a.b);
PasoDeLaEstructuraPorValor(a);
PasoDeLaEstructuraPorReferencia(&a);
PasoDeUnArrayDeEstructuras(b);
return 0;
}
El tipo de un campo de bit debe declararse como unsigned int o signed int.
Veamos un ejemplo de declaracin de un campo de bit:
struct ALFA{
unsigned a
signed b :
unsigned :
unsigned c
}campo;
: 1;
2;
4;
: 1;
El lenguaje de programacin C
Es posible mezclar en la declaracin elementos normales de estructura con
elementos de campo de bit. Veamos un ejemplo:
struct EMP{
char nombre[20],apellido[2][20];
float sueldo;
unsigned vacaciones:1;
unsigned enfermo:1;
};
8.3 - Uniones.
En C una unin es una posicin de memoria que se usa por varias variables
similares, que pueden ser de tipos diferentes. La definicin de unin es:
union nombre_union{
tipo nombre1;
tipo nombre2;
...
tipo nombreN;
}var_union;
Tendremos:
<------alfa.a------>
Byte0
Byte1
<-alfa.b->
El lenguaje de programacin C
8.4 - Enumeraciones.
Una enumeracin es un conjunto de constantes enteras con nombre y especifica
todos los valores legales que pueden tener unas variables. Las enumeraciones se
declaran de la siguiente forma:
enum nombre_enum{lista_de_enumeracin} lista_de_variables;
Las enumeraciones asignan una constante entera a cada uno de los smbolos de
la enumeracin, empezando por el valor 0. Esto puede modificarse colocando en la
declaracin el valor que deseamos tengan los elementos a partir de uno dado. Esto se
realiza de la siguiente forma:
enum CURSO{ primero, segundo, tercero, cuarto_t=100, quinto_t,
cuarto_e=200, quinto_e};
En este caso, las constantes primero, segundo y tercero tienen los valores 0,1 y
2, las constantes cuarto_t y quinto_t los valores 100 y 101, y las constantes cuarto_e y
quinto_e los valores 200 y 201 respectivamente.
El lenguaje de programacin C
Tema 9 - El preprocesador.
En un programa escrito en C, es posible incluir diversas instrucciones para el
compilador dentro del cdigo fuente del programa. Estas instrucciones dadas al
compilador son llamadas directivas del preprocesador y, aunque realmente no son parte
del lenguaje C, expanden el mbito del entorno de programacin de C.
El preprocesador, definido por el standard ANSI de C, contiene las siguientes
directivas:
#if
#elif
#undef
#ifdef
#endif
#line
#ifndef
#include
#error
#else
#define
#pragma
El lenguaje de programacin C
El lenguaje de programacin C
La idea general de la directiva #if es que si es verdad la expresin que se
encuentra despus del #if, se compilara el cdigo que figura entre el #if y el #endif se
compilara. La directiva #else funciona de igual forma que el else del lenguaje C. La
directiva #elif funciona como el escalonado de if del lenguaje C. La definicin formal
es:
#if expresin1
secuencia de sentencias
#elif expresin2
secuencia de sentencias
......
#else
secuencia de sentencias
#endif
El lenguaje de programacin C
E igual para #ifndef. Veamos algunos ejemplos:
#define VAL 10
#ifdef VAL
printf("VAL definido");
#else
printf("VAL no definido");
#endif
#ifndef NOVAL
printf("NOVAL no definido");
#endif
Veamos un ejemplo:
#line 100 /* Inicializa el contador de lineas a 100 */
/* 10 lineas */
#error Detenida compilacin
El lenguaje de programacin C
Dicha funcin lee caracteres, de uno en uno, desde el teclado, esperando, para
leer los caracteres, la pulsacin de un retorno de carro. Es por ello que es posible
escribir varios caracteres antes de que se ninguno de ellos sea ledo. La funcin
getchar() hace eco en pantalla del carcter ledo. En caso de error devuelve EOF.
La funcin putchar() escribe un carcter a la pantalla del ordenador. Dicha
funcin se define como:
int putchar(int c);
El lenguaje de programacin C
#include <stdio.h>
int main(void)
{
char ch;
do
{
ch=getchar();
putchar(ch);
}
while (ch!='e' && ch!='E');
return 0;
}
Este programa lee todas las teclas pulsadas en el teclado, y las coloca en
pantalla, hasta leer una 'e' o una 'E'. Obsrvese que solo lee las teclas despus de pulsar
un retorno de carro.
La funcin gets() lee un string desde el teclado. La funcin se define como:
char *gets(char *s);
La funcin gets() lee un string desde el teclado hasta que se pulsa un retorno de
carro. El string es almacenado en la variable s, y el retorno de carro ledo desde el
teclado es, automticamente, reemplazado por un carcter de final de string ('\0').
Devuelve un puntero a la variable s si sucede de forma correcta, y NULL en caso
contrario. La funcin gets() permite corregir errores de teclado usando la tecla de
retroceso antes de pulsar el retorno de carro.
La funcin puts() escribe un string en pantalla. La funcin se define como:
int puts(const char *s);
El lenguaje de programacin C
La funcin scanf() se usa para leer cualquier tipo de dato predefinido desde el
teclado, y convertirlo, de forma automtica, al formato interno adecuado. La funcin se
define como:
int scanf(const char *formato[,direccin,...]);
El string formato es la cadena de control que indica los datos a leer. Dicha
cadena de control consta de tres clases de caracteres:
Especificadores de formato.
Caracteres de espacio en blanco.
Caracteres que no sean espacios en blanco.
El lenguaje de programacin C
despus lea, y descarte, los dos puntos, y luego lea otro int. Si el carcter especificado
no se encuentra, scanf() termina su ejecucin.
Todas las variables utilizadas para recibir valores (si son necesarias), deben ser
pasadas por "referencia", o sea, por sus direcciones. Esto supone que los argumentos
deben ser punteros a las variables.
La presencia del signo * despus del signo % y antes del cdigo del formato
produce que scanf() lea, pero no asigne el valor ledo a ninguna variable. Por ejemplo:
int x,y;
scanf("%d%*c%d",&x,&y);
La cadena apuntada por formato consta de dos tipos de elementos. El primer tipo
esta constituido por los caracteres que se mostraran en pantalla. El segundo tipo
contiene las ordenes de formato que describen la forma en que se muestran los
argumentos. Las ordenes de formato estn precedidas por el signo % y le sigue el
cdigo de formato. Estas ordenes de formato son:
Especificado
r
%c
%d
%i
%e
%E
%f
%g
%G
%o
%s
%u
%x
%X
%p
Descripcin
Carcter.
Enteros decimales con signo.
Enteros decimales con signo.
Punto flotante en notacin cientfica (e minscula).
Punto flotante en notacin cientfica (E mayscula).
Punto flotante.
Usar el ms corto de %e y %f.
Usar el ms corto de %E y %f.
Octal sin signo.
Cadena de caracteres.
Enteros decimales sin signo.
Hexadecimales sin signo (letras minsculas).
Hexadecimales sin signo (letras maysculas).
Mostrar un puntero.
El lenguaje de programacin C
%n
%%
El lenguaje de programacin C
Donde nombre es un string que contiene el nombre del archivo que queremos leer
y modo es otro string que contiene el modo de apertura deseado. Dichos modos de
apertura son:
Modo Descripcin
r
Abrir un archivo para lectura.
w
Crear un archivo para escritura.
a
Abrir un archivo para aadir.
rb
Abrir un archivo binario para lectura.
wb
Crear un archivo binario para escritura.
ab
Abrir un archivo binario para aadir.
rt
Abrir un archivo de texto para lectura.
wt
Crear un archivo de texto para escritura.
at
Abrir un archivo de texto para aadir.
r+
Abrir una archivo para lectura/escritura.
w+
Crear un archivo para lectura/escritura.
a+
Abrir un archivo para leer/aadir.
r+b
Abrir un archivo binario para lectura/escritura.
w+b
Crear un archivo binario para lectura/escritura.
a+b
Abrir un archivo binario para leer/aadir.
r+t
Abrir un archivo de texto para lectura/escritura.
w+t
Crear un archivo de texto para lectura/escritura.
a+t
Abrir un archivo de texto para leer/aadir.
Tabla 10.2.1: Modos de apertura de un fichero con la funcin fopen().
En todos los casos de aadir, si el archivo especificado no existe, se procede a
crearlo.
Si no se especifica en modo si la apertura se realiza para un archivo binario o
texto, depender de la configuracin del sistema que la apertura sea en binario o en
texto, siendo en la mayora de los casos en modo texto. La diferencia fundamental
entre modo texto y modo binario es que en modo texto, secuencias de lectura tales
como retorno de carro/alimentacin de lnea se traducen en un nico carcter nueva
lnea, mientras que en modo texto eso no sucede; el efecto contrario sucede en
escritura.
La funcin fopen() devuelve un puntero de tipo FILE a la estructura que
representa el archivo abierto. En caso de que no pueda abrir o crear el archivo
especificado, se devuelve un puntero NULL, por lo cual, siempre que se abra un
archivo, deber comprobarse que el valor devuelto no es NULL, y entonces, el cdigo
deber ser:
FILE *fp;
if ((fp=fopen("prueba","w"))==NULL)
{
puts("\nNo puedo abrir el fichero\n");
exit(1);
}
El lenguaje de programacin C
La funcin fclose() cierra un archivo. Su definicin es:
int fclose(FILE *fp);
Una vez abierto un archivo, y hasta que se proceda a cerrarlo es posible leer,
escribir, etc., en el, segn se indique en el modo de apertura. Las principales funciones
de lectura y escritura sobre un archivo son:
int getc(FILE *fp);
int putc(int ch,FILE *fp);
char *fgets(char *str,int n,FILE *fp);
int fputs(const char *str,FILE *fp);
int fscanf(FILE *fp,const char *formato[,direccin,...]);
int fprintf(FILE *fp,const char *formato[,argumento,...]);
int fread(void *memoria,int num,int cont,FILE *fp);
int fwrite(void *memoria,int num,int cont,FILE *fp);
El lenguaje de programacin C
La funcin getc() lee caracteres del archivo asociado a fp. Devuelve EOF
cuando se alcanza el final del archivo.
La funcin putc() escribe el carcter ch en el archivo asociado a fp. Devuelve el
carcter escrito si funciona de forma correcta, y EOF en caso de error.
La funcin fgets() funciona de igual forma que la funcin gets(), solo que,
adems de leer del fichero asociado a fp, el parmetro n indica el nmero mximo de
caracteres que se pueden leer. Existe, adems, una sutil diferencia, la funcin fgets() no
elimina el retorno de carro (si se lee) de la cadena de entrada, sino que lo conserva en
la misma,. aadiendo a continuacin de dicho retorno de carro, y de forma automtica,
el carcter de fin de cadena ('\0').
La funcin fputs() funciona igual que la funcin puts(), solo que, adems de
escribir en el fichero asociado a fp, no aade al final del string un retorno de carro, tal
y como hacia la funcin puts().
Las funciones fscanf() y fprintf() funcionan de forma similar a sus equivalentes
sobre la consola scanf() y printf(), solo que leen o escriben del archivo asociado a fp.
Las funcin fread() permite leer un bloque de datos. Su declaracin es:
int fread(void *memoria,int num,int cont,FILE *fp);
El lenguaje de programacin C
Veamos un ejemplo de uso de fread() y fwrite():
#include <stdio.h>
#define TAM 1000
int main(int argc,char *argv[])
{
FILE *f_inp,*f_out;
char buffer[TAM];
int num;
if (argc!=3)
return 0;
if ((f_inp=fopen(argv[1],"rb"))==NULL)
return 0;
if ((f_out=fopen(argv[2],"wb"))==NULL)
exit(1);
while ((num=fread(buffer,sizeof(char),TAM,f_inp))!=0)
fwrite(buffer,sizeof(char),num,f_out);
if (fclose(f_inp) || fclose(f_out)
exit(1);
return 0;
}
El lenguaje de programacin C
La funcin fseek() devuelve un valor de cero si funciona correctamente. Un
valor distinto de cero indica un error en la ltima operacin de posicionamiento en el
fichero.
La funcin fseek() solo funciona correctamente en archivos abiertos en modo
binario, pues, dadas las conversiones que se realizan en ciertas transacciones de
caracteres en los archivos abiertos en modo texto, se produciran errores en el
posicionamiento en el fichero al usar dicha funcin. Veamos un ejemplo de uso de
fseek():
#include <stdio.h>
int LeeCaracter(FILE *fp,long pos,int origen)
{
if (fseek(fp,pos,origen))
return(EOF);
return(getc(fp));
}
El lenguaje de programacin C
El lenguaje de programacin C
unsigned a;
float b;
int *c;
}*d;
if ((d=(struct ALFA *)malloc(sizeof(struct ALFA)))==NULL)
exit(0); /Salimos del programa */
Donde tipo es cualquier tipo de datos valido (float, int, long int, etc.)
El lenguaje de programacin C
Las variables necesarias para crear la lista son las siguientes:
struct LISTA *cabeza=NULL,*p;
tipo dato;
El lenguaje de programacin C
q->sig=p->sig;
free(p);
}
}
return cabeza;
}
Siendo la llamada:
cabeza=LiberarLista(cabeza,dato);
El lenguaje de programacin C
feof
#include <stdio.h>
int feof(FILE *f);
ferror
#include <stdio.h>
int ferror(FILE *f);
El lenguaje de programacin C
La funcin ferror() comprueba si existen errores en alguna operacin realizada
sobre el archivo asociado a f. Un valor devuelto de cero indica que no hay errores, un
valor distinto de cero indica la existencia de errores. Los indicadores de error
asociados a f permanecen activos hasta que se cierra el archivo o se llama a las
funciones rewind() o perror().
fflush
#include <stdio.h>
int fflush(FILE *f);
fgetc
#include <stdio.h>
int fgetc(FILE *f);
fgets
#include <stdio.h>
char *fgets(char *cad,int num,FILE *f);
La funcin fgets() lee como mximo hasta num-1 caracteres del archivo
asociado a f y los sita en el array apuntado por cad. Los caracteres se leen hasta que
se recibe un carcter de salto de linea, un EOF (fin de fichero) o hasta que se llega al
limite especificado. Despus de ledos los caracteres, se pone automticamente un
carcter de nulo inmediatamente despus del ultimo carcter ledo. Si se termina la
lectura por un carcter de salto de linea, dicho carcter se guarda como parte de cad. Si
tiene xito, fgets() devuelve un puntero a la direccin de cad. En caso de error devuelve
un puntero nulo (NULL).
fopen
#include <stdio.h>
FILE *fopen(const char *nombre,const char *modo);
La funcin fopen() abre un archivo cuyo nombre viene dado por nombre y
devuelve un puntero a una estructura de tipo FILE que se le asocia en la apertura. El
El lenguaje de programacin C
tipo de operaciones permitidas en el archivo estn definidas por el valor de modo. Los
valores permitidos de modo son:
Modo Descripcin
r
Abrir un archivo para lectura.
w
Crear un archivo para escritura.
a
Abrir un archivo para aadir.
rb
Abrir un archivo binario para lectura.
wb
Crear un archivo binario para escritura.
ab
Abrir un archivo binario para aadir.
rt
Abrir un archivo de texto para lectura.
wt
Crear un archivo de texto para escritura.
at
Abrir un archivo de texto para aadir.
r+
Abrir una archivo para lectura/escritura.
w+
Crear un archivo para lectura/escritura.
a+
Abrir un archivo para leer/aadir.
r+b
Abrir un archivo binario para lectura/escritura.
w+b Crear un archivo binario para lectura/escritura.
a+b
Abrir un archivo binario para leer/aadir.
r+t
Abrir un archivo de texto para lectura/escritura.
w+t
Crear un archivo de texto para lectura/escritura.
a+t
Abrir un archivo de texto para leer/aadir.
Tabla A.1.1: Modos de apertura de un fichero con la funcin fopen().
Si fopen() tiene xito en abrir el archivo, devuelve un puntero de tipo FILE, en
caso contrario devuelve un puntero nulo (NULL).
fprintf
#include <stdio.h>
int fprintf(FILE *f,const char *formato,...);
fputc
#include <stdio.h>
int fputc(int c,FILE *f);
El lenguaje de programacin C
ser ignorada y no se escribir. Si se ejecuta de forma correcta, fputc() devuelve el
valor c, en caso de error devuelve el valor EOF.
fputs
#include <stdio.h>
int fputs(const char *cad,FILE *f);
fread
#include <stdio.h>
int fread(void *buf,size_t tam,sise_t cuenta, FILE *f);
La funcin fread() lee cuenta numero de elementos, cada uno de ellos de tam
bytes de longitud, del archivo asociado a la variable f, y los sita en el array apuntado
por buf. El indicador de posicin del archivo se incrementa en el nmero de bytes
ledos. La funcin fread() devuelve el nmero de elementos realmente ledos. Si se leen
menos elementos de los pedidos en la llamada se produce un error. La funcin fread()
funciona de forma correcta en archivos abiertos en modo binario; en archivos abiertos
en modo texto, pueden producirse ciertos cambios de caracteres (salto de carro seguido
de salto de linea se convierte en salto de linea, etc.).
fscanf
#include <stdio.h>
int fscanf(FILE *f,const char *formato,...);
La funcin fscanf() lee del archivo asociado a la variable f de igual forma que la
funcin scanf() lo realiza del teclado. Devuelve el numero de argumentos a los que
realmente se asigna valores. Este nmero no incluye los campos ignorados. Si se
produce un error antes de realizar la primera asignacin se devuelve el valor EOF. Para
mas informacin consultar la funcin scanf().
fseek
#include <stdio.h>
#int fseek(FILE *f,long desp,int origen);
El lenguaje de programacin C
Final del archivo
SEEK_END
2
Tabla A.1.2: Valores del origen en la funcin fseek().
La funcin fseek() devuelve un valor de cero si sucede correctamente, en caso
contrario el valor devuelto es distinto de cero.
Puede utilizarse fseek() para mover el indicador de posicin en el archivo a
cualquier lugar del mismo, incluso mas alla del final del mismo, pero es un error
intentar situarse antes del comienzo del archivo.
ftell
#include <stdio.h>
long ftell(FILE *f);
La funcin ftell() devuelve el valor actual del indicador de posicin del archivo
asociado a la variable f. Para archivos binarios, el valor devuelto es el nmero de bytes
desde el principio del archivo. Para archivos de texto solo debe usarse como argumento
para la funcin fseek(), ya que, debido a que secuencias de caracteres como retorno de
carro y salto de lnea pueden sustituirse por un salto de lnea, el tamao aparente del
archivo puede variar. Si falla la funcin ftell() devuelve el valor -1L.
fwrite
#include <stdio.h>
int fwrite(const void *buf,size_t tam,size_t cuenta,FILE *f);
getc
#include <stdio.h>
int getc(FILE *f);
gets
El lenguaje de programacin C
#include <stdio.h>
char *gets(char *cad);
perror
#include <stdio.h>
int perror(const char *cad);
printf
#include <stdio.h>
int printf(const char *formato,...);
Descripcin
Carcter.
Enteros decimales con signo.
Enteros decimales con signo.
Punto flotante en notacin cientfica (e minscula).
Punto flotante en notacin cientfica (E mayscula).
Punto flotante.
Usar el ms corto de %e y %f.
Usar el ms corto de %E y %f.
Octal sin signo.
Cadena de caracteres.
Enteros decimales sin signo.
Hexadecimales sin signo (letras minsculas).
El lenguaje de programacin C
%X
%p
%n
%%
putc
#include <stdio.h>
int putc(int c,FILE *f);
puts
#include <stdio.h>
int puts(char *cad);
rewind
#include <stdio.h>
void rewind(FILE *f);
El lenguaje de programacin C
scanf
#include <stdio.h>
int scanf(const char *formato,...);
Especificadores de formato.
Caracteres de espacio en blanco.
Caracteres que no sean espacios en blanco.
Descripcin.
Leer un nico carcter.
Leer un entero decimal.
Leer un entero decimal.
Leer un nmero en punto flotante.
Leer un nmero en punto flotante.
Leer un nmero en punto flotante.
Leer un nmero octal.
Leer una cadena de caracteres.
Leer un nmero hexadecimal.
Leer un puntero.
Recibe un valor igual al nmero de carcter
ledos.
%u
Leer un entero sin signo.
Tabla A.1.4: Especificadores de formato de la funcin scanf().
Adems, es posible utilizar los modificadores h (short), l (long) y L de igual
forma que en la funcin printf().
Un espacio en blanco en la cadena de control da lugar a que scanf() salte sobre
uno o mas espacios de la cadena de entrada, un espacio en blanco puede ser un espacio,
un tabulador o un salto de lnea. Adems, un espacio en blanco da lugar, tambin, a
que scanf() lea, pero no guarde cualquier nmero de espacios en blanco, incluso cero.
Un carcter que no sea espacio en blanco, da lugar a que scanf() lea y elimine el
carcter asociado. Por ejemplo, %d:%d da lugar a que scanf() lea primero un int,
despus lea, y descarte, los dos puntos, y luego lea otro int. Si el carcter especificado
no se encuentra, scanf() termina su ejecucin.
El lenguaje de programacin C
Todas las variables utilizadas para recibir valores a travs de scanf() deben ser
pasadas por referencia, o sea, por sus direcciones. Esto supone que los argumentos
deben ser punteros a las funciones.
La presencia del signo * despus del signo % y antes del cdigo del formato,
produce que scanf() lea, pero no asigne el valor ledo a ninguna variable, por ejemplo:
scanf("%d%*c%d",&x,&y);
Provoca, si la entrada es 10/20, que se le asigne el valor 10 a la variable x, se
lea y descarte el signo /, y despus se asigne el valor 20 a la variable y.
La funcin scanf() devuelve un nmero igual al de campos que han sido
asignados correctamente, este nmero no incluye los campos que fueron ledos, pero
no asignados, utilizando el modificador * para eliminar la asignacin.
setbuf
#include <stdio.h>
void setbuf(FILE *f, char *buf);
setvbuf
#include <stdio.h>
int setvbuf(FILE *f,char *buf,int modo,.size_t tam);
El lenguaje de programacin C
La funcin setvbuf() devuelve un valor de cero si se ejecuta con xito. En caso
de error, un valor distinto de cero ser devuelto.
sprintf
#include <stdio.h>
int sprintf(char *buf,const char *formato,...);
sscanf
#include <stdio.h>
int sscanf(const char *buf,const char *formato,...);
La funcin sscanf() es idntica a la funcin scanf(), excepto que los datos son
ledos del array apuntado por buf. El valor devuelto por la funcin es igual al nmero
de campos que hubieran sido realmente asignados. Este nmero no incluye los campos
que fueron saltados al utilizar el modificador de ordenes de formato *. Para ms
detalles vea la funcin scanf().
ungetc
#include <stdio.h>
int ungetc(int c,FILE *f);
isalpha
El lenguaje de programacin C
#include <ctype.h>
int isalpha(int ch);
iscntrl
#include <ctype.h>
int iscntrl(int ch);
isdigit
#include <ctype.h>
int isdigit(int ch);
isgraph
#include <ctype.h>
int isgraph(int ch);
islower
#include <ctype.h>
int islower(int ch);
isprint
#include <ctype.h>
int isprint(int ch);
ispunct
#include <ctype.h>
El lenguaje de programacin C
int ispunct(int ch);
isspace
#include <ctype.h>
int isspace(int ch);
isupper
#include <ctype.h>
int isupper(int ch);
isxdigit
#include <ctype.h>
int isxdigit(int ch);
tolower
#include <ctype.h>
int tolower(int ch);
toupper
#include <ctype.h>
int toupper(int ch);
El lenguaje de programacin C
memcmp
#include <string.h>
int memcmp(const void *buf1,const void *buf2,size_t cuenta);
memcpy
#include <string.h>
void *memcpy(void *hacia,const void *desde,size_t cuenta);
La funcin memcpy() copia cuenta caracteres del array apuntado por desde en el
array apuntado por hacia. Si los arrays se superponen, el comportamiento de memcpy()
queda indefinido. La funcin devuelve un puntero a hacia.
memset
#include <string.h>
void *memset(void *buf,int ch,size_t cuenta);
strcat
#include <string.h>
char *strcat(char *cad1,const char *cad2);
El lenguaje de programacin C
La funcin strcat() concatena una copia de cad2 en cad1, y aade al final de
cad1 un carcter nulo ('\0'). El carcter nulo de terminacin, que originalmente tena
cad1, es sustituido por el primer carcter de cad2. La cadena cad2 no se modifica en
esta operacin. La funcin strcat() devuelve cad1.
strchr
#include <string.h>
char *strchr(char *cad,int ch);
strcmp
#include <string.h>
int strcmp(const char *cad1,const char *cad2);
strcpy
#include <string.h>
char *strcpy(char *cad1,const char *cad2);
strlen
#include <string.h>
unsigned int strlen(char *cad);
strtok
#include <string.h>
char *strtok(char *cad1,const char *cad2);
El lenguaje de programacin C
La funcin strtok() devuelve un puntero a la siguiente palabra de la cadena
apuntada por cad1. Los caracteres que constituyen la cadena apuntada por cad2 son los
delimitadores que identifican la palabra. Devuelve un puntero nulo (NULL) cuando no
existe ninguna palabra que devolver.
La primera vez que se llama a strtok() se utiliza realmente cad1 en la llamada.
Las llamadas posteriores utilizan un puntero nulo (NULL) como primer argumento.
La funcin strtok() modifica la cadena apuntada por cad1, pues, cada vez que se
encuentra una palabra, se pone un carcter nulo donde esta el delimitador. De esta
forma strtok() puede continuar avanzando por la cadena.
asin
#include <math.h>
double asin(double arg);
atan
#include <math.h>
double atan(double arg);
atan2
#include <math.h>
double atan2(double y,double x);
El lenguaje de programacin C
ceil
#include <math.h>
double ceil(double num);
cos
#include <math.h>
double cos(double arg);
La funcin cos() devuelve el coseno de arg. El valor de arg debe venir dado en
radianes.
cosh
#include <math.h>
double cosh(double arg);
exp
#include <math.h>
double exp(double arg);
fabs
#include <math.h>
double fabs(double num);
floor
#include <math.h>
double floor(double num);
El lenguaje de programacin C
fmod
#include <math.h>
double fmod(double x,double y);
log
#include <math.h>
double log(double num);
log10
#include <math.h>
double log10(double num);
pow
#include <math.h>
double pow(double base,double exp);
sin
#include <math.h>
double sin(double arg);
La funcin sin() devuelve el seno de arg. El valor de arg debe venir dado en
radianes.
sinh
#include <math.h>
double sinh(double arg);
El lenguaje de programacin C
sqrt
#include <math.h>
double sqrt(double num);
tan
#include <math.h>
double tan(double arg);
La funcin tan() devuelve la tangente de arg. El valor de arg debe venir dado en
radianes.
tanh
#include <math.h>
double tanh(double arg);
La funcin calloc() asigna memoria para un array de num objetos, cada uno de
los cuales tiene tamao tam. La memoria asignada es inicializada con el valor cero. La
funcin calloc() devuelve un puntero al primer byte de la regin asignada. Si no existe
memoria libre suficiente para satisfacer la peticin, se devuelve un puntero nulo
(NULL).
free
#include <stdlib.h>
void free(void *ptr);
La funcin free() libera la memoria apuntada por ptr, haciendo que dicha
memoria este disponible para futuras asignaciones. Solo se debe llamar a free() con un
puntero que haya sido previamente asignado utilizando alguna funcin de asignacin
dinmica.
El lenguaje de programacin C
malloc
#include <stdlib.h>
void *malloc(size_t tam);
realloc
#include <stdlib.h>
void *realloc(void *ptr,size_t tam);
La funcin abs() devuelve el valor absoluto del entero dado por num.
atof
#include <stdlib.h>
double atof(const char *cad);
El lenguaje de programacin C
atoi
#include <stdlib.h>
int atoi(const char *cad);
La funcin atoi() convierte la cadena apuntada por cad en un valor de tipo int.
La cadena debe contener un nmero entero valido. Si no es este el caso, el valor
devuelto es indefinido, aunque, la mayora de implementaciones de la funcin
devuelven el valor cero.
El nmero puede acabar con cualquier carcter que no pueda formar parte de un
nmero entero. Esto incluye espacios en blanco, signos de puntuacin, y cualquier
carcter que no sea la E o la e. Esto supone que si se llama a atoi() con la cadena
"123.23", devolver el valor 123.
atol
#include <stdlib.h>
long int atol(const char *cad);
La funcin atol() convierte la cadena apuntada por cad en un valor de tipo long
int. Para ms informacin consultar la funcin atoi().
exit
#include <stdlib.h>
void exit(int estado);
labs
#include <stdlib.h>
long labs(long num);
system
#include <stdlib.h>
int system(const char *cad);
La funcin system() pasa la cadena apuntada por cad como una orden al
procesador de ordenes del sistema operativo. Si se llama a system() con un puntero
nulo (NULL), devuelve un valor distinto de cero si est presente un procesador de
El lenguaje de programacin C
ordenes, en otro caso, se devuelve un valor distinto de cero. Si cad no es un puntero
nulo (NULL), system() devuelve el valor cero si la orden ha sido correctamente
ejecutada, y un valor distinto de cero en caso contrario.
El lenguaje de programacin C
B.1 - palindro.c.
/* Programa que calcula si una palabra es palindroma, esto es, se lee
igual de derecha a izquierda que de izquierda a derecha. */
#include <stdio.h>
#include <string.h>
#define TAM 100
/* Rutina que calcula si una palabra es palindroma.
Parametros: char *cadena Puntero al string con la palabra.
Return: int 0 no palindroma, <>0 palindroma. */
int Palindroma(char *cadena)
{
register int i,j;
i=0;
j=strlen(cadena)-1;
while (i<j && cadena[i]==cadena[j])
{
i++;
j--;
}
return (i>=j);
}
int main(void)
{
char cadena[TAM];
printf("\nIntroduce la palabra\n");
gets(cadena);
printf("La palabra: %s %s palindroma.\n",cadena,
(Palindroma(cadena)) ? "es" : "no es");
return 0;
}
B.2 - matriz.c.
/* Programa que calcula el producto de dos matrices. */
#include <stdio.h>
75
El lenguaje de programacin C
/* Definicion del tamao maximo */
#define TAM 10
/* Definicion de los codigos de error */
#define OK 0
#define ERROR 1
/* Definicion de la estructura de datos */
struct MATRIZ
{
unsigned fila,columna;
float matriz[TAM][TAM];
};
/* Rutina que muestra un menu y pide una opcion del menu.
Parametros: Ninguno.
Return: char Opcion del menu elegida. */
char Menu(void)
{
register char d;
printf("\nElige la opcion deseada:\n");
printf("\t0 -- Salir del programa.\n");
printf("\t1 -- Cambiar la matriz A.\n");
printf("\t2 -- Cambiar la matriz B.\n");
printf("\t3 -- Calcular A*B\n");
printf("\t4 -- Calcular B*A\n");
while ((d=getchar())<'0' || d>'4');
return d;
}
/* Rutina que pide el numero de filas o de columnas de una matriz.
Parametros: char *cadena Puntero al string a mostrar.
Return: unsigned Numero de filas o de columnas. */
unsigned PedirTamano(const char *cadena)
{
unsigned valor;
do
{
printf("%s",cadena);
scanf("%u",&valor);
}
while (valor==0 || valor>TAM);
return valor;
}
/* Rutina que cambia una matriz.
Parametros: struct MATRIZ *a Puntero a la matriz que vamos a cambiar.
Return: Ninguno. */
void PedirMatriz(struct MATRIZ *a)
{
register unsigned i,j;
float valor;
76
El lenguaje de programacin C
a->fila=PedirTamano("\nNumero de filas de la matriz: ");
a->columna=PedirTamano("\nNumero de columnas de la matriz: \n");
for(i=0;i<a->fila;i++)
for(j=0;j<a->columna;j++)
{
printf("M[%u][%u]: ",i,j);
scanf("%f",&valor);
a->matriz[i][j]=valor;
}
}
/* Rutina que multiplica dos matrices. Las matrices se pasan por
puntero pues ello es mas rapido, aunque no se modifican en toda la
funcion.
Parametros: struct MATRIZ *a Puntero a la estructura con la primera
matriz a multiplicar.
struct MATRIZ *b Puntero a la estructura con la segunda
matriz a multiplicar.
struct MATRIZ *res Puntero a la estructura que contendra
el resultado.
Return: int Codigo de error. */
int Multiplicar(const struct MATRIZ *a,const struct MATRIZ *b,struct
MATRIZ *res)
{
register unsigned i,j,k;
if (a->columna!=b->fila)
return ERROR;
res->fila=a->fila;
res->columna=b->columna;
for(i=0;i<a->fila;i++)
for(j=0;j<b->columna;j++)
{
res->matriz[i][j]=0;
for(k=0;k<a->fila;k++)
res->matriz[i][j]+=a->matriz[i][k]*b->matriz[k][j];
}
return OK;
}
/* Rutina que muestra en pantalla el resultado de la operacion.
Parametros: struct MATRIZ *res Puntero a la estructura con el
resultado.
Return: Ninguno. */
void Mostrar(const struct MATRIZ *res)
{
register unsigned i,j;
for(i=0;i<res->fila;i++)
{
for(j=0;j<res->columna;j++)
printf("Res[%u][%u]= %f\n",i,j,res->matriz[i][j]);
printf("\nPulsa Enter para continuar.\n");
getchar();
}
}
77
El lenguaje de programacin C
int main(void)
{
struct MATRIZ a,b,res;
char d;
a.fila=a.columna=b.fila=b.columna=1;
a.matriz[0][0]=b.matriz[0][0]=1.0;
do
switch(d=Menu())
{
case '0':break;
case '1':PedirMatriz(&a);
break;
case '2':PedirMatriz(&b);
break;
case '3':
if (Multiplicar(&a,&b,&res)==ERROR)
printf("\nNo es posible multiplicar A*B\n");
else
Mostrar(&res);
break;
case '4':
if (Multiplicar(&b,&a,&res)==ERROR)
printf("\nNo es posible multiplicar B*A\n");
else
Mostrar(&res);
break;
}
while (d!='0');
return 0;
}
B.3 - ordenar.c.
/* Programa que ordena un fichero de cualquier tamao mediante el
algoritmo QuickSort. El fichero contiene como primer elemento un
unsigned con el numero de elementos del fichero, y a continuacion
figuran todos los elementos a ordenar */
#include <stdio.h>
#include <stdlib.h>
/* Rutina que lee el fichero de datos y devuelve un puntero al array
de la memoria reservada.
Parametros: char *nombre Nombre del fichero a leer.
unsigned *num Puntero al unsigned que contendra el numero
de elementos del array.
Return: float * Puntero al array de float, NULL si sucede un error. */
float *LeerFichero(const char *nombre, unsigned *num)
{
FILE *fp;
float *p;
register unsigned i;
78
El lenguaje de programacin C
if ((fp=fopen(nombre,"rt"))==NULL)
{
printf("\nError, no puedo abrir el fichero: %s\n",nombre);
return NULL;
}
fscanf(fp,"%u\n",num);
if ((p=(float *)calloc(*num,sizeof(float)))==NULL)
{
printf("\nError, memoria insuficiente.\n");
fclose(fp);
return NULL;
}
for(i=0;i<*num;i++)
fscanf(fp,"%f\n",&p[i]);
fclose(fp);
return p;
}
/* Rutina que escribe el fichero de datos ordenado.
Parametros: char *nombre Nombre del fichero donde guardar los datos.
unsigned num Numero de elementos del array.
float *p Puntero al array ordenado.
Return: Ninguno. */
void GuardarFichero(const char *nombre,const unsigned num,const float
*p)
{
FILE *fp;
register unsigned i;
if ((fp=fopen(nombre,"wt"))==NULL)
{
printf("\nError, no puedo crear el fichero: %s\n",nombre);
return;
}
fprintf(fp,"%u\n",num);
for(i=0;i<num;i++)
fprintf(fp,"%f\n",p[i]);
fclose(fp);
}
/* Rutina que ordena un array segun el algoritmo Quick-Sort.
Parametros:
float *p Puntero al array a ordenar.
unsigned izq Elemento de la izquierda a ordenar.
unsigned der Elemento de la derecha a ordenar.
Return:
Ninguno. */
void QuickSort(float *p,unsigned izq,unsigned der)
{
register unsigned i=izq,j=der;
float val,inter;
val=p[(i+j)/2];
do
{
while (p[i]<val) i++;
while (p[j]>val) j--;
if (i<=j)
79
El lenguaje de programacin C
{
inter=p[i];
p[i]=p[j];
p[j]=inter;
i++;
j--;
}
}
while (i<=j);
if (izq<j) QuickSort(p,izq,j);
if (i<der) QuickSort(p,i,der);
return;
}
int main(int argc,char *argv[])
{
float *p;
unsigned num;
if (argc!=3)
{
printf("\nModo de uso: %s <fichero1> <fichero2>\n",argv[0]);
return(1);
}
if ((p=LeerFichero(argv[1],&num))==NULL)
return 1;
QuickSort(p,0,num-1);
GuardarFichero(argv[2],num,p);
free(p);
return 0;
}
B.4 - fichero.c.
/* Programa que maneja una pequea base de datos directamente sobre el
fichero */
#include <stdio.h>
#include <string.h>
/* Definicion de las constantes del programa */
#define TAM 30
#define TAM_BUFFER 10
/* Definicion de los codigos de error */
#define OK 0
#define ERROR 1
/* Definicion de las estructuras de datos del programa */
struct FICHA
{
unsigned long dni;
char nombre[TAM];
char apellido[2][TAM];
};
80
El lenguaje de programacin C
/* Rutina que muestra un menu en pantalla.
Parametros: Ninguno.
Return: char Opcion elegida. */
char Menu(void)
{
register char d;
printf("\nElige una opcion:\n");
printf("\t0 -- Salir del programa.\n");
printf("\t1 -- Insertar un nuevo elemento.\n");
printf("\t2 -- Buscar un elemento por su dni.\n");
printf("\t3 -- Buscar un elemento por su apellido.\n");
while ((d=getchar())<'0' || d>'3');
return d;
}
/* Rutina que muestra un elemento en pantalla.
Parametros: struct FICHA *ficha Puntero a la estructura con los datos
a mostrar.
Return: Ninguno. */
void Mostrar(const struct FICHA *ficha)
{
printf("\n\nDNI: %lu\n",ficha->dni);
printf("NOMBRE: %s\n",ficha->nombre);
printf("PRIMER APELLIDO: %s\n",ficha->apellido[0]);
printf("SEGUNDO APELLIDO: %s\n",ficha->apellido[1]);
printf("\nPulsa Enter para continuar\n");
getchar();
}
/* Rutina que busca un elemento dado su dni.
Parametros: FILE *fichero Puntero al fichero de trabajo.
unsigned long dni Numero de dni a buscar.
char opcion Opcion de ejecucion, 1 mostrar, 0 no mostrar.
Return: int Codigo de error. */
int BuscarDni(FILE *fichero,const unsigned long dni,const char opcion)
{
struct FICHA ficha;
fseek(fichero,0L,SEEK_SET);
while (fread(&ficha,sizeof(struct FICHA),1,fichero)==1)
if (dni==ficha.dni)
{
if (opcion)
Mostrar(&ficha);
Return OK;
}
return ERROR;
}
/* Rutina que busca por apellidos.
Parametros: FILE *fichero Puntero al fichero de trabajo.
char *apellido Apellido a buscar.
Return: int Codigo de error.*/
81
El lenguaje de programacin C
int BuscarApellido(FILE *fichero,char *apellido)
{
struct FICHA ficha;
char encontrado=0;
fseek(fichero,0L,SEEK_SET);
while (fread(&ficha,sizeof(struct FICHA),1,fichero)==1)
if (!strcmp(apellido,ficha.apellido[0]) ||
!strcmp(apellido,ficha.apellido[1]))
{
Mostrar(&ficha);
encontrado=1;
}
return (encontrado) ? OK : ERROR;
}
/* Rutina que inserta un nuevo elemento en el fichero.
Parametros: FILE *fichero Puntero al fichero de trabajo.
struct FICHA *ficha Puntero a la ficha a insertar.
Return: int Codigo de error. */
int Insertar(FILE *fichero,const struct FICHA *ficha)
{
if (BuscarDni(fichero,ficha->dni,0)!=ERROR)
return ERROR;
fseek(fichero,0L,SEEK_END);
fwrite(ficha,sizeof(struct FICHA),1,fichero);
return OK;
}
/* Rutina que pide los datos de una ficha.
Parametros: struct FICHA *ficha Puntero a la ficha que contendra los
datos.
char opcion Opcion de ejecucion (0..2).
Return: struct FICHA * Puntero a la ficha que contiene los datos. */
struct FICHA *PedirDatos(struct FICHA *ficha,
const char opcion)
{
switch(opcion)
{
case 0: printf("\nDNI: ");
scanf("%lu",&ficha->dni);
fflush(stdin);
break;
case 1: fflush(stdin);
printf("APELLIDO: ");
strupr(gets(ficha->apellido[1]));
break;
case 2: printf("\nDNI: ");
scanf("%lu",&ficha->dni);
fflush(stdin);
printf("NOMBRE: ");
strupr(gets(ficha->nombre));
printf("PRIMER APELLIDO: ");
strupr(gets(ficha->apellido[0]));
printf("SEGUNDO APELLIDO: ");
strupr(gets(ficha->apellido[1]));
82
El lenguaje de programacin C
break;
}
return ficha;
}
int main(int argc,char *argv[])
{
FILE *fichero;
struct FICHA ficha;
register char d;
if (argc!=2)
{
printf("\nModo de uso: %s <fichero>\n",argv[0]);
return 1;
}
if ((fichero=fopen(argv[1],"a+b"))==NULL)
{
printf("\nError creando el fichero: %s\n",argv[1]);
return 1;
}
if (setvbuf(fichero,NULL,_IOFBF,
TAM_BUFFER*sizeof(struct FICHA))!=0)
{
printf("\nError creando el buffer para %d elementos.\n",
TAM_BUFFER);
fclose(fichero);
return 1;
}
do
switch(d=Menu())
{
case '0':break;
case '1':if (Insertar(fichero,PedirDatos(&ficha,2))==ERROR)
printf("\nNumero de dni duplicado.\n");
break;
case '2':PedirDatos(&ficha,0);
if (BuscarDni(fichero,ficha.dni,1)==ERROR)
printf("\nDni no existente.\n");
break;
case '3':PedirDatos(&ficha,1);
if (BuscarApellido(fichero,ficha.apellido[1])==ERROR)
printf("\nApellido inexistente.\n");
break;
}
while (d!='0');
fclose(fichero);
return 0;
}
B.5 - arbol.c.
/* Programa que lee las palabras de un fichero y las almacena en un
arbol binario */
#include <stdio.h>
El lenguaje de programacin C
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
/* Definicion de la longitud maxima de una palabra */
#define TAM 30
/* Definicion de las estructuras de datos del programa */
struct ARBOL
{
char pal[TAM+1];
struct ARBOL *izq,*der;
};
/* Rutina que lee una palabra del fichero.
Parametros: FILE *fichero Puntero al fichero de donde se leen las
palabras.
char *cadena Array de caracteres donde almacenar las
palabras.
Return: char * Puntero a la cadena con la palabra leida, NULL si
error. */
char *LeerPalabra(FILE *fichero,char *cadena)
{
register char d,i=0;
while ((d=fgetc(fichero))!=EOF && !isalpha(d));
if (d==EOF)
return NULL;
do
cadena[i++]=d;
while (i<TAM && (isalpha(d=fgetc(fichero)) || isdigit(d) ||
d=='_'));
cadena[i]='\0';
return cadena;
}
/* Rutina que crea el arbol binario, leyendo para ello el fichero.
Parametros: char *nombre Nombre del fichero a leer.
Return: struct ARBOL * Puntero a la raiz del arbol creado, NULL si
error. */
struct ARBOL *LeerFichero(char *nombre)
{
FILE *fichero;
char cadena[TAM+1],insertado;
int val;
struct ARBOL *cab=NULL,*p,*q;
if ((fichero=fopen(nombre,"rt"))==NULL)
{
printf("\nError, no puedo leer el fichero: %s\n",nombre);
return(NULL);
}
while (LeerPalabra(fichero,cadena)!=NULL)
{
if ((q=(struct ARBOL *)malloc(sizeof(struct ARBOL)))==NULL)
{
84
El lenguaje de programacin C
printf("\nError reservando memoria.\n");
fclose(fichero);
return NULL;
}
strcpy(q->pal,cadena);
q->izq=q->der=NULL;
if (cab==NULL)
cab=q;
else
{
p=cab;
insertado=0;
while (!insertado)
if ((val=strcmp(cadena,p->pal))<0)
if (p->izq==NULL)
{
p->izq=p;
insertado=1;
}
else
p=p->izq;
else
if (val>0)
if (p->der==NULL)
{
p->der=q;
insertado=1;
}
else
p=p->der;
else
insertado=1;
}
}
fclose(fichero);
return cab;
}
/* Rutina que muestra por pantalla el arbol ordenado a la vez que
libera la memoria.
Parametros: struct ARBOL *p Puntero al nodo a mostrar.
unsigned *cont Puntero al contador de elementos para
permitir parar la visualizacion.
Return: Ninguno.
*/
void Mostrar(struct ARBOL *p,unsigned *cont)
{
if (p->izq!=NULL)
Mostrar(p->izq,cont);
puts(p->pal);
if (++*cont>21)
{
*cont=1;
printf("\nPulsa Enter para continuar.\n");
getchar();
}
if (p->der!=NULL)
85
El lenguaje de programacin C
Mostrar(p->der,cont);
free(p);
}
int main(int argc,char *argv[])
{
struct ARBOL *p;
unsigned cont=1;
if (argc!=2)
{
printf("\nModo de uso: %s <fichero>\n",argv[0]);
return 1;
}
if ((p=LeerFichero(argv[1]))==NULL)
return 1;
printf("\n\n\n\n\n\n");
Mostrar(p,&cont);
return 0;
}
86