Sei sulla pagina 1di 47

Curso de programacin en C.

INDICE

Introduccin...................................................................................................................... 2
Programas. ........................................................................................................................ 2
Tipos bsicos y variables. ................................................................................................. 5
Funciones.......................................................................................................................... 6
Expresiones y operadores. ................................................................................................ 7
Conversin de tipos. ......................................................................................................... 9
Control de flujo............................................................................................................... 10
Definicin y prototipos de funciones.............................................................................. 12
Construccin de tipos. .................................................................................................... 13
mbito de funciones y variables. ................................................................................... 17
Punteros. ......................................................................................................................... 18
El preprocesador. ............................................................................................................ 21
Funciones de entrada y salida por pantalla. .................................................................... 22
Funciones de asignacin de memoria. ............................................................................ 25
Funciones matemticas................................................................................................... 26
Operaciones con ficheros................................................................................................ 27
Ejercicios.. .............................................................................................. 34
Bibliografa y referencias. .............................................................................................. 53
2


Introduccin.

C es un lenguaje de programacin de propsito general que ofrece economa sintctica, control de flujo y
estructuras sencillas y un buen conjunto de operadores. No es un lenguaje de muy alto nivel y ms bien
un lenguaje pequeo, sencillo y no est especializado en ningn tipo de aplicacin. Esto lo hace un
lenguaje potente, con un campo de aplicacin ilimitado y sobre todo, se aprende rpidamente. En poco
tiempo, un programador puede utilizar la totalidad del lenguaje.

Este lenguaje ha sido estrechamente ligado al sistema operativo UNIX, puesto que fueron desarrollados
conjuntamente. Sin embargo, este lenguaje no est ligado a ningn sistema operativo ni a ninguna
mquina concreta. Se le suele llamar lenguaje de programacin de sistemas debido a su utilidad para
escribir compiladores y sistemas operativos, aunque de igual forma se pueden desarrollar cualquier tipo
de aplicacin.

Programas.

La mejor forma de aprender un lenguaje es programando con l. El programa ms sencillo que se puede
escribir en C es el siguiente:

main()
{
}

Como nos podemos imaginar, este programa no hace nada, pero contiene la parte ms importante de
cualquier programa C y adems, es el ms pequeo que se puede escribir y que se compile
correctamente. En el se define la funcin main, que es la que ejecuta el sistema operativo al llamar a un
programa C. El nombre de una funcin C siempre va seguida de parntesis, tanto si tiene argumentos
como si no. La definicin de la funcin est formada por un bloque de sentencias, que esta encerrado
entre llaves {}.

Un programa algo ms complicado es el siguiente:



#include <stdio.h>
main()
{
printf("Hola amigos!\n");
}


Con el visualizamos el mensaje Hola amigos! en el terminal. En la primera lnea indica que se
tengan en cuenta las funciones y tipos definidos en la librera stdio (standard input/output). Estas
definiciones se encuentran en el fichero header stdio.h. Ahora, en la funcin main se incluye una
nica sentencia que llama a la funcin printf. Esta toma como argumento una cadena de caracteres,
que se imprimen van encerradas entre dobles comillas " ". El smbolo \n indica un cambio de lnea.
Hay un grupo de smbolos, que son tratados como caracteres individuales, que especifican algunos
caracteres especiales
del cdigo ASCII. Los ms importantes son:





\a

alert

\b

backspace

\f

formfeed

\n

newline
3

\r

carriage return

\t

horizontal tab

\v

vertical tab

\\

backslash

\'

single quote

\"

double quote

\OOO

visualiza un carcter cuyo cdigo ASCII es OOO en octal.

\xHHH

visualiza un carcter cuyo cdigo ASCII es HHH en hexadecimal.




Las funciones de entrada y salida y los formatos utilizados los explicaremos con ms detalle en otro
captulo.


Tipos bsicos y variables.

Los tipos de datos bsicos definidos por C son caracteres, nmeros enteros y nmeros en coma flotante.
Los caracteres son representados por char, los enteros por short, int, long y los nmeros en
coma flotante por floaty double. Los tipos bsicos disponibles y su tamao son:





char

Carcter

(normalmente 8 bits)

short

Entero corto con signo

(normalmente 16 bits)

int

Entero con signo

(depende de la implementacin)

unsigned

Entero sin signo

(depende de la implementacin)

long

Entero largo con signo

(normalmente 32 bits)

float

Flotante simple

(normalmente 32 bits)

double

Flotante doble

(normalmente 64 bits)

La palabra unsigned en realidad es un modificador aplicable a tipos enteros, aunque si no se
especifica un tipo se supone int. Un modificador es una palabra clave de C que indica que una variable,
o funcin, no se comporta de la forma normal. Hay tambin un modificador signed, pero como los
tipos son por defecto con signo, casi no se utiliza.







4
Las variables son definidas utilizando un identificador de tipo seguido del nombre de la variable.
Veamos el siguiente programa:




#include <stdio.h>
main()
{
float cels, farh;


farh = 35.0;
cels = 5.0 * ( farh - 32.0 ) / 9.0;
printf("-> %f F son %f C\n", farh, cels );
}

En el programa anterior se definen dos variables float, se asigna un valor a la primera y se calcula la
segunda mediante una expresin aritmtica. Las asignaciones en C tambin son una expresin, por lo que
se pueden utilizar como parte de otra expresin, pero segn que prcticas de este tipo no son muy
recomendables ya que reducen la legibilidad del programa. En la instruccin printf, el smbolo %f
indica que se imprime un nmero en coma flotante.

Hay un tipo muy importante que se representa por void que puede significar dos cosas distintas,
segn su utilizacin. Puede significar nada, o sea que si una funcin devuelve un valor de tipo void
no devuelve ningn resultado, o puede significar cualquier cosa, como puede ser un puntero a void es
un puntero genrico a cualquier tipo de dato. Ms adelante veremos su utilizacin.

Funciones.

Un programa C est formado por un conjunto de funciones que al menos contiene la funcin main. Una
funcin se declara con el nombre de la funcin precedido del tipo de valor que retorna y una lista de
argumentos encerrados entre parntesis. El cuerpo de la funcin est formado por un conjunto de
declaraciones y de sentencias comprendidas entre llaves. Veamos un ejemplo de utilizacin de funciones:


#include <stdio.h>
#define VALOR 5
#define FACT 120


int fact_i ( int v )
{
int r = 1, i = 0;


while ( i <= v ) {
r = r * i;
i = i + 1;
}
return r;
}


int fact_r ( int v )
{
if ( v == 0 )
return 1;
else
return v * fact_r(v-1);
}

5

main()
{
int r, valor = VALOR;


if ( (r = fact_i(valor)) != fact_r(valor) )
printf("Codificacin errnea!!.\n");
else
if ( r == FACT )
printf("Codificacin correcta.\n");
else
printf("Algo falla!!.\n");
}

Se definen dos funciones, fact_i y fact_r, adems de la funcin main. Ambas toman como
parmetro un valor entero y devuelven otro entero. La primera calcula el factorial de un nmero de forma
iterativa, mientras que la segunda hace lo mismo de forma recursiva.

Todas las lneas que comienzan con el smbolo #indican una directiva del precompilador. Antes de
realizar la compilacin en C se llama a un precompilador cuya misin es procesar el texto y realizar
ciertas sustituciones textuales. Hemos visto que la directiva #includeincluye el texto contenido en un
fichero en el fuente que estamos compilando. De forma parecida, #define nombre texto sustituye
todas las apariciones de nombre por texto. As, en el fuente, la palabra VALOR se sustituye por el nmero
5.

El valor que debe devolver una funcin se indica con la palabra return. La evaluacin de la expresin
debe dar una valor del mismo tipo de dato que el que se ha definido como resultado. La declaracin de
una variable puede incluir una inicializacin en la misma declaracin. Se debe tener muy en cuenta que
en C todos los argumentos son pasados 'por valor'. No existe el concepto de paso de parmetros 'por
variable' o 'por referencia'. Veamos un ejemplo:




int incr ( int v )
{
return v + 1;
}


main()
{
int a, b;


b = 3;
a = incr(b);
/*
a = 4 mientras que
b = 3. No ha cambiado despus de la llamada.
*/
}

En el ejemplo anterior el valor del parmetro de la funcin incr, aunque se modifique dentro de la
funcin, no cambia el valor de la variable b de la funcin main. Todo el texto comprendido entre los
caracteres /* y */ son comentarios al programa y son ignorados por el compilador. En un fuente C los
comentarios no se pueden anidar.

Expresiones y operadores.
6

Los distintos operadores permiten formar expresiones tanto aritmticas como lgicas. Los operadores
aritmticos y lgicos son:

+, - suma, resta

++, -- incremento, decremento

*, /, % multiplicacin, divisin, mdulo

>>, << rotacin de bits a la derecha, izquierda.

& AND booleano

| OR booleano

^ EXOR booleano

~ complemento a 1

! complemento a 2, NOT lgico

==, != igualdad, desigualdad

&&, || AND, OR lgico

<, <= menor, menor o igual

>, >= mayor, mayor o igual


En estos operadores deben tenerse en cuenta la precedencia de operadores y las reglas de asociatividad,
que son las normales en la mayora de lenguajes. Se debe consultar el manual de referencia para obtener
una explicacin detallada. Adems hay toda una serie de operadores aritmticos con asignacin, como
pueden ser +=y ^=.

En la evaluacin de expresiones lgicas, los compiladores normalmente utilizan tcnicas de evaluacin
rpida. Para decidir si una expresin lgica es cierta o falsa muchas veces no es necesario evaluarla
completamente. Por ejemplo una expresin formada <exp1>|| <exp2>, el compilador evala primero
<exp1>y si es cierta, no evala <exp2>. Por ello se deben evitar construcciones en las que se modifiquen
valores de datos en la propia expresin, pues su comportamiento puede depender de la implementacin
del compilador o de la optimizacin utilizada en una compilacin o en otra. Estos son errores que se
pueden cometer fcilmente en C ya que una asignacin es tambin una expresin.

Debemos evitar:


if (( x++ > 3 ) || ( x < y ))

y escribir en su lugar:


x++;
if (( x > 3 ) || ( x < y ))












Hay un tipo especial de expresin en C que se denomina expresin condicional y est representada por los
operadores ? : . Su utilizacin es como sigue: <e>? <x>: <y>. Se evala si e entonces x; si no, y.
7
int mayor ( int a, int b )
{
return ( a > b ) ? TRUE : FALSE;
}


waste_time ()
{
float a, b = 0.0;


( b > 0.0 ) ? sin(M_PI / 8) : cos(M_PI / 4);
}

Conversin de tipos.

Cuando escribimos una expresin aritmtica a+b, en la cual hay variables o valores de distintos tipos, el
compilador realiza determinadas conversiones antes de que evale la expresin. Estas conversiones
pueden ser para 'aumentar' o 'disminuir' la precisin del tipo al que se convierten los elementos de la
expresin. Un ejemplo claro, es la comparacin de una variable de tipo intcon una variable de tipo
double. En este caso, la de tipo intes convertida a doublepara poder realizar la comparacin.

Los tipos pequeos son convertidos de la forma siguiente: un tipo char se convierte a int, con el
modificador signed si los caracteres son con signo, o unsigned si los caracteres son sin signo. Un
unsigned char es convertido a intcon los bits ms altos puestos a cero. Un signed char es
convertido a intcon los bits ms altos puestos a uno o cero, dependiendo del valor de la variable.

Para los tipos de mayor tamao: si un operando es de tipo double, el otro es convertido a double. Si un
operando es de tipo float, el otro es convertido a float. Si un operando es de tipo unsigned long,
el otro es convertido a unsigned long. Si un operando es de tipo long, el otro es convertido a long.
Si un operando es de tipo unsigned, el otro es convertido a unsigned. Si no, los operandos
son te tipo int.

Una variable o expresin de un tipo se puede convertir explcitamente a otro tipo, anteponindole el tipo
entre parntesis.

void cambio_tipo (void)
{
float a;
int b;


b = 10;
a = 0.5;


if ( a <= (float) b )
menor();
}
88


Control de flujo.

La sentencia de control bsica es if (<e>) then <s> else <t>. En ella se evala una expresin
condicional y si se cumple, se ejecuta la sentencia s; si no, se ejecuta la sentencia t. La segunda parte de la
condicin, else <t>, es opcional.




int cero ( double a )
{
if ( a == 0.0 )
return (TRUE);
else
return (FALSE);
}



En el caso que <e>no sea una expresin condicional y sea aritmtica, se considera falso si vale 0; y si no,
verdadero. Hay casos en los que se deben evaluar mltiples condiciones y nicamente se debe evaluar una
de ellas. Se puede programar con un grupo de sentencias if then elseanidadas, aunque ello puede
ser farragoso y de complicada lectura. Para evitarlo nos puede ayudar la sentencia switch. Su
utilizacin es:




switch (valor) {

case valor1: <sentencias>

case valor2: <sentencias>

...

default: <sentencias>

}



Cuando se encuentra una sentencia case que concuerda con el valor del switch se ejecutan las
sentencias que le siguen y todas las dems a partir de ah, a no ser que se introduzca una sentencia break
para salir de la sentencia switch. Por ejemplo,




ver_opcion ( char c )
{
switch(c){
case 'a': printf("Op A\n");
break; case 'b': printf("Op
B\n"); break; case 'c':
case 'd': printf("Op C o D\n"); break;
default: printf("Op ?\n");
}
}





99
Otras sentencias de control de flujo son las que nos permiten realizar iteraciones sobre un conjunto de
sentencias. En C tenemos tres formas principales de realizar iteraciones. La sentencia while (<e>)
<s>es seguramente la ms utilizada. La sentencia, o grupo de sentencias <s>se ejecuta mientras la
evaluacin de la expresin <e>sea verdadera.




long raiz ( long valor )
{
long r = 1;


while ( r * r <= valor )
r++;


return r;
}



Otra sentencia iterativa, que permite inicializar los controles del bucle se la sentencia for ( <i>; <e>;
<p>) <s>. La sentencia for se puede escribir tambin como:




<i>;

while ( <e> ) {

<s>;

<p>;

}

El ejemplo anterior se podra escribir como:




long raiz ( long valor )
{
long r;


for ( r = 1; r * r <= valor; r++ )
;


return r;
}

Una variacin de la sentencia whilees: do <s>while ( <e>); En ella la sentencia se ejecuta al
menos una vez, antes de que se evale la expresin condicional.
10
10 Otras sentencias interesantes, aunque menos utilizadas son break y continue. break provoca que se
termine la ejecucin de una iteracin o para salir de la sentencia switch, como ya hemos visto. En
cambio, continueprovoca que se comience una nueva iteracin, evalundose la expresin de control.
Veamos dos ejemplos:




void final_countdown (void)
{
int count = 10;


while ( count-- > 1 ) {
if ( count == 4 )
start_engines();
if ( status() == WARNING )
break;
printf("%d ", count );
}
if ( count == 0 ) {
launch();
printf("Shuttle launched\n");
}
else {
printf("WARNING condition received.\n");
printf("Count held at T - %d\n", count );
}
}


d2 ()
{
int f;


for ( f = 1; f <= 50; f++ ) {
if ( f % 2 == 0 )
continue;
printf("%d", f );
}
}

Definicin y prototipos de funciones.

Los programas sencillos, como los ejemplo planteados hasta ahora, normalmente no necesitan un nivel de
estructuracin elevado. Pero cuando stos crecen un poco necesitamos estructurarlos adecuadamente para
mantenerlos legibles, facilitar su mantenimiento y para poder reutilizar ciertas porciones de cdigo. El
mecanismo C que nos permite esto son las funciones. Con los compiladores, los fabricantes nos
proporcionan un conjunto importante de funciones de librera. A veces, nos puede interesar construir
nuestras propias libreras. Ya hemos utilizado funciones, pero veamos cmo debemos definirlas.

Los prototipos de funciones son una caracterstica clave de la recomendacin ANSI del C. Un prototipo
es una declaracin que toma la forma:

tipo_resultado nombre_funcin ( tipo_parmetro nombre_parmetro ... );

Aqu tenemos varios ejemplos:



11
11

int fact_i ( int v );
int mayor ( int a, int b );
int cero ( double a );
long raiz ( long valor );
void final_countdown ( void );
int main ( int argc, char **argv );



Observando el prototipo de una funcin podemos decir exactamente que tipo de parmetros necesita y
que resultado devuelve. Si una funcin tiene como argumento void, quiere decir que no tiene
argumentos, al igual que si el resultado es void, no devuelve ningn valor.

En la vieja definicin de Kernighan y Ritchie el tipo que devolva una funcin se declaraba nicamente si
era distinto de int. Similarmente, los parmetros eran declarados en el cuerpo de la funcin, en lugar de
utilizar la lista de parmetros. Por ejemplo:

mayor ( a, b )
int a;
int b;
{
...
}

Las funciones al viejo estilo se compilan correctamente en muchos compiladores actuales. Por contra,
proporcionan menos informacin sobre sus parmetros y errores que afecten al tipo de parmetros de
llamada a las funciones no pueden ser detectados automticamente. Por tanto, la declaracin de una
funcin debe escribirse igual que su prototipo pero sin el punto y coma final. El cuerpo de la funcin le
sigue encerrado entre llaves.

En un programa que est formado por distintas partes bien diferenciadas es conveniente utilizar mltiples
ficheros fuente. Cada fuente agrupa las funciones semejantes, como por ejemplo en un compilador
podramos tener un fuente para el anlisis lxico, otro para el sintctico y otro para la generacin de
cdigo. Pero en un fuente necesitaremos funciones que se han definido en otro. Para ello, escribiremos un
fichero de cabecera (header), que contendr las declaraciones que podemos necesitar en otros fuente. As,
en el fuente que implementa el analizador sintctico pondremos una lnea #include "lexic.h". De
esta forma al compilar el mdulo sintctico tendremos todos los prototipos de las funciones del lxico y el
compilador podr detectar malas utilizaciones de las funciones all definidas.

Construccin de tipos.

Los datos del mundo real, normalmente no estn formados por variables escalares de tipos los tipos
bsicos. Por ejemplo, nos puede interesar saber cuntos mdulos en C hemos escrito cada semana, a lo
largo del ao. O tambin nos interesa tener los datos de cada planeta del Sistema Solar, masa, posicin,
velocidad y aceleracin, para un programa de simulacin de la ley de gravitacin de Newton. Para
resolver el primer caso, C nos permite declarar una variable que sea de tipo vector. Para el segundo,
podemos definir un registro para cada elemento.

Un vector es una porcin de memoria que es utilizada para almacenar un grupo de elementos del mismo
tipo Un vector se declara: tipo nombre [tamao];. Por ejemplo, int modulo[52];. Aqu 'modulo'
es un vector de 52 elementos enteros.

main()
{
int f, modulo[52];


for ( f = 0; f < 52; f++ )
modulo[f] = 0;
...
}
12
12

Cada elemento de un vector es accedido mediante un nmero de ndice y se comporta como una variable
del tipo base del vector. Los elementos de un vector son accedidos por ndices que van desde 0 hasta N-1
para un vector de N elementos. Los elementos de un vector pueden ser inicializados en la misma
declaracin:




char vocal[5] = { 'a', 'e', 'i', 'o', 'u' };
float n_Bode[5] = { 0.4, 0.7, 1, 1.6, 2.8 };



Tambin podemos definir vectores multidimensionales. C no impone ninguna limitacin al nmero de
dimensiones de un vector. Existe, en cambio, la limitacin del tamao de memoria que podamos utilizar
en nuestro ordenador. Por ejemplo, para la declaracin de un vector multidimensional podemos escribir:




int video[25][80][2];



El tamao de la variable video es proporcional al tamao del tipo inty al tamao de cada dimensin.
Existe un operador C que nos permite obtener el tamao de un tipo o de una variable. Este es sizeof()
y nos proporciona el tamao en bytes.

if ( sizeof(video) == 80 * 25 * 2 * sizeof(int) )
printf("OK!\n");
else
printf("Algo no funciona.\n");

Un tipo vector muy utilizado es la cadena de caracteres (string). Si queremos asignar espacio para un
string podemos hacer:


char nombre[60], direccion[80];

Es un vector C pero con la particularidad de que el propio lenguaje utiliza un carcter especial como
marca de final de string. As en un vector de caracteres de tamao N podremos almacenar una cadena de
N-1 caracteres, cuyo ltimo carcter estar en la posicin N-2 y la marca de final de string en la N-1.
Veamos un ejemplo:


char servei[6] = "SCI";

La posicin 0 contiene el carcter 'S'; la 1 el 'C'; la 2 el 'I'; la 3 el '\0', marca de final de string. El resto de
componentes no estn definidas. En la inicializacin de strings no se debe indicar el final; ya lo hace el
compilador. Para la manipulacin de cadenas de caracteres ANSI proporciona el fichero string.h
que contiene las declaraciones de un conjunto de funciones proporcionadas con la librera del compilador.

Un registro agrupa distintos tipos de datos en una misma estructura. Los registros son definidos de la
forma:

struct nombre { lista de declaraciones };

Los campos de cada registro pueden ser tipos bsicos u otros registros. Por ejemplo:


struct planeta {
struct 3D r, v, a;
double masa;
char nom[10];
};

struct 3D {
double x,y,z;};

13
13
Los campos de cada registro son accesibles mediante el nombre del registro seguido de punto y el nombre
del campo, como por ejemplo venus.r.x = 1.0;. Cada campo se comporta como lo hace su tipo
bsico. C no proporciona mecanismos de inicializacin ni copia de registros, por lo que debe ser el
programador el que los implemente.

A veces los datos se ajustan a series ordenadas en las cuales un elemento sigue, o precede, a otro. Un caso
tpico son los das de la semana. Si se desea realizar iteraciones con los das de la semana una forma es,
por ejemplo, asignar un nmero a cada da con #define. C proporciona un mecanismo compacto para
realizar esto; son las enumeraciones. Una enumeracin toma la forma: enum nombre { lista de
elementos };. Veamos un ejemplo:


void planning ( void )
{
enum diasemana { lunes, martes, miercoles,
jueves, viernes, sabado, domingo };
int dia;


for ( dia = lunes; dia <= viernes; dia++ )
trabajar(dia);
if ( dia == sabado )
salir();
}



A cada elemento de la enumeracin se le asigna un valor consecutivo, comenzando por 0. Si se desea que
el valor asignado sea distinto se puede hacer de la siguiente forma:




enum puntos { t_6_25 = 3, t_zona = 2, t_libre = 1 };



Muchas veces es conveniente renombrar tipos de datos para que la escritura del programa se nos haga
ms sencilla y la lectura tambin. Esto se puede conseguir con la palabra typedef. Con ella damos un
nombre a cierto tipo, o combinacin de ellos.


typedef struct planeta PLANETA;


PLANETA mercurio, venus, tierra, marte;



Al igual que podemos inicializar las variables de tipos bsicos en la misma declaracin, tambin lo
podemos hacer con los registros. Los valores de cada campo de un registro van separados por comas y
encerrados entre llaves.




PLANETA mercurio = { { 0.350, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 },
100, "Mercurio" };
14
14
mbito de funciones y variables.

El mbito, o visibilidad, de una variable nos indica en que lugares del programa est activa esa variable.
Hasta ahora, en los ejemplos que hemos visto, se han utilizado variables definidas en el cuerpo de
funciones. Estas variables se crean en la memoria del ordenador cuando se llama a la funcin y se
destruyen cuando la funcin termina de ejecutarse. Es necesario a veces, que una variable tenga un valor
que pueda ser accesible desde todas las funciones de un mismo fuente, e incluso desde otros fuentes.

En C, el mbito de las variables depende de dnde han sido declaradas y si se les ha aplicado algn
modificador. Una variable definida en una funcin es, por defecto, una variable local. Esto es, que slo
existe y puede ser accedida dentro de la funcin. Para que una variable sea visible desde una funcin
cualquiera del mismo fuente debe declararse fuera de cualquier funcin. Esta variable slo ser visible en
las funciones definidas despus de su declaracin. Por esto, el lugar ms comn para definir las variables
globales es antes de la definicin de ninguna funcin. Por defecto, una variable global es visible desde
otro fuente. Para definir que existe una variable global que est definida en otro fuente tenemos que
anteponer la palabra extern a su declaracin. Esta declaracin nicamente indica al compilador que se
har referencia a una variable declarada en un mdulo distinto al que se compila.

Las variables locales llevan implcito el modificador auto. Este indica que se crean al inicio de la
ejecucin de la funcin y se destruyen al final. En un programa sera muy ineficiente en trminos de
almacenamiento que se crearan todas las variables al inicio de la ejecucin. Por contra, en algunos casos
es deseable. Esto se consigue anteponiendo el modificador static a una variable local. Si una funcin
necesita una variable que nicamente sea accedida por la misma funcin y que conserve su valor a travs
de sucesivas llamadas, es el caso adecuado para que sea declarada local a la funcin con el modificador
static. El modificador static se puede aplicar tambin a variables globales. Una variable global es
por defecto accesible desde cualquier fuente del programa. Si, por cualquier motivo, se desea que una de
estas variables no se visible desde otro fuente se le debe aplicar el modificador static. Lo mismo
ocurre con las funciones. Las funciones definidas en un fuente son utilizables desde cualquier otro. En
este caso conviene incluir los prototipos de las funciones del otro fuente. Si no se desea que alguna
funcin pueda ser llamada desde fuera del fuente en la que est definida se le debe anteponer el
modificador static.




void contar ( void )
{
static long cuenta = 0;


cuenta++;
printf("Llamada %ld veces\n", cuenta );
}



Un modificador muy importante es const. Con l se pueden definir variables cuyo valor debe
permanecer constante durante toda la ejecucin del programa. Tambin se puede utilizar con argumentos
de funciones. En esta caso se indica que el argumento en cuestin es un parmetro y su valor no debe ser
modificado. Si al programar la funcin, modificamos ese parmetro, el compilador nos indicar el error.




#define EULER 2.71828
const double pi = 3.14159;


double lcercle ( const double r )
{
15
15


return 2.0 * pi * r;
}


double EXP ( const double x )
{
return pow ( EULER, x );
}


double sinh ( const double x )
{
return (exp(x) - exp(-x)) / 2.0;
}



Debemos fijarnos que en el ejemplo anterior pi es una variable, la cual no podemos modificar. Por ello
pi slo puede aparecer en un nico fuente. Si la definimos en varios, al linkar el programa se nos
generar un error por tener una variable duplicada. En el caso en que queramos acceder a ella desde otro
fuente, debemos declararla con el modificador extern.

Otro modificador utilizado algunas veces es el register. Este modificador es aplicable nicamente a
variables locales e indica al compilador que esta variable debe ser almacenada permanentemente en un
registro del procesador del ordenador. Este modificador es herencia de los viejos tiempos, cuando las
tecnologas de optimizacin de cdigo no estaban muy desarrolladas y se deba indicar qu variable era
muy utilizada en la funcin. Hoy en da casi todos los compiladores realizan un estudio de qu variables
locales son las ms adecuadas para ser almacenadas en registros, y las asignan automticamente. Con los
compiladores modernos se puede dar el caso de que una declaracin register inadecuada disminuya la
velocidad de ejecucin de la funcin, en lugar de aumentarla. Por ello, hoy en da, la utilizacin de este
modificador est en desuso, hasta el punto de que algunos compiladores lo ignoran. Se debe tener en
cuenta que de una variable declarada como register no se puede obtener su direccin, ya que est
almacenada en un registro y no en memoria.

Punteros.

Cada variable de un programa tiene una direccin en la memoria del ordenador. Esta direccin indica la
posicin del primer byte que la variable ocupa. En el caso de una estructura es la direccin del primer
campo. En los ordenadores actuales la direccin de inicio se considera la direccin baja de memoria.
Como en cualquier caso las variables son almacenadas ordenadamente y de una forma predecible, es
posible acceder a estas y manipularlas mediante otra variables que contenga su direccin. A este tipo de
variables se les denomina punteros.

Los punteros C son el tipo ms potente y seguramente la otra clave del xito del lenguaje. La primera
ventaja que obtenemos de los punteros es la posibilidad que nos dan de poder tratar con datos de un
tamao arbitrario sin tener que moverlos por la memoria. Esto puede ahorrar un tiempo de computacin
muy importante en algunos tipos de aplicaciones. Tambin permiten que una funcin reciba y cambie el
valor de una variable. Recordemos que todas las funciones C nicamente aceptan parmetros por valor.
Mediante un puntero a una variable podemos modificarla indirectamente desde una funcin cualquiera.

Un puntero se declara de la forma: tipo *nombre;




float *pf;
PLANETA *pp;
char *pc;
16
16 Para manipular un puntero, como variable que es, se utiliza su nombre; pero para acceder a la variable a la
que apunta se le debe preceder de *. A este proceso se le llama indireccin. Accedemos indirectamente a
una variable. Para trabajar con punteros existe un operador, &, que indica 'direccin de'. Con l se puede
asignar a un puntero la direccin de una variable, o pasar como parmetro a una funcin.


void prova_punter ( void )
{
long edat;
long *p;


p = &edat;
edad = 50;
printf("La edat es %ld\n", edat );
*p = *p / 2;
printf("La edat es %ld\n", edat );
}


void imprimir_string ( char string[] )
{
char *p;


for ( p = string; *p != '\0'; p++ )
imprimir_char(*p);
}



Los punteros tambin se pueden utilizar con los registros. Para ello se utiliza la notacin ->en lugar del
punto que utilizbamos anteriormente. Si p es un puntero a PLANETA, y queremos conocer su masa,
debemos escribir p->masa. Un puntero se puede utilizar para almacenar la direccin de cualquier tipo de
datos, tanto simple como un vector, como un registro. De cmo lo definimos y lo utilizamos depende su
comportamiento. Las componentes de un vector, por ejemplo pueden ser referenciadas por un puntero al
tipo de cada componente. Veamos un ejemplo:


#define N_PLA 9


static PLANETA SSolar[N_PLA];


void init_SistemaSolar ( void )
{
PLANETA *p;


for ( p = SSolar; p < SSolar[N_PLA]; p++ )
init_planeta(p);
}
void init_planeta ( PLANETA *p )
{
p->masa = 0; p-
>nom = "";
init_co(&(p->r));
init_co(&(p->v));
init_co(&(p->a));
}


17
17
void init_co ( struct co *c )
{
c->x = c->y = c->z = 0;
}



Definimos un vector de N_PLA componentes de tipo PLANETA. Este tipo est formado por un registro.
Vemos que en la funcin de inicializacin del vector el puntero a la primera componente se inicializa con
el nombre del vector. Esto es una caracterstica importante de C. La direccin de la primera componente
de un vector se puede direccionar con el nombre del vector. Esto es debido a que en la memoria del
ordenador, los distintos elementos estn ordenados de forma ascendente. As, SSolar se puede utilizar
como &SSolar[0]. A cada iteracin llamamos a una funcin que nos inicializar los datos de cada
planeta. A esta funcin le pasamos como argumento el puntero a la componente en curso para que,
utilizando la notacin ->, pueda asignar los valores adecuados a cada campo del registro. Debemos
fijarnos en el incremento del puntero de control de la iteracin, p++. Con los punteros se pueden realizar
determinadas operaciones aritmticas aunque, a parte del incremento y decremento, no son muy
frecuentes. Cuando incrementamos un puntero el compilador le suma la cantidad necesaria para que
apunte al siguiente elemento de la memoria. Debemos fijarnos que esto es aplicable slo siempre que
haya distintas variables o elementos situados consecutivamente en la memoria, como ocurre con los
vectores.

De forma similar se pueden utilizar funciones que tengan como parmetros punteros, para cambiar el
valor de una variable. Veamos:




void intercambio ( void )
{
int a, b;


a = 1;
b = 2;
swap( &a, &b );
printf(" a = %d b = %d\n", a, b );
}


void swap ( int *x, int *y )
{
int tmp;


tmp = *x;

*x = *y;
*y = tmp;
}



La sintaxis de C puede, a veces, provocar confusin. Se debe distinguir lo que es un prototipo de una
funcin de lo que es una declaracin de una variable. As mismo, un puntero a un vector de punteros,
etc...



int f1();

funcin que devuelve un entero

int *p1;

puntero a entero

int *f2();

funcin que devuelve un puntero a entero
18
18

int
(*pf)(int);

puntero a funcin que toma y devuelve un entero

int (*pf2)(int
*pi);

puntero a funcin que toma un puntero a entero y devuelve
un entero

int a[3];

vector de tres enteros

int *ap[3];

vector de tres punteros a entero

int *(ap[3]);

vector de tres punteros a entero

int (*pa)[3];

puntero a vector de tres enteros

int
(*apf[5])(int
*pi);

vector de 5 punteros a funcin que toman un puntero a entero
y devuelven un entero

En los programas que se escriban se debe intentar evitar declaraciones complejas que dificulten la
legibilidad del programa. Una forma de conseguirlo es utilizando typedef para redefinir/renombrar
tipos.

typedef int *intptr;
typedef intptr (*fptr) ( intptr );
fptr f1, f2;

El preprocesador.

El preprocesador es una parte del compilador que se ejecuta en primer lugar, cuando se compila un fuente
C y que realiza unas determinadas operaciones, independientes del propio lenguaje C. Estas operaciones
se realizan a nivel lxico y son la inclusin de otros textos en un punto del fuente, realizar sustituciones o
eliminar ciertas partes del fuente. Debemos tener en cuenta que el preprocesador trabaja nicamente con
el texto del fuente y no tiene en cuenta ningn aspecto sintctico ni semntico del lenguaje.

El control del preprocesador se realiza mediante determinadas directivas incluidas en el fuente. Una
directiva es una palabra que interpreta el preprocesador, que siempre va precedida por el smbolo #y que
est situada a principio de lnea.

La directiva #definese utiliza para definir una macro. Las macros proporcionan principalmente un
mecanismo para la sustitucin lxica. Una macro se define de la forma #defineid secuencia. Cada
ocurrencia de id en el fuente es sustituida por secuencia. Puede definirse una macro sin una secuencia de
caracteres. Una macro se puede "indefinir" mediante la directiva #undef.




#define MSG01 "SCI-I-START: Starting system kernel\n"
#define MSG02 "SCI-I-STOP: Stopping system kernel\n"


void print_msg ( void )
{
if ( check_state() == START )
printf(MSG01);
else
printf(MSG02);
}








19
19
El estado de una macro, si est definida o no, se puede comprobar mediante las directivas #ifdef y
#ifndef. Estas dos directivas se deben completar con una #endif y, el texto comprendido entre
ambas es procesado si la macro est definida. Todas las directivas deben ser completadas en el mismo
fuente y pueden ser anidadas.




#ifndef M_PI
#define M_PI 3.1415927
#endif



El preprocesador nos permite tambin incluir tambin otros ficheros en un fuente C. Esto se consigue con
la directiva #include. Esta puede tomar tres formas: #include <fichero>, #include "fichero" y
#includemacro. La diferencia entre la primera y la segunda est en el lugar dnde se buscar el
fichero en cuestin. Normalmente se utiliza la primera para ficheros proporcionados por la librera del
compilador y la segunda para ficheros creados por el programador.

Funciones de entrada y salida por pantalla.

En este apartado y los siguientes vamos a ver algunas de las funciones ms importantes que nos
proporcionan las libreras definidas por ANSI y su utilizacin. Como hemos visto hasta ahora, el lenguaje
C no proporciona ningn mecanismo de comunicacin ni con el usuario ni con el sistema operativo. Ello
es realizado a travs de las funciones de librera proporcionadas por el compilador.

El fichero de declaraciones que normalmente ms se utiliza es el stdio.h. Vamos a ver algunas
funciones definidas en l.

Una funcin que ya hemos utilizado y que, ella y sus variantes, es la ms utilizadas para la salida de
informacin es printf. Esta permite dar formato y enviar datos a la salida estndar del sistema
operativo.

#include <stdio.h>

int printf ( const char *format [, argumentos, ...] );


Acepta un string de formato y cualquier nmero de argumentos. Estos argumentos se aplican a cada uno
de los especificadores de formato contenidos en format. Un especificador de formato toma la forma
%[flags][width][.prec][h|l] type. El tipo puede ser:



d, i

entero decimal con signo

o

entero octal sin signo

u

entero decimal sin signo

x

entero hexadecimal sin signo (en minsculas)

X

entero hexadecimal sin signo (en maysculas)

f

coma flotante en la forma [-]dddd.dddd

e

coma flotante en la forma [-]d.dddd e[+/-]ddd

g

coma flotante segn el valor

E

como e pero en maysculas
20
20

G

como g pero en maysculas

c

un carcter

s

cadena de caracteres terminada en '\0'

%

imprime el carcter %

p

puntero

Los flags pueden ser los caracteres:



+

siempre se imprime el signo, tanto +como -

-

justifica a la izquierda el resultado, aadiendo espacios al final

blank

si es positivo, imprime un espacio en lugar de un signo +
# especifica la forma alternativa


En el campo width se especifica la anchura mnima de la forma:


n

se imprimen al menos n caracteres.

0n

se imprimen al menos n caracteres y si la salida es menor, se anteponen ceros

*

la lista de parmetros proporciona el valor

Hay dos modificadores de tamao, para los tipos enteros:


l

imprime un entero long

h

imprime un entero short

Otra funcin similar a printf pero para la entrada de datos es scanf. Esta toma los datos de la entrada
estndar del sistema operativo. En este caso, la lista de argumentos debe estar formada por punteros, que
indican dnde depositar los valores.


#include <stdio.h>

int scanf ( const char *format [, argumentos, ...] );


Hay dos funciones que trabajan con strings. La primera lee un string de la entrada estndar y la segunda
lo imprime en el dispositivo de salida estndar.


#include <stdio.h>
char *gets ( char *s );
int puts ( char *s );








21
21
Tambin hay funciones de lectura y escritura de caracteres individuales.


#include <stdio.h>
int getchar ( void );
int putchar ( int c );


Veamos, por ejemplo, un programa que copia la entrada estndar a la salida estndar del sistema
operativo, carcter a carcter.

#include <stdio.h>

main()
{
int c;


while ( (c = getchar()) != EOF )
putchar(c);
}



Funciones de asignacin de memoria.

Hemos visto que en C, las variables estticas pueden estar creadas al inicio de la ejecucin del programa,
o bien son variables locales automticas que se crean al iniciarse la ejecucin de una funcin. En muchas
aplicaciones en necesario la utilizacin de estructuras de datos dinmicas, o bien variables que deben
existir durante un tiempo no determinado a priori. Para asignar memoria de forma dinmica, C utiliza
varias funciones definidas en stdlib.h. Vamos a ver la utilizacin de estas funciones.

La funcin de asignacin de memoria ms utilizada es malloc. Esta toma como parmetro el tamao en
bytes y devuelve un puntero al bloque de memoria asignado. Si no hay memoria suficiente para asignar el
bloque devuelve NULL.




#include <stdlib.h>
void *malloc ( size_t size );



El tipo size_test definido normalmente como unsigned y se utiliza en todas las funciones que
necesitan un tamao en bytes. Otra funcin similar es:




#include <stdlib.h>
void *calloc ( size_t nitems, size_t size );



En este caso se le pasa como parmetro el nmero de elementos consecutivos que se desean. A diferencia
de malloc, calloc inicializa el contenido de la memoria asignada al valor 0. La funcin que se utiliza
para devolver memoria dinmica previamente asignada es free. Esta toma como parmetro un puntero
previamente obtenido con malloc o calloc




#include <stdlib.h>
void free ( void *block );
22
22


Hay que tener en cuenta, que la funcin free no cambia el valor del parmetro. El puntero al cual se
haba asignado memoria y ahora se ha liberado sigue almacenando la direccin de memoria, pero esta ya
no existe despus de llamar a free. Es misin del programador actualizar el valor del puntero, si es
necesario. Como ejemplo mostraremos una funcin que asigna memoria para un vector, lo inicializa y lo
libera.




void alloc_array ( void )
{
int *v, f;


if ((v = (int *) calloc ( 10, sizeof(int) )) == NULL)
printf("No hay memoria\n");
else {
for ( f = 0; f < 10; f++ )
v[f] = 0;


free(v);
v = NULL;
}
}



Debemos observar la conversin de tipo realizada al valor que devuelve calloc. Todas las funciones
devuelven punteros a void, por lo que se deben convertir al tipo de nuestra variable.

Funciones matemticas.

La utilizacin de las funciones matemticas definidas en el ANSI C requieren la inclusin del fichero
math.h. Todas ellas trabajan con el tipo double, por lo que si los argumentos o resultados son del tipo
floatel propio compilador se encarga de convertirlos al formato adecuado. En ANSI se est trabajando
para proporcionar funciones con argumentos de tipo floate introducir el tipo long float. Casi
todas la funciones tienen la forma double nombre ( double x );.



atan2

toma dos argumentos x e y y devuelve la arcotangente de y/x en radianes.

exp

devuelve el valor e elevado a x.

acos

retorna el arco coseno del parmetro x.

asin

retorna el arco seno del parmetro x.

atan

retorna el valor de la arco tangente del parmetro x.

cos

retorna el coseno del ngulo x.

cosh

retorna el coseno hiperblico del parmetro x.
23
23



sin

retorna el seno del ngulo x.

sinh

retorna el seno hiperblico del parmetro x.

tan

retorna la tangente del ngulo x.

tanh

retorna la tangente hiperblica del parmetro x.

log

retorna el logaritmo natural del parmetro x.

log10

retorna el logaritmo en base 10 del parmetro x.

pow

toma dos parmetros x e y y devuelve el valor xy

sqrt

retorna la raiz cuadrada del parmetro x.

Operaciones con ficheros.

La entrada y salida a ficheros es uno de los aspectos ms delicados de cualquier lenguaje de
programacin, pues suelen estar estrechamente integradas con el sistema operativo. Los servicios
ofrecidos por los sistemas operativos varan enormemente de un sistema a otro. Las libreras del C
proporcionan un gran conjunto de funciones, muchas de ellas descritas en el libro de Kernighan y Ritchie y
otras derivadas de los servicios que ofrece el Unix.

En C hay dos tipos de funciones de entrada/salida a ficheros. Las primeras son derivadas del SO Unix y
trabajan sin buffer. Las segundas son las que fueron estandarizadas por ANSI y utilizan un buffer
intermedio. Adems, hacen distinciones si trabajan con ficheros binarios o de texto. Veremos las
segundas, que son las ms utilizadas.

Las funciones del C no hacen distincin si trabajan con un terminal, cinta o ficheros situados en un disco.
Todas las operaciones se realizan a travs de streams. Un stream est formado por una serie ordenada de
bytes. Leer o escribir de un fichero implica leer o escribir del stream. Para realizar operaciones se debe
asociar un stream con un fichero, mediante la declaracin de un puntero a una estructura FILE. En esta
estructura se almacena toda la informacin para interactuar con el SO. Este puntero es inicializado
mediante la llamada a la funcin fopen(), para abrir un fichero.

Cuando se ejecuta todo programa desarrollado en C hay tres streams abiertos automticamente. Estos son
stdin, stdout y stderr. Normalmente estos streams trabajan con el terminal, aunque el sistema operativo
permite redireccionarlos a otros dispositivos. Las funciones printf() y scanf() que hemos visto,
utilizan stdout y stdin respectivamente.

Los datos de los ficheros pueden ser accedidos en uno de los dos formatos: texto o binario. Un text stream
consiste en una serie de lineas de texto acabadas con un carcter newline. En modo binario un fichero es
una coleccin de bytes sin ninguna estructura especial.

Hay que tener muy en cuenta que respecto a la velocidad de la memoria y de la CPU, los dispositivos de
entrada y salida con muy lentos. Puede haber cinco o seis rdenes de magnitud entre la velocidad de la
CPU y la de un disco duro. Adems una operacin de entrada y salida puede consumir una cantidad
importante de recursos del sistema. Por ello, conviene reducir en nmero de lecturas y escrituras a disco.
La mejor forma de realizar esto es mediante un buffer. Un buffer es una rea de memoria en la cual los
datos son almacenados temporalmente, antes de ser enviados a su destino. Por ejemplo, las operaciones
de escritura de caracteres a un fichero se realizan sobre el buffer del stream. Unicamente cuando se llena
el buffer se escriben todos los caracteres sobre el disco de una vez. Esto ahorra un buen nmero de
30
30


operaciones sobre el disco. Las funciones del C nos permiten modificar el tamao y comportamiento del
buffer de un stream.

Para utilizar las funciones de ficheros se debe incluir el fichero stdio.h. Este define los prototipos de
todas las funciones, la declaracin de la estructura FILE y algunas macros y definiciones. Una definicin
importante es EOF, que es el valor devuelto por muchas funciones cuando se llega al final de fichero.

Los pasos a seguir para operar con un fichero son: abrir, realizar el tratamiento y cerrar. Para abrir un
fichero se utiliza la funcin fopen. Esta toma dos strings como parmetros. El primero indica el nombre
del fichero que deseamos abrir y el segundo indica el modo de acceso.

#include <stdio.h>
FILE *fopen ( const char *filename, const char *mode );



Los modos de acceso para streams de texto son los siguientes:


"r"

Abre un fichero que ya existe para lectura. La lectura se realiza al inicio del fichero.

"w"

Se crea un nuevo fichero para escribir. Si el fichero existe se inicializa y sobreescribe.

"a"

Abre un fichero que ya existe para aadir informacin por el final. Slo se puede escribir a
partir del final.

"r+"

Abre un fichero que ya existe para actualizarlo (tanto para lectura como para escritura).

"w+"

Crea un nuevo fichero para actualizarlo (lectura y escritura) si existe, lo sobreescribe.

"a+"

Abre un fichero para aadir informacin al final. Si no existe lo crea.

Si se desea especificar un fichero binario, se aade una b al modo: "wb+". Si el fichero se abre
correctamente, la funcin devuelve un puntero a una estructura FILE. Si no, devuelve NULL.

La funcin fprintf se comporta exactamente a printf, excepto en que toma una argumento ms que
indica el stream por el que se debe realizar la salida. De hecho, la llamada printf("x") es equivalente
a fprintf ( stdout, "x").


FILE *f;
if ((f = fopen( "login.com", "r" )) == NULL )
printf("ERROR: no puedo abrir el fichero\n");

Para cerrar un fichero se utiliza la funcin fclose. Esta toma como argumento el puntero que nos
proporcion la funcin fopen.

include <stdio.h>

int fclose ( FILE *stream );



Devuelve 0 si el fichero se cierra correctamente, EOF si se produce algn error.

Una vez conocemos como abrir y cerrar ficheros, vamos a ver cmo leer y escribir en ellos. Hay
funciones para trabajar con caracteres, lineas y bloques.

Las funciones que trabajan con caracteres son fgetc y fputc. La primera lee un carcter de un stream
y la segunda lo estribe.



31
31

#include <stdio.h>
int fgetc ( FILE *stream );
int fputc ( int c, FILE *stream );



La primera lee el siguiente carcter del stream y los devuelve convertido a entero sin signo. Si no hay
carcter, devuelve EOF. La segunda, fputc, devuelve el propio carcter si no hay error. Si lo hay,
devuelve el carcter EOF. Hay una tercera funcin, feof que devuelve cero si no se ha llegado al final
del stream. Veamos un ejemplo de cmo se copia un fichero carcter a carcter.




while ( !feof(infile))
fputc ( fgetc ( infile ), outfile );



Suponemos que infiley outfileson los streams asociados al fichero de entrada y al de salida, que
estn abiertos. Luego debemos cerrarlos para vaciar los buffers y completar los cambios realizados.

Otras funciones nos permiten realizar operaciones con ficheros de texto trabajando lnea a lnea.




#include <stdio.h>
char *fgets ( char *s, int n, FILE *stream );
int fputs ( const char *s, FILE *stream );



La funcin fgets lee caracteres del stream hasta que encuentra un final de lnea o se lee el carcter n-1.
Mantiene el carcter \n en el string y aade el carcter \0. Devuelve la direccin del string o NULL si se
produce algn error. La funcin fputscopia el string al stream, no aade ni elimina caracteres \n y no
copia la marca de final de string \0.

Hay dos funciones que nos permiten trabajan en bloques. Podemos considerar un bloque como un array.
Debemos especificar el tamao de cada elemento y el nmero de elementos.




#include <stdio.h>
size_t fread ( void *p, size_t s, size_t n, FILE *f );
size_t fwrite ( void *p, size_t s, size_t n, FILE *f );

A las anteriores funciones se les pasa un puntero genrico p con la direccin del rea de datos que se
desea leer o escribir, el tamao de cada elemento s, y el nmero de elementos n, adems del stream.
Ambas devuelven el nmero de elementos ledos o escritos, que debe ser el mismo que le hemos
indicado, en el caso en que no se haya producido ningn error.

Hasta ahora hemos visto funciones de tratamiento de ficheros que nos van bien para realizar un
tratamiento secuencial de stos. Debemos tener en cuenta que cuando debemos realizar operaciones de
entrada y de salida alternadas, se deben vaciar los buffers de los streams para que las operaciones se
realicen correctamente sobre los ficheros. Esto se consigue con las funciones fflush y flushall. La
primera es aplicable al stream que deseemos y la segunda vaca los buffers de todos los streams abiertos.


#include <stdio.h>
int fflush ( FILE *stream );
int flushall ( void );





32
32
Si deseamos hacer un acceso aleatorio a un fichero disponemos de las funciones fseek y ftell. La
primera mueve el cursor, indicador de posicin, a un lugar determinado dentro del fichero. Este lugar
viene determinado por el parmetro whence. Este puede ser SEEK_SET, si es desde el inicio del
fichero, SEEK_CUR si es desde la posicin actual y SEEK_END si es desde el final del fichero. Devuelve
0 si la operacin se realiza correctamente.




#include <stdio.h>
int fseek ( FILE *stream, long offset, int whence );
long ftell ( FILE *stream );



La segunda funcin devuelve la posicin del cursor dentro del fichero. Este valor indica el nmero de
bytes desde el inicio del fichero, si el fichero es binario.




int escribir_planetas ( char *nombre )
{
PLANETA *p;
FILE *f;


if ( ( f = fopen ( "w+", nombre )) == NULL )
return ERROR;


if (N_PLA != fwrite ( p, sizeof(PLANETA), N_PLA, f ))
return ERROR;


if ( fclose(f) != 0 )
return ERROR;
else
return OK;
}
33
33



Bucles y tomas de decisin

1.-Hacer un pseudocodigo que imprima los numeros del 1 al 100.

PROGRAMA cont ador 1
ENTORNO:
c <- 0
ALGORI TMO:
Bor r ar _pant al l a( )
MI ENTRAS c < 101 HACER
ESCRI BI R c
c <- c + 1
FI NMI ENTRAS
FI NPROGRAMA

2.-Hacer un pseudocodigo que imprima los numeros del 100 al 0, en orden decreciente.

PROGRAMA cont ador 2
ENTORNO:
c <- 100
ALGORI TMO:
Bor r ar _pant al l a( )
MI ENTRAS c <= 0 HACER
ESCRI BI R c
c <- c - 1
FI NMI ENTRAS
FI NPROGRAMA

3.-Hacer un pseudocodigo que imprima los numeros pares entre 0 y 100.

PROGRAMA par es
ENTORNO:
c <- 2
ALGORI TMO:
Bor r ar _pant al l a( )
MI ENTRAS c < 101 HACER
ESCRI BI R c
c <- c + 2
FI NMI ENTRAS
FI NPROGRAMA

4.-Hacer un programa que imprima la suma de los 100 primeros numeros.

PROGRAMA suma
ENTORNO:
c <- 1
suma <- 0
ALGORI TMO:
Bor r ar _pant al l a( )
MI ENTRAS c <= 100 HACER
suma <- suma + c
c <- c + 1
FI NMI ENTRAS
ESCRI BI R " La suma de l os 100 pr i mer os nmer os es: "
ESCRI BI R suma
FI NPROGRAMA

5.-Hacer un pseudocdigo que imprima los numeros impares hasta el 100 y que imprima cuantos
impares hay.

PROGRAMA i mpar es
ENTORNO:
c <- 1
son <- 0
ALGORI TMO:
34
34
Bor r ar _pant al l a( )
MI ENTRAS c < 100
ESCRI BI R c
c <- c + 2
son <- son + 1
FI NMI ENTRAS
ESCRI BI R " El nmer o de i mpar es: "
ESCRI BI R son
FI NPROGRAMA

6.-Hacer un pseudocodigo que imprima todos los numeros naturales que hay desde- la unidad
hasta un numero que introducimos por teclado.

PROGRAMA nat ur al
ENTORNO:
i <- 0
n <- 0
ALGORI TMO:
Bor r ar _pant al l a( )
ESCRI BI R " I nt r oduce un nmer o: "
LEER n
MI ENTRAS i < n HACER
i <- i + 1
ESCRI BI R i
FI NMI ENTRAS
FI NPROGRAMA

7.-Introducir tantas frases como queramos y contarlas.

PROGRAMA f r ases
ENTORNO:
r es <- " S"
f r ase <- Espaci os( 30 )
c <- 0
ALGORI TMO:
Bor r ar _pant al l a( )
MI ENTRAS r es = " S" HACER
ESCRI BI R "Fr ase: "
LEER f r ase
c <- c + 1
ESCRI BI R "Deseas i nt r oduci r ms f r ases ( S/ N) : "
LEER r es
FI NMI ENTRAS
ESCRI BI R " El nmer o de f r ases i nt r oduci das son: "
ESCRI BI R c
FI NPROGRAMA

8.-Hacer un pseudocodigo que solo nos permita introducir S o N.

PROGRAMA sn
ENTORNO:
r es <- " "
ALGORI TMO:
Bor r ar _pant al l a( )
MI ENTRAS r es <> "S" Y r es <> " N" HACER
ESCRI BI R "I nt r oduce S o N"
LEER r es
r es <- Conver t i r _mayscul as( r es )
FI NMI ENTRAS
FI NPROGRAMA

9.-Introducir un numero por teclado. Que nos diga si es positivo o negativo.

PROGRAMA si gno
ENTORNO:
num<- 0
ALGORI TMO:
Bor r ar _pant al l a( )
ESCRI BI R " I nt r oduce un nmer o: "
35
35
LEER num
SI num>= 0 ENTONCES
ESCRI BI R "es posi t i vo"
SI NO
ESCRI BI R "es negat i vo"
FI NSI
FI NPROGRAMA

10.-Introducir un numero por teclado. Que nos diga si es par o impar.

PROGRAMA par i dad
ENTORNO:
num<- 0
ALGORI TMO:
Bor r ar _pant al l a( )
ESCRI BI R " I nt r oduce un nmer o: "
LEER num
SI num= i nt ( num/ 2 ) * 2 ENTONCES
ESCRI BI R "es par "
SI NO
ESCRI BI R "es i mpar "
FI NSI
FI NPROGRAMA

11.-Imprimir y contar los multiplos de 3 desde la unidad hasta un numero que introducimos por
teclado.

PROGRAMA mul t i pl o3
ENTORNO:
i <- 3
n <- 0
c <- 0
ALGORI TMO:
Bor r ar _pant al l a( )
ESCRI BI R " Nmer o: "
LEER n
MI ENTRAS i <= n HACER
SI i = i nt ( i / 3 ) * 3 ENTONCES
ESCRI BI R i
c <- c + 1
FI NSI
i <- i + 1
FI NMI ENTRAS
ESCRI BI R " El nmer o de ml t i pl os de 3 son: "
ESCRI BI R c
FI NPROGRAMA

12.-Hacer un pseudocodigo que imprima los numeros del 1 al 100. Que calcule la suma de todos
los numeros pares por un lado, y por otro, la de todos los
impares.

PROGRAMA par _i mpar
ENTORNO:
i <- 1
sumapar <- 0
sumai mp <- 0
ALGORI TMO:
Bor r ar _pant al l a( )
MI ENTRAS i < 101 HACER
SI i = i nt ( i / 2 ) * 2 ENTONCES
sumapar <- sumapar + i
SI NO
sumai mp <- sumai mp + i
FI NSI
i <- i + 1
FI NMI ENTRAS
ESCRI BI R " La suma de l os par es es: "
ESCRI BI R sumapar
ESCRI BI R " La suma de l os i mpar es es: "
36
36
ESCRI BI R sumai mp
FI NPROGRAMA

13.-Imprimir y contar los numeros que son multiplos de 2 o de 3 que hay entre 1 y 100.

PROGRAMA mul t i pl o_2_3
ENTORNO:
i <- 1
c <- 0
ALGORI TMO:
Bor r ar _pant al l a( )
MI ENTRAS i < 101 HACER
SI i = i nt ( i / 2 ) * 2 O i = i nt ( i / 3 ) * 3 ENTONCES
c <- c + 1
ESCRI BI R i
FI NSI
i <- i + 1
FI NMI ENTRAS
ESCRI BI R " El nmer o de ml t i pl os es de: "
ESCRI BI R c
FI NPROGRAMA

14.-Hacer un pseudocodigo que imprima el mayor y el menor de una serie de cinco numeros que
vamos introduciendo por teclado.

PROGRAMA mayor _menor
ENTORNO:
con <- 0
n <- 0
maxi mo <- 0
mi ni mo <- 99999
ALGORI TMO:
Bor r ar _pant al l a( )
MI ENTRAS con <= 5 HACER
ESCRI BI R "Nmer o: "
LEER n
SI n > maxi mo ENTONCES
maxi mo = n
FI NSI
SI n < mi ni mo ENTONCES
mi ni mo <- n
FI NSI
con <- con + 1
FI NMI ENTRAS
ESCRI BI R " El mayor de l os nmer os es: "
ESCRI BI R maxi mo
ESCRI BI R " El menor de l os nmer os es: "
ESCRI BI R mi ni mo
FI NPROGRAMA

15.-Introducir dos numeros por teclado. Imprimir los numeros naturales que hay entre ambos
numeros empezando por el m s pequeo, contar cuantos hay y cuantos de ellos son pares.
Calcular la suma de los impares.

PROGRAMA par _i mpar
ENTORNO:
num1 <- 0
num2 <- 0
aux <- 0
son <- 0
par es <- 0
sumai mpa <- 0
ALGORI TMO:
Bor r ar _pant al l a( )
ESCRI BI R " Nmer o: "
LEER num1
ESCRI BI R " Nmer o: "
LEER num2
SI num1 > num2 ENTONCES
37
37
aux <- num1
num1 <- num2
num2 <- aux
FI NSI
MI ENTRAS num1 >= num2 HACER
ESCRI BI R num1
son <- son + 1
SI num1 = i nt ( num1 / 2 ) * 2 ENTONCES
par es <- par es + 1
SI NO
sumai mpa <- sumai mpa + num1
FI NSI
num1 <- num1 + 1
FI NMI ENTRAS
ESCRI BI R " Nmer os vi sual i zados: "
ESCRI BI R son
ESCRI BI R " Par es hay: "
ESCRI BI R par es
ESCRI BI R " La suma de l os i mpar es es: "
ESCRI BI R sumai mpa
FI NPROGRAMA

Bucles anidados y subprogramas

16.-Imprimir diez veces la serie de numeros del 1 al 10.

PROGRAMA di ez
ENTORNO:
ser i e <- 0
ALGORI TMO:
Bor r ar _pant al l a( )
MI ENTRAS ser i e <= 10 HACER
numer o <- 1
MI ENTRAS numer o <= 10 HACER
ESCRI BI R numer o
numer o <- numer o + 1
FI NMI ENTRAS
ser i e <- ser i e + 1
FI NMI ENTRAS
FI NPROGRAMA

17.-Imprimir, contar y sumar los multiplos de 2 que hay entre una serie de numeros, tal que el
segundo sea mayor o igual que el primero.

PROGRAMA mul t i pl o2
ENTORNO:
r es <- " S"
ALGORI TMO:
Bor r ar _pant al l a( )
MI ENTRAS r es = " S" HACER
c <- 0
sum<- 0
num1 <- 0
num2 <- - 999
ESCRI BI R "Nmer o: "
LEER num1
ESCRI BI R "Nmer o mayor que el ant er i or "
MI ENTRAS num1 >= num2 HACER
LEER num2
FI NMI ENTRAS
num1 <- num1 + 1
MI ENTRAS num1 <= num2 - 1 HACER
SI num1 = i nt ( num1 / 2 ) * 2 ENTONCES
ESCRI BI R num1
c <- c + 1
sum<- sum+ num1
FI NSI
num1 <- num1 + 1
FI NMI ENTRAS
38
38
ESCRI BI R "Nmer o de ml t i pl os de 2: "
ESCRI BI R c
ESCRI BI R "Su suma es: "
ESCRI BI R sum
r es <- Espaci os( 1 )
MI ENTRAS r es <> " S" Y r es <> "N" HACER
ESCRI BI R " Ot r a ser i e de nmer os ( S/ N) : "
LEER r es
r es <- Conver t i r _mayscul as( r es )
FI NMI ENTRAS
FI NMI ENTRAS
FI NPROGRAMA

18.-Hacer un pseudocodigo que cuente las veces que aparece una determinada letra en una
frase que introduciremos por teclado.

PROGRAMA l et r a
ENTORNO:
f r ase <- Espaci os( 30 )
l et r a <- Espaci os( 1 )
l ongi t ud <- 0
a <- 0
r es <- " S"
ALGORI TMO:
MI ENTRAS r es = " S" HACER
Bor r ar _pant al l a( )
ESCRI BI R "I nt r oduce una f r ase: "
LEER f r ase
l ongi t ud <- Hal l ar _l ongi t ud( f r ase )
i <- 1
ESCRI BI R "Let r a a buscar : "
LEER l et r a
MI ENTRAS i <= l ongi t ud HACER
SI l et r a = Car act er ( f r ase, i , 1 ) ENTONCES
a <- a + 1
FI NSI
i <- i + 1
FI NMI ENTRAS
Bor r ar _pant al l a( )
ESCRI BI R "El nmer o de veces que apar ece l a l et r a "
ESCRI BI R l et r a
ESCRI BI R " en l a f r ase "
ESCRI BI R f r ase
ESCRI BI R " es de "
ESCRI BI R a
r es <- Espaci os( 1 )
MI ENTRAS r es <> " S" Y r es <> "N" HACER
ESCRI BI R " Desea i nt r oduci r m&aacut e; s f r ases ( S/ N) : "
LEER r es
r es <- Conver t i r _mayscul as( r es )
FI NMI ENTRAS
FI NMI ENTRAS
FI NPROGRAMA

19.-Hacer un pseudocodigo que simule el funcionamiento de un reloj digital y que permita
ponerlo en hora.

PROGRAMA r el oj
ENTORNO:
hor as <- 0
mi nut os <- 0
segundos <- 0
r es <- " S"
ALGORI TMO:
Bor r ar _pant al l a( )
ESCRI BI R " Hor as: "
LEER hor as
ESCRI BI R " Mi nut os: "
LEER mi nut os
39
39
ESCRI BI R " Segundos: "
LEER segundos
MI ENTRAS r es = " S" HACER
MI ENTRAS hor as < 24 HACER
MI ENTRAS mi nut os < 60 HACER
MI ENTRAS segundos < 60 HACER
ESCRI BI R hor as
ESCRI BI R mi nut os
ESCRI BI R segundos
segundos <- segundos + 1
FI NMI ENTRAS
mi nut os <- mi nut os + 1
segundos <- 0
FI NMI ENTRAS
hor as <- hor as + 1
mi nut os <- 0
FI NMI ENTRAS
hor as <- 0
FI NMI ENTRAS
FI NPROGRAMA

20.-Calcular el factorial de un numero, mediante subprogramas.

PROGRAMA f act or i al
ENTORNO:
r es <- " S"
ALGORI TMO:
MI ENTRAS r es = " S" HACER
Bor r ar _pant al l a( )
f act or i al <- 1
ESCRI BI R "Nmer o: "
LEER numer o
SI numer o < 0 ENTONCES
ESCRI BI R " No t i ene f act or i al "
SI NO
HACER Cal cul os
FI NSI
HACER Mas
FI NMI ENTRAS
FI NPROGRAMA
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SUBPROGRAMA Cal cul os
MI ENTRAS numer o > 1 HACER
f act or i al <- f act or i al * numer o
numer o <- numer o - 1
FI NMI ENTRAS
HACER I mpr i mi r
FI NSUBPROGRAMA
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SUBPROGRAMA Mas
r es <- " "
MI ENTRAS r es <> "S" Y r es <> " N" HACER
ESCRI BI R "Desea cal cul ar m&aacut e; s f act or i al es ( S/ N) : "
LEER r es
r es <- Conver t i r _mayscul as( r es )
FI NMI ENTRAS
FI NSUBPROGRAMA
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SUBPROGRAMA I mpr i mi r
ESCRI BI R " Su f act or i al es: "
ESCRI BI R f act or i al
FI NSUBPROGRAMA

21.-Hacer un programa que calcule independientemente la suma de los pares y los impares de
los numeros entre 1 y 1000, utilizando un switch.

PROGRAMA suma
ENTORNO:
par <- 0
i mpar <- 0
40
40
sw <- 0
i <- 1
ALGORI TMO:
Bor r ar _pant al l a( )
MI ENTRAS i <= 1000 HACER
SI sw = 0 ENTONCES
i mpar <- i mpar + i
sw <- 1
SI NO
par <- par + i
sw <- 0
FI NSI
i <- i + 1
FI NMI ENTRAS
ESCRI BI R " La suma de l os par es es: "
ESCRI BI R par
ESCRI BI R " La suma de l os i mpar es es: "
ESCRI BI R i mpar
FI NPROGRAMA

Presentacion en pantalla y cabeceras

22.-Introducir una frase por teclado. Imprimirla cinco veces en filas consecutivas, pero cada
impresion ir desplazada cuatro columnas hacia la derecha.

PROGRAMA f r ase
ENTORNO:
f r ase <- Espaci os( 30 )
ALGORI TMO:
Bor r ar _pant al l a( )
EN 5, 15 ESCRI BI R " Fr ase: "
EN 5, 22 LEER f r ase
f i <- 8
co <- 15
veces <- 0
MI ENTRAS veces <= 5 HACER
EN f i , co ESCRI BI R f r ase
veces <- veces + 1
co <- co + 4
f i <- f i + 1
FI NMI ENTRAS
FI NPROGRAMA

23.-Hacer un pseudocodigo que imprima los nmeros del 0 al 100, controlando las filas y las
columnas.

PROGRAMA numer os
ENTORNO:
c <- 0
ALGORI TMO:
Bor r ar _pant al l a( )
EN 5, 20 ESCRI BI R " Los nmer os del 0 al 100 son: "
f i <- 7
col <- 5
MI ENTRAS c < 101 HACER
EN f i , col ESCRI BI R c
c <- c + 1
col <- col + 4
SI col > 75 ENTONCES
f i <- f i + 2
col <- 5
FI NSI
FI NMI ENTRAS
FI NPROGRAMA

24.-Comprobar si un numero mayor o igual que la unidad es primo.

PROGRAMA pr i mo
ENTORNO:
41
41
r es <- " S"
ALGORI TMO:
MI ENTRAS r es = " S" HACER
Bor r ar _pant al l a( )
numer o <- 0
sw <- 0
MI ENTRAS numer o < 1 HACER
EN 8, 10 ESCRI BI R " Nmer o: "
EN 8, 18 LEER numer o
FI NMI ENTRAS
i <- numer o - 1
MI ENTRAS i > 1 Y sw <> 1 HACER
SI numer o = I nt ( numer o / i ) * i ENTONCES
sw = 1
SI NO
i <- i - 1
FI NSI
FI NMI ENTRAS
SI sw = 1 ENTONCES
EN 10, 10 ESCRI BI R "no es pr i mo"
SI NO
EN 10, 10 ESCRI BI R "s es pr i mo"
FI NSI
HACER Mas
FI NMI ENTRAS
FI NPROGRAMA
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SUBPROGRAMA Mas
r es <- " "
MI ENTRAS r es <> "S" Y r es <> " N" HACER
ESCRI BI R "Desea i nt r oduci r ms nmer os ( S/ N) : "
LEER r es
r es <- Conver t i r _mayuscul as( r es )
FI NMI ENTRAS
FI NSUBPROGRAMA

25.-Introducir un numero menor de 5000 y pasarlo a numero romano.

PROGRAMA r omano
ENTORNO:
r es <- " S"
ALGORI TMO:
MI ENTRAS r es = " S" HACER
Bor r ar _pant al l a( )
num<- 0
MI ENTRAS num< 1 O num> 5000 HACER
EN 8, 10 ESCRI BI R " Nmer o: "
EN 8, 18 ESCRI BI R num
FI NMI ENTRAS
col <- 15
MI ENTRAS num>= 1000 HACER
EN 15, col ESCRI BI R " M"
num<- num- 1000
col <- col + 1
FI NMI ENTRAS
SI num>= 900 ENTONCES
EN 15, col ESCRI BI R " CM"
num<- num- 900
col <- col + 2
FI NSI
SI num>= 500 ENTONCES
EN 15, col ESCRI BI R " D"
num<- num- 500
col <- col + 1
FI NSI
MI ENTRAS num>= 100 HACER
EN 15, col ESCRI BI R " C"
num<- num- 100
col <- col + 1
FI NMI ENTRAS
42
42
SI num>= 90 ENTONCES
EN 15, col ESCRI BI R " XC"
num<- num- 90
col <- col + 2
FI NSI
SI num>= 50 ENTONCES
EN 15, col ESCRI BI R " L"
num<- num- 50
col <- col + 1
FI NSI
SI num>= 40 ENTONCES
EN 15, col ESCRI BI R " XL"
num<- num- 40
col <- col + 2
FI NSI
MI ENTRAS num>= 10 HACER
EN 15, col ESCRI BI R " X"
num<- num- 10
col <- col + 1
FI NMI ENTRAS
SI num= 9 ENTONCES
EN 15, col ESCRI BI R " I X"
num<- num- 9
col <- col + 2
FI NSI
SI num>= 5 ENTONCES
EN 15, col ESCRI BI R " V"
num<- num- 5
col <- col + 1
FI NSI
SI num>= 4 ENTONCES
EN 15, col ESCRI BI R " I V"
num<- num- 4
col <- col + 2
FI NSI
MI ENTRAS num> 0 HACER
EN 15, col ESCRI BI R " I "
num<- num- 1
col <- col + 1
FI NMI ENTRAS
HACER Mas
FI NMI ENTRAS
FI NPROGRAMA
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SUBPROGRAMA Mas
r es <- " "
MI ENTRAS r es <> "S" Y r es <> " N" HACER
ESCRI BI R "Desea i nt r oduci r ms nmer os ( S/ N) : "
LEER r es
r es <- Conver t i r _mayuscul as( r es )
FI NMI ENTRAS
FI NSUBPROGRAMA

26.-Introducir una frase por teclado. Imprimirla en el centro de la pantalla.

PROGRAMA cent r o
ENTORNO:
r es <- " S"
f r ase <- Espaci os( 40 )
ALGORI TMO:
MI ENTRAS r es = " S" HACER
Bor r ar _pant al l a( )
EN 5, 15 ESCRI BI R "Fr ase: "
EN 5, 22 LEER f r ase
EN 12, 40 - I nt ( Longi t ud( f r ase ) / 2 ) ESCRI BI R f r ase
HACER Mas
FI NMI ENTRAS
FI NPROGRAMA

27.-Realizar la tabla de multiplicar de un numero entre 0 y 10.
43
43

PROGRAMA t abl a
ENTORNO:
num<- - 1
ALGORI TMO:
HACER Numer o
Bor r ar _pant al l a( )
EN 5, 10 ESCRI BI R " Tabl a de mul t i pl i car del nmer o: "
EN 5, 40 LEER num
i <- 0
f i <- 8
MI ENTRAS i <= 10 HACER
EN f i , 15 ESCRI BI R num
EN f i , 19 ESCRI BI R " * "
EN f i , 23 ESCRI BI R i
EN f i , 25 ESCRI BI R " = "
EN f i , 29 ESCRI BI R num* i
f i <- f i + 1
i <- i + 1
FI NMI ENTRAS
FI NPROGRAMA
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SUBPROGRAMA Numer o
MI ENTRAS num< 0 HACER
Bor r ar _pant al l a( )
EN 10, 25 ESCRI BI R " Nmer o: "
EN 10, 33 LEER num
FI NMI ENTRAS
FI NSUBPROGRAMA

Numeros aleatorios y menus

28.-Simular el lanzamiento de una moneda al aire e imprimir si ha salido cara o cruz.

PROGRAMA moneda
ENTORNO:
r es <- " S"
ALGORI TMO:
MI ENTRAS r es = " S" HACER
Bor r ar _pant al l a( )
SI Rnd( ) <= 0. 5 ENTONCES
EN 10, 35 ESCRI BI R "Car a"
SI NO
EN 10, 35 ESCRI BI R "Cr uz"
FI NSI
HACER Mas
FI NMI ENTRAS
FI NPROGRAMA
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SUBPROGRAMA Mas
r es <- Espaci os( 1 )
MI ENTRAS r es <> "S" Y r es <> " N" HACER
EN 20, 30 ESCRI BI R " M s l anzami ent os ( S/ N) : "
EN 20, 57 LEER r es
r es <- Conver t i r _mayuscul as( r es )
FI NMI ENTRAS
FI NSUBPROGRAMA

29.-Simular cien tiradas de dos dados y contar las veces que entre los dos suman 10.

PROGRAMA dado
ENTORNO:
c <- 0
i <- 0
ALGORI TMO:
Bor r ar _pant al l a( )
MI ENTRAS i < 101 HACER
SI I nt ( Rnd( ) * 6 ) + I nt ( Rnd( ) * 6 ) + 2 = 10 ENTONCES
c <- c + 1
44
44
FI NSI
i <- i + 1
FI NMI ENTRAS
EN 10, 20 ESCRI BI R "Las veces que suman 10 son: "
EN 10, 48 ESCRI BI R c
FI NPROGRAMA

30.-Simular una carrera de dos caballos si cada uno tiene igual probabilidad de ganar.

PROGRAMA cabal l os
ENTORNO:
di buj o <- "****"
col 1 <- 4
col 2 <- 4
ALGORI TMO:
Bor r ar _pant al l a( )
EN 10, col 1 ESCRI BI R di buj o
EN 10, col 2 ESCRI BI R di buj o
MI ENTRAS col 1 <= 75 Y col 2 <= 75 HACER
SI Rnd( ) <= 0. 5 ENTONCES
EN 10, col 1 ESCRI BI R Espaci os( 4 )
col 1 <- col 1 + 4
EN 10, col 1 ESCRI BI R di buj o
SI NO
EN 12, col 2 ESCRI BI R Espaci os( 4 )
col 2 <- col 2 + 4
EN 12, col 2 ESCRI BI R di buj o
FI NSI
FI NMI ENTRAS
EN 16, 20 ESCRI BI R "El ganador es el cabal l o nmer o: "
SI col 1 >= 75 ENTONCES
EN 16, 54 ESCRI BI R " 1"
SI NO
EN 16, 54 ESCRI BI R " 2"
FI NSI
FI NPROGRAMA

31.-Introducir dos nymeros por teclado y mediante un menu, calcule su suma, su resta, su
multiplicacion o su division.

PROGRAMA menu1
ENTORNO:
op <- 0
ALGORI TMO:
EN 10, 20 ESCRI BI R "Nmer o: "
EN 10, 29 LEER n1
EN 12, 20 ESCRI BI R "Nmer o: "
EN 12, 29 LEER n2
MI ENTRAS op <> 5 HACER
op <- 0
Bor r ar _pant al l a( )
EN 6, 20 ESCRI BI R "Men de opci ones"
EN 10, 25 ESCRI BI R " 1. - Suma"
EN 12, 25 ESCRI BI R " 2. - Rest a"
EN 14, 25 ESCRI BI R " 3. - Mul t i pl i caci n"
EN 16, 25 ESCRI BI R " 4. - Di vi si n"
EN 18, 25 ESCRI BI R " 5. - Sal i r del pr ogr ama"
EN 22, 25 ESCRI BI R " El i j a opci n: "
EN 22, 39 LEER op
Bor r ar _pant al l a( )
HACER CASO
CASO op = 1
EN 10, 20 ESCRI BI R " Su suma es: "
EN 10, 33 ESCRI BI R n1 + n2
Pausa( )
CASO op = 2
EN 10, 20 ESCRI BI R " Su r est a es: "
EN 10, 33 ESCRI BI R n1 - n2
Pausa( )
CASO op = 3
45
45
EN 10, 20 ESCRI BI R " Su mul t i pl i caci n es: "
EN 10, 33 ESCRI BI R n1 * n2
Pausa( )
CASO op = 4
EN 10, 20 ESCRI BI R " Su di vi si n es: "
EN 10, 33 ESCRI BI R n1 / n2
Pausa( )
FI NCASO
FI NMI ENTRAS
FI NPROGRAMA

32.-Hacer un programa que nos permita introducir un numero por teclado y sobre el se realicen
las siguientes operaciones: comprobar si es primo, hallar su factorial o imprimir su tabla de
multiplicar.

PROGRAMA menu2
ENTORNO:
op <- 0
ALGORI TMO:
EN 10, 20 ESCRI BI R "Nmer o: "
EN 10, 29 LEER n
MI ENTRAS op <> 4 HACER
op <- 0
Bor r ar _pant al l a( )
EN 6, 30 ESCRI BI R "Men de opci ones"
EN 10, 25 ESCRI BI R " 1. - Compr obar si es pr i mo"
EN 12, 25 ESCRI BI R " 2. - Hal l ar su f act or i al "
EN 14, 25 ESCRI BI R " 3. - Tabl a de mul t i pl i car "
EN 16, 25 ESCRI BI R " 4. - Sal i r del pr ogr ama"
EN 22, 25 ESCRI BI R " El i j a opci n: "
EN 22, 39 LEER op
HACER CASO
CASO op = 1
HACER Pr i mo
CASO op = 2
HACER Fact or i al
CASO op = 3
HACER Tabl a
FI NCASO
FI NMI ENTRAS
FI NPROGRAMA
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SUBPROGRAMA Pr i mo
sw <- 0
i <- n - 1
MI ENTRAS i > 1 Y sw <> 1 HACER
SI n = I nt ( n / i ) * i ENTONCES
sw <- 1
SI NO
i <- i - 1
FI NSI
FI NMI ENTRAS
Bor r ar _pant al l a( )
SI sw = 1 ENTONCES
EN 10, 10 ESCRI BI R " no es pr i mo"
SI NO
EN 10, 10 ESCRI BI R " s es pr i mo"
FI NSI
Pausa( )
FI NSUBPROGRAMA
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SUBPROGRAMA Fact or i al
f ac <- 1
Bor r ar _pant al l a( )
SI n < 0 ENTONCES
EN 10, 10 ESCRI BI R " No t i ene f act or i al "
SI NO
MI ENTRAS n > 1 HACER
f ac <- f ac * n
n <- n - 1
46
46
FI NMI ENTRAS
EN 10, 10 ESCRI BI R " Su f act or i al es: "
EN 10, 27 ESCRI BI R f ac
FI NSI
Pausa( )
FI NSUBPROGRAMA
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SUBPROGRAMA Tabl a
i <- 0
f i <- 10
Bor r ar _pant al l a( )
MI ENTRAS i <= 10 HACER
EN 8, 10 ESCRI BI R "Tabl a de mul t i pl i car "
EN f i , 10 ESCRI BI R n
EN f i , 15 ESCRI BI R " *"
EN f i , 20 ESCRI BI R i
EN f i , 25 ESCRI BI R " ="
EN f i , 30 ESCRI BI R n * i
i <- i + 1
FI NMI ENTRAS
Pausa( )
FI NSUBPROGRAMA

Arrays unidimensionales

33.-Crear un array unidimensional de 20 elementos con nombres de personas. Visualizar los
elementos de la lista debiendo ir cada uno en una fila distinta.

PROGRAMA nombr es
ENTORNO:
DI MENSI ONA dat os[ 20 ]
i <- 1
ALGORI TMO:
Bor r ar _pant al l a( )
f i <- 10
MI ENTRAS i < 21 HACER
EN f i , 10 ESCRI BI R " Nombr e: "
EN f i , 18 LEER dat os[ i ]
i <- i + 1
FI NMI ENTRAS
Bor r ar _pant al l a( )
i <- 1
f i <- 3
EN 1, 20 ESCRI BI R " El ement os de l a l i st a"
MI ENTRAS i < 21 HACER
EN f i , 28 ESCRI BI R dat os[ i ]
f i <- f i + 1
i <- i + 1
FI NMI ENTRAS
FI NPROGRAMA

34.-Hacer un programa que lea las calificaciones de un alumno en 10 asignaturas, las almacene
en un vector y calcule e imprima su media.

PROGRAMA not amedi a
ENTORNO:
DI MENSI ONA not as[ 10 ]
suma <- 0
medi a <- 0
ALGORI TMO:
Bor r ar _pant al l a( )
f i <- 7
PARA i DESDE 1 HASTA 10 HACER
EN f i , 15 ESCRI BI R " Not a "
EN f i , 20 ESCRI BI R i
EN f i , 21 ESCRI BI R " : "
EN f i , 23 LEER not as[ i ]
f i <- f i + 1
FI NPARA
47
47
PARA i DESDE 1 HASTA 10 HACER
suma <- suma + not as[ i ]
FI NPARA
medi a <- suma / 10
EN 20, 20 ESCRI BI R "Not a medi a: "
EN 20, 32 ESCRI BI R medi a
FI NPROGRAMA

35.-Usando el segundo ejemplo, hacer un programa que busque una nota en el vector.

PROGRAMA buscar
ENTORNO:
i <- 0
num<- 0
ALGORI TMO:
Bor r ar _pant al l a( )
ESCRI BI R " Not a a buscar : "
LEER num
I TERAR
i <- i + 1
SI not as[ i ] = numO i = 10 ENTONCES
SALI R
FI NSI
FI NI TERAR
SI not as[ i ] = numENTONCES
ESCRI BI R "Encont r ado en posi ci &oacut e; n: "
ESCRI BI R i
SI NO
ESCRI BI R "No exi st e esa not a"
FI NSI
FI NPROGRAMA

Arrays bidimensionales

36.-Generar una matriz de 4 filas y 5 columnas con numeros aleatorios entre 1 y 100, e
imprimirla.

PROGRAMA mat r i z
ENTORNO:
DI MENSI ONAR A[ 4, 5 ]
i <- 1
f i <- 10
co <- 15
ALGORI TMO:
Bor r ar _pant al l a( )
EN 6, 25 ESCRI BI R " El ement os de l a mat r i z"
MI ENTRAS i <= 4 HACER
j <- 1
MI ENTRAS j <= 5 HACER
A[ i , j ] <- I nt ( Rnd( ) * 100 ) + 1
EN f i , co ESCRI BI R A[ i , j ]
co <- co + 5
j <- j + 1
FI NMI ENTRAS
co <- 15
f i <- f i + 2
i <- i + 1
FI NMI ENTRAS
FI NPROGRAMA

37.-Generar una matriz de 4 filas y 5 columnas con nmeros aleatorios entre 1y 100, y hacer su
matriz transpuesta.

PROGRAMA t r anspuest a
ENTORNO:
DI MENSI ONAR A[ 4, 5 ]
DI MENSI ONAR B[ 5, 4 ]
f i <- 8
co <- 10
48
48
f i t <- 8
cot <- 40
i <- 1
ALGORI TMO:
Bor r ar _pant al l a( )
EN 6, 15 ESCRI BI R " Mat r i z uno"
EN 6, 45 ESCRI BI R " Tr anspuest a"
MI ENTRAS i <= 4 HACER
j <- 1
MI ENTRAS j <= 5 HACER
A[ i , j ] <- I nt ( Rnd( ) * 100 ) + 1
B[ j , i ] <- A[ i , j ]
EN f i , co ESCRI BI R A[ i , j ]
EN f i t , cot ESCRI BI R B[ j , i ]
co <- co + 4
f i t <- f i t + 2
j <- j + 1
FI NMI ENTRAS
f i <- f i + 2
co <- 10
f i t <- 8
cot <- cot + 4
i <- i + 1
FI NMI ENTRAS
FI NPROGRAMA

38.-Cargar en una matriz las notas de los alumnos de un colegio en funcion del numero de
cursos (filas) y del nmero de alumnos por curso (columnas).

PROGRAMA not as
ENTORNO:
i <- 1
j <- 1
ALGORI TMO:
Bor r ar _pant al l a( )
EN 10, 20 ESCRI BI R "Nmer o de cur sos: "
EN 10, 39 LEER M
EN 12, 20 ESCRI BI R "Nmer o de al umnos: "
EN 12, 40 LEER N
DI MENSI ONAR A[ M, N ]
Bor r ar _pant al l a( )
EN 2, 25 ESCRI BI R " I nt r oducci n de l as not as"
MI ENTRAS i <= M HACER
EN 10, 25 ESCRI BI R " Cur so: "
EN 10, 32 ESCRI BI R i
MI ENTRAS j <= N HACER
EN 14, 25 ESCRI BI R "Al umno: "
EN 14, 33 ESCRI BI R j
EN 16, 25 ESCRI BI R "Not a: "
EN 16, 32 LEER A[ i , j ]
j <- j + 1
FI NMI ENTRAS
i <- i + 1
FI NMI ENTRAS
FI NPROGRAMA

39.-Ordenar una matriz de M filas y N columnas por la primera columna utilizando el mtodo
SHELL (por insercion).

PROGRAMA or denar
ENTORNO:
i <- 1
j <- 1
f i <- 10
co <- 15
M <- 0
N <- 0
ALGORI TMO:
Bor r ar _pant al l a( )
49
49
EN 10, 20 ESCRI BI R "Fi l as: "
EN 10, 27 LEER M
EN 12, 20 ESCRI BI R "Col umnas: "
EN 12, 30 LEER N
DI MENSI ONAR A[ M, N ]
Bor r ar _pant al l a( )
MI ENTRAS i <= M HACER
MI ENTRAS j <= N HACER
A[ i , j ] = I nt ( Rnd( ) * 100 ) + 1
EN f i , co ESCRI BI R A[ i , j ]
co <- co + 5
j <- j + 1
FI NMI ENTRAS
co <- 15
f i <- f i + 2
i <- i + 1
FI NMI ENTRAS
sal t o <- I nt ( M / 2 )
MI ENTRAS sal t o >= 1 HACER
sw <- 1
MI ENTRAS sw <> 0 HACER
sw <- 0
i <- 1
MI ENTRAS i <= M - sal t o HACER
SI A[ i , 1 ] > A[ i + sal t o, 1 ] ENTONCES
HACER Cambi os
FI NSI
i <- i + 1
FI NMI ENTRAS
FI NMI ENTRAS
sal t o <- I nt ( sal t o / 2 )
FI NMI ENTRAS
FI NPROGRAMA
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SUBPROGRAMA Cambi os
j <- 1
MI ENTRAS j <= N HACER
aux <- A[ i + sal t o, j ]
A[ i + sal t o, j ] <- A[ i , j ]
A[ i , j ] <- aux
j <- j + 1
FI NMI ENTRAS
sw <- 1
FI NSUBPROGRAMA

Arrays multidimensionales

40.-Crear una tabla de 3 paginas, 4 filas y 5 columnas donde el primer elemento valga 1, el
segundo 2, el tercero 3 y as sucesivamente, e imprimirla.

PROGRAMA t abl a
ENTORNO:
DI MENSI ONAR A[ 3, 4, 5 ]
i <- 1
j <- 1
k <- 1
b <- 0
f i <- 8
co <- 12
ALGORI TMO:
MI ENTRAS i <= 3 HACER
Bor r ar _pant al l a( )
EN f i , co ESCRI BI R " El ement os de l a p gi na: "
EN f i , co + 24 ESCRI BI R i
f i <- f i + 2
MI ENTRAS j <= 4 HACER
MI ENTRAS k <= 5 HACER
b <- b + 1
A[ i , j , k ] <- b
EN f i , co ESCRI BI R A[ i , j , k ]
50
50
co <- co + 4
k <- k + 1
FI NMI ENTRAS
f i <- f i + 2
co <- 12
j <- j + 1
FI NMI ENTRAS
EN f i + 2, 20 ESCRI BI R " Pul se I NTRO par a cont i nuar . . . "
Pausa( )
i <- i + 1
FI NMI ENTRAS
FI NPROGRAMA

41.-Se dispone de una tabla de 5 p ginas, 10 filas y 20 columnas, que se refieren al centro, al
curso y al numero de alumnos de un colegio respectivamente. Imprimir la nota media por curso
y la nota media maxima y su centro de pertenencia.

PROGRAMA not as
ENTORNO:
max <- - 1
sum<- 0
cent r o <- 0
i <- 1
j <- 1
k <- 1
f i <- 10
ALGORI TMO:
Bor r ar _pant al l a( )
EN 8, 18 ESCRI BI R " Cent r o"
EN 8, 38 ESCRI BI R " Not a medi a"
MI ENTRAS i <= 5 HACER
MI ENTRAS j <= 10 HACER
MI ENTRAS k <= 20 HACER
sum<- sum+ A[ i , j , k ]
k <- k + 1
FI NMI ENTRAS
j <- j + 1
FI NMI ENTRAS
EN f i , 20 ESCRI BI R i
EN f i , 40 ESCRI BI R sum/ 20
f i <- f i + 2
SI sum/ 20 > max ENTONCES
max <- sum/ 20
cent r o <- i
FI NSI
i <- i + 1
FI NMI ENTRAS
EN f i + 2, 20 ESCRI BI R "Not a medi a mxi ma: "
EN f i + 2, 39 ESCRI BI R max
EN f i + 4, 20 ESCRI BI R " per t enece al cent r o: "
EN f i + 4, 41 ESCRI BI R cent r o
FI NPROGRAMA

42.-Una empresa guarda en una tabla de 3x12x4 las ventas realizadas por sus tres
representantes a lo largo de doce meses de sus cuatro productos, VENTAS[ representante, mes,
producto ]. Queremos proyectar el array tridimensional sobre uno de dos dimensiones que
represente el total de ventas, TOTAL[ mes, producto ], para lo cual sumamos las ventas de cada
producto de cada mes de todos los representantes. Imprimir ambos arrays.

PROGRAMA vent as
ENTORNO:
** Las var i abl es est n def i ni das en cada subpr ogr ama
ALGORI TMO:
HACER Vol car
HACER I mp_Tr es
HACER I mp_Dos
FI NPROGRAMA
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SUBPROGRAMA Vol car
51
51
DI MENSI ONAR TOTAL[ 12, 4 ]
j <- 1
MI ENTRAS j <= 12 HACER
k <- 1
MI ENTRAS k <= 4 HACER
i <- 1
suma <- 0
MI ENTRAS i <= 3 HACER
suma <- suma + VENTAS[ i , j , k ]
i <- i + 1
FI NMI ENTRAS
TOTAL[ j , k ] <- suma
k <- k + 1
FI NMI ENTRAS
j <- j + 1
FI NMI ENTRAS
FI NSUBPROGRAMA
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SUBPROGRAMA I mp_Tr es
i <- 1
MI ENTRAS i <= 3 HACER
Bor r ar _pant al l a( )
f i <- 8
co <- 12
EN f i , co ESCRI BI R " Vent as del r epr esent ant e: "
EN f i , co + 26 ESCRI BI R i
f i <- f i + 2
j <- 1
MI ENTRAS j <= 12 HACER
k <- 1
MI ENTRAS k <= 4 HACER
EN f i , co ESCRI BI R VENTAS[ i , j , k ]
co <- co + 4
k <- k + 1
FI NMI ENTRAS
f i <- f i + 2
co <- 12
j <- j + 1
FI NMI ENTRAS
Pausa( )
i <- i + 1
FI NMI ENTRAS
FI NSUBPROGRAMA
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SUBPROGRAMA I mp_Dos
Bor r ar _pant al l a( )
j <- 1
EN 8, 20 ESCRI BI R " Vent as t ot al es"
f i <- 10
co <- 16
MI ENTRAS j <= 12 HACER
k <- 1
MI ENTRAS k <= 4 HACER
EN f i , co ESCRI BI R TOTAL[ j , k ]
co <- co + 4
k <- k + 1
FI NMI ENTRAS
f i <- f i + 2
co <- 12
j <- j + 1
FI NMI ENTRAS
FI NSUBPROGRAMA

Ficheros

43.-Hacer un programa que nos permita dar altas en el fichero secuencial DATOS.DAT, cuyos
campos son: DNI, NOMBRE, APELLIDOS, DIRECCION y PROVINCIA.

[code] PROGRAMA altas
52
52
ENTORNO:
res <- "S"
ALGORITMO:
MIENTRAS res ="S" HACER
ABRIR "DATOS.DAT"
sw <- 0
num <- 0
Borrar_pantalla( )
EN 5,10 ESCRIBIR "D.N.I.: "
EN 5,18 LEER num
MIENTRAS NO Eof( ) Y sw =0 HACER
SI dni =num ENTONCES
EN 10,10 ESCRIBIR "Alta duplicada"
EN 15,10 ESCRIBIR "Pulse INTRO para continuar"
Pausa( )
sw <- 1
SINO
Siguiente_registro( )
FINSI
FINMIENTRAS
SI sw =0 ENTONCES
EN 7,5 ESCRIBIR "Nombre: "
EN 9,5 ESCRIBIR "Apellidos: "
EN 11,5 ESCRIBIR "Direcci&oacute;n: "
EN 13,5 ESCRIBIR "Provincia: "
EN 7,16 LEER nombre
EN 9,16 LEER apellidos
EN 11,16 LEER direccion
EN 13,16 LEER provincia
dni <- num
Final_fichero( )
Escribir_registro( )
FINSI
CERRAR "DATOS.DAT"
res <- Espacios( 1 )
HACER Mas
FINMIENTRAS
FINPROGRAMA
------------------------------
SUBPROGRAMA Mas
MIENTRAS res <>"S" Y res <>"N" HACER
ESCRIBIR "Desea m s altas (S/N): "
LEER res
res <- Convertir_mayusculas( res )

















53
53
Bibliografa y referencias.

[1] El lenguaje de programacin C.
Brian W. Kernighan, Dennis M. Ritchie.
Prentice-Hall Hispanoamericana, 1985.
ISBN 968-880-024-4

[2] American National Standard for Information Systems -- Programming
Language C.
American National Standards Institute.
1430 Broadway
New York, NY 10018

[3] El lenguaje de programacin C, segunda edicin.
Brian W. Kernighan, Dennis M. Ritchie.
Prentice-Hall Hispanoamericana, 1991.
ISBN 968-880-205-0

[4] C. A software engineering approach.
Peter A Darnell, Philip E. Margolis.
Springer-Verlag, 1991
ISBN 3-540-97389-3

Potrebbero piacerti anche