Está en la página 1de 33

Programacin I

RESUMEN PROGRAMACIN I
TIPOS DE DATOS .......................................................................................... 2
DATOS SIMPLES ................................................................................................................................................................ 2
DATOS COMPLEJOS (ESTRUCTURA DE DATOS) ................................................................................................................. 2
OPERADORES .................................................................................................................................................................... 2

ESTRUCTURAS DE CONTROL ..................................................................... 3


ESTRUCTURAS DE DECISIN O CONDICIONALES .............................................................................................................. 3
ESTRUCTURAS DE CICLOS ................................................................................................................................................. 3

VECTORES .................................................................................................... 4
OPERACIONES TPICAS CON VECTORES ............................................................................................................................ 5

MANEJO DE CADENAS .............................................................................. 12


FUNCIONES ESTNDAR PARA MANEJAR CADENAS ........................................................................................................ 13
PUNTEROS ...................................................................................................................................................................... 16

FUNCIONES ................................................................................................. 17
A)
B)
C)
D)
E)
F)

PROTOTIPADO DE FUNCIONES .............................................................................................................................. 17


DECLARACIN DE FUNCIONES ............................................................................................................................... 17
INVOCACIN DE FUNCIONES ................................................................................................................................. 17
PASO DE PARMETROS .......................................................................................................................................... 18
FUNCIONES VOID ................................................................................................................................................... 18
ALOCACIN DINMICA DE MEMORIA ................................................................................................................... 18

MTODOS DE ORDENAMIENTO ................................................................ 20


1)
2)

SELECCIN ............................................................................................................................................................. 20
BURBUJA ................................................................................................................................................................ 20

ALEATORIEDAD .......................................................................................... 23
RAND() .............................................................................................................................................................................. 23
SRAND() ............................................................................................................................................................................ 23

ESTRUCTURAS ........................................................................................... 24
DECLARACIN DE ESTRUCTURAS ................................................................................................................................... 24
PASO DE ESTRUCTURAS A FUNCIONES ........................................................................................................................... 24

LISTAS ......................................................................................................... 28
DEFINICIN ..................................................................................................................................................................... 28
FUNCIONES BSICAS SOBRE LISTAS ................................................................................................................................ 29

http://www.algoritmia.net
http://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C
http://www.fismat.umich.mx/mn1/manual/manual.html
http://profeblog.es/blog/alfredo/curso-de-programacion-en-c/

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

TIPOS DE DATOS
DATOS SIMPLES: predefinidos por el lenguaje
Tipo de dato
Int
Float
Char
Char [n]

Especificadores
de formato
%d
%f
%c
%s

Comentario
Entero con signo
Real con signo
caracter
Cadena de caracteres

DATOS COMPLEJOS (ESTRUCTURA DE DATOS):


Las estructuras de datos pueden ser de dos tipos:

Estticas: son aqullas que ocupan un espacio determinado en la memoria del ordenador.
Este espacio es invariable y lo especifica el programador durante la escritura del cdigo
fuente.

Dinmicas: sin aqullas cuyo espacio ocupado en la memoria puede modificarse durante la
ejecucin del programa.

OPERADORES
Nombre del Operador

Smbolo o representacin

Operador de miembro de estructura

nombre.miembro nombre->miembro

incremento, decremento, positivo, negativo,


NOT lgico, NOT de bits, derreferenciacin,
direccin, cast, tamao

++, --, +, -, !, ~, *'puntero, &nombre, (tipo)valor,


sizeof(variable)

Multiplicacin, Divisin, Mdulo

*, /, %

Suma y resta

+, -

Desplazamiento de bits izquierda y derecha

<<, >>

Comparaciones: Mayor que, Mayor o igual


que, Menor que, Menor o igual que

>, >=, <, <=

Comparaciones: Igual que, Diferente de

==, !=

AND para bits

&

XOR para bits

OR para bits

AND para comparacin

&&

OR para comparacion

||

Expresiones de condiciones

expr1 ? expr2 : expr3

Incrementar c en n, Decrementar c en n,
Multiplicar c por n, Dividir c entre n

c+=n, c-=n, c*=n, c/=n, ...

Alexis Giorgi / Luca Gonzlez Clavijo

Orden de
agrupacin
izquierda ->
derecha
derecha ->
izquierda
izquierda ->
derecha
izquierda ->
derecha
izquierda ->
derecha
izquierda ->
derecha
izquierda ->
derecha
izquierda ->
derecha
izquierda ->
derecha
izquierda ->
derecha
izquierda ->
derecha
izquierda ->
derecha
derecha ->
izquierda
derecha ->
izquierda

Programacin I

ESTRUCTURAS DE CONTROL
Se clasifican en estructuras de decisin y estructuras de ciclos

ESTRUCTURAS DE DECISIN O CONDICIONALES


Las estructuras de decisin o condicionales realizan una comparacin y en base al resultado de
esa comparacin, se sigue un curso de accin dentro del programa.
IF
if (Condicin)
{
Sentencia V;
}
else
{
Sentencia F;
}

ESTRUCTURAS DE CICLOS
Se utilizan para repetir una sentencia o un grupo de sentencias. La cantidad de veces que se repite
puede ser conocida de antemano o no.

WHILE
while (Condicin)
{
sentencia 1;
sentencia 2;
sentencia N;
}
FOR
for (pre ejecucin; condicin; pos ejecucin)
{
sentencia 1;
sentencia 2;
sentencia N;
}

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

VECTORES
Un array (arreglo) es una agrupacin de varios datos individuales del mismo tipo bajo el mismo
nombre. Cada dato individual de un array es accesible mediante un ndice.

El caso ms simple de array es el array unidimensional, tambin llamado vector. Por ejemplo, un
vector de nmeros enteros es una coleccin de varios nmeros enteros a los que les adjudicamos
un nico identificador.

La declaracin de un vector en C se hace as:


tipo_de_datos nombre_vector[nmero_de_elementos];

Por ejemplo: int serie[5];


La variable serie ser un vector que contendr 5 nmeros enteros. Se puede acceder a cada uno
de los nmeros que forman el vector escribiendo a continuacin del nombre un nmero entre
corchetes. Ese nmero se denomina ndice. Ejemplo:
int serie[5];
serie[2] = 20;
serie[3] = 15;
serie[4] = serie[2] + serie[3];
printf("%i", serie[4]);
El vector serie puede almacenar hasta 5 nmeros enteros. En su posicin 2 se almacena el nmero
20, y en su posicin 3, el 15. Luego se suman ambos valores, y el resultado se almacena en la
posicin 4. Finalmente, se imprime en la pantalla el resultado de la suma, es decir, 35.
Es muy til representar los vectores de forma grfica para entenderlos mejor. El vector serie del
ejemplo anterior se puede representar as:
Posiciones 0 1 2
3
4
Valores
? ? 20 15 35
Es importante observar que el primer elemento del vector tiene el ndice 0, es decir, el primer
elemento es serie[0]. Como este vector tiene 5 elementos, el ltimo ser serie[4], no serie[5].
Observar tambin que los elementos 0 y 1 no han sido utilizados y, por lo tanto, tienen un valor
desconocido, exactamente lo mismo que ocurre con cualquier variable de tipo simple que no se
inicialice.
Se pueden construir vectores cuyos elementos sean de cualquier otro tipo simple, con la nica
restriccin de que todos los elementos sean del mismo tipo. Tambin es posible construir vectores
cuyos elementos sean de un tipo complejo. As, podemos tener vectores de vectores o de cualquier
otro tipo.

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

OPERACIONES TPICAS CON VECTORES


1) Manipulacin de elementos individuales
Los vectores en C deben manipularse elemento a elemento.
Para asignar valores a los elementos de un vector el mecanismo es este:
int serie[5];
serie[0] = 5;
serie[1] = 3;
serie[2] = 7;
...etc...

La inicializacin de los valores de un vector tambin puede hacerse conjuntamente en el momento


de declararlo:
int serie[5] = {5, 3, 7, 9, 14};

Cada elemento del vector es una variable que puede usarse independientemente de los dems
elementos. As, por ejemplo, un elemento del vector serie puede usarse en una instruccin de
salida igual que cualquier variable simple de tipo int:
int serie[5];
serie[0] = 21;
printf("%i", serie[0]);

Del mismo modo, pueden usarse elementos de vector en una instruccin de entrada. Por ejemplo:
int serie[5];
scanf("%i", &serie[0]);
serie[1] = serie[0] + 15;
printf("%i", serie[1]);

2) Recorrido de un vector
Una forma habitual de manipular un vector es accediendo secuencialmente a todos sus elementos,
uno tras otro. Para ello, se utiliza un bucle con contador, de modo que la variable contador nos
sirve como ndice para acceder a cada uno de los elementos del vector.

Supongamos, por ejemplo, que tenemos un vector de 10 nmeros enteros declarado como int
v[10]; y una variable entera declarada como int i; Por medio de un bucle podemos realizar todas
estas operaciones:

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

a) Inicializar todos los elementos a un valor cualquiera (por ejemplo, 0):


for (i = 0; i <= 9; i++)
{
v[i] = 0;
}

b) Inicializar todos los elementos con valores introducidos por teclado:


for (i = 0; i <= 9; i++)
{
printf("Escriba el valor del elemento n %i: ", i);
scanf("%i", &v[i]);
}

c) Mostrar todos los elementos en la pantalla:


for (i = 0; i <= 9; i++)
{
printf("El elemento n %i vale %i\n", i, v[i]);
}

d) Realizar alguna operacin que implique a todos los elementos. Por ejemplo, sumarlos:
suma = 0;
for (i = 0; i <= 9; i++)
{
suma = suma + v[i];
}

3) Bsquedas en vectores

Si las bsquedas se realizan pocas veces, o bien los vectores son pequeos, optaremos por
la bsqueda secuencial, que no necesita ordenar previamente el vector.

Si las bsquedas se realizan muchas veces y los vectores son de gran tamao, optaremos
por la bsqueda binaria, pero antes debemos ordenar el vector

a) Bsqueda secuencial
Consiste en recorrer el vector desde el primer elemento hasta el ltimo. Si encontramos el dato
buscado, podemos interrumpir la bsqueda. Si no, continuaremos hasta el final del vector.

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

Esta es una posible implementacin en C:


// Bsqueda secuencial
// Buscamos el elemento dato en el vector v
// Devolvemos la posicin donde est dato o, si no lo encontramos, -1
int buscar(int v[LONGITUD_VECTOR], int dato)
{
int i = 0;
int x = -1;
while ((i < LONGITUD_VECTOR) && (x == -1))
{
if (v[i] == dato)
x = i;

// Lo hemos encontrado

// Anotamos en x la posicin

i++;
}
return x;
}

b) Bsqueda binaria

Para que esta bsqueda funcione, el vector debe estar previamente ordenado. El mtodo consiste
en lo siguiente:

Supongamos que v es el vector y que contiene N elementos. Llamaremos iz a la posicin del


elemento izquierdo del vector (inicialmente, iz = 0). Llamaremos de a la posicin del elemento
derecho del vector (inicialmente, de = N-1)
Tomamos un x igual al punto medio entre iz y de, es decir, x = (iz/de) / 2
Miramos el elemento v[x]. Si es el dato que buscbamos, ya hemos terminado. Si no, pueden
ocurrir dos cosas:
Que v[x] sea mayor que el dato que buscbamos. En ese caso, y dado que el vector est
ordenado, continuamos la bsqueda a la izquierda de x, haciendo que de = x.
Que v[x] sea menor que el dato que buscbamos. En ese caso, continuamos la bsqueda a la
derecha de x, haciendo iz = x.
Repetimos desde el paso 2 hasta que encontremos el elemento buscado o hasta que iz = de (lo
que significar que el elemento no est en el vector)

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

He aqu una implementacin en C:


// Buscamos el elemento busc en el vector v, que debe estar ordenado
// Devolvemos la posicin donde est busc o, si no lo encontramos, -1
int buscar_binario(int v[LONGITUD_VECTOR], int busc)
{
int izq, der, mitad, encontrado;
// Iniciamos una bsqueda binaria
encontrado = 0;
izq = 0;
der = LONGITUD_VECTOR - 1;
while ((izq <= der) && (encontrado == 0))
{
mitad = izq + ((der - izq) / 2);
if (v[mitad] == busc)

// Calculamos la posicin "mitad"

// Lo hemos encontrado !!

encontrado = 1;
if (v[mitad] > busc)

// Seguimos buscando en la mitad izquierda

der = mitad-1;
if (v[mitad] < busc)

// Seguimos buscando en la mitad derecha

izq = mitad+1;
}
if (encontrado == 1)
return mitad;
else
return -1;
}

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

4) Paso de vectores como parmetros a funciones

Para pasar un vector como argumento a una funcin, en la llamada a la funcin se escribe
simplemente el nombre del vector, sin ndices. Esto sirve para pasar a la funcin la direccin de
memoria donde se almacena el primer elemento del vector. Como C guarda todos los elementos de
los vectores en posiciones de memoria consecutivas, conociendo la direccin del primer elemento
es posible acceder a todas las dems.

El hecho de que a la funcin se le pase la direccin del vector y no sus valores provoca un efecto
importante: que los arrays siempre se pasan por referencia, nunca por valor. Por lo tanto, si algn
elemento del vector se modifica en una funcin, tambin ser modificado en la funcin desde la
que fue pasado.
Como siempre se pasan por referencia, no es necesario utilizar el smbolo & delante del parmetro.

Por ejemplo, supongamos que serie es un vector de 15 nmeros enteros. Para pasarlo como
parmetro a una funcin llamada funcion escribiramos simplemente esto:
int serie[15];
funcion1(serie);

En cuanto a la definicin de la funcin, la declaracin de un parmetro que en realidad es un vector


se puede hacer de tres maneras diferentes:
void funcion1 (int sere[15]);

/* Array delimitado */

void funcion1 (int serie[]);

/* Array no delimitado */

void funcion1 (int *serie);

/* Puntero */

El resultado de las tres declaraciones es, en principio, idntico, porque todas indican al compilador
que se va a recibir la direccin de un vector de nmeros enteros.
Dentro de la funcin, el vector puede usarse del mismo modo que en el programa que la llama, es
decir, no es preciso utilizar el operador asterisco.

Por ejemplo: Un programa que sirve para leer 50 nmeros por teclado, y calcular la suma, la media
y la desviacin tpica de todos los valores. La desviacin es una magnitud estadstica que se
calcula restando cada valor del valor medio, y calculando la media de todas esas diferencias.
Observe el siguiente programa de ejemplo detenidamente, prestando sobre todo atencin al uso de
los vectores y a cmo se pasan como parmetros.
Los nmeros de la serie se almacenarn en un vector float de 50 posiciones llamado valores. La
introduccin de datos en el vector se hace en la funcin introducir_valores(). No es necesario usar

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

10

el smbolo & al llamar a la funcin, porque los vectores siempre se pasan por referencia. Por lo
tanto, al modificar el vector dentro de la funcin, tambin se modificar en el algoritmo principal.
Despus, se invoca a tres funciones que calculan las tres magnitudes. El vector tambin se pasa
por referencia a estas funciones.
#include <stdio.h>
#include <math.h>
int main(void)
{
float valores[50];
float suma, media, desviacion;
introducir_valores(valores);
suma = calcular_suma(valores);
media = calcular_media(valores, suma);
desviacion = calcular_desviacion(valores, media);
printf("La suma es %f, la media es %f y la desviacin es %f", suma, media,
desviacion);
return 0;
}
/* Lee 50 nmeros y los almacena en el vector N pasado por variable */
void introducir_valores(float N[50])
{
int i;
for (i=1; i<=49; i++)
{
printf("Introduzca el valor n %d: ", i);
scanf("%f", &N[i]);
}
}

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

11

/* Devuelve la suma todos los elementos del vector N */


float calcular_suma(float N[50])
{
int i;
float suma;
suma = 0;
for (i=1; i<=49; i++)
suma = suma + N[i];
return suma;
}
/* Devuelve el valor medio de los elementos del vector N. Necesita conocer la
suma de los elementos para calcular la media */
float calcular_media(float N[50], float suma)
{
int i;
float media;
media = suma / 50;
return media;
}
/* Calcula la desviacin tpica de los elementos del vector N. Necesita conocer
la media para hacer los clculos */
float calcular_desviacion(float N[50], float media)
{
int i;
float diferencias;
diferencias = 0;
for (i=1; i<=49; i++)
diferencias = diferencias + abs(N[i] media) ;
diferencias = diferencias / 50;
return diferencias;
}

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

12

MANEJO DE CADENAS
Los vectores cuyos elementos son caracteres se denominan cadenas de caracteres o,
simplemente, cadenas. Por lo tanto, una cadena de caracteres se declara as:
char cadena[50];

/* Cadena de 50 caracteres */

Declaracin y manipulacin de cadenas:


Las cadenas pueden manipularse elemento por elemento, como cualquier vector. Por ejemplo:
char cadena[50];
cadena[0] = 'H';
cadena[1] = 'o';
cadena[2] = 'l';
cadena[3] = 'a';

Las cadenas deben tener, despus de su ltimo carcter vlido, un carcter especial llamado nulo
\0.
En consecuencia, en una cadena definida como la anterior, de 50 caracteres, en realidad slo
tienen cabida 49, ya que siempre hay que reservar una posicin para el carcter nulo.

La declaracin de una cadena puede ir acompaada de una inicializacin mediante una constante.
En este caso, la constante debe ir encerrada entre comillas dobles, al tratarse de una cadena y no
de caracteres sueltos. Por ejemplo:
char cadena[50] = "Hola";
En inicializaciones de este tipo, el compilador se encarga de aadir el carcter nulo.

Por ltimo, sealemos que no es necesario indicar el tamao de la cadena si se inicializa al mismo
tiempo que se declara. Por ejemplo, la declaracin anterior puede sustituirse por esta otra:
char cadena[] = "Hola";

Esto se denomina array de longitud indeterminada. El compilador, al encontrar una declaracin as,
crea una cadena del tamao suficiente para contener todos los caracteres. Esto vale no slo para
las cadenas, sino que tambin es aplicable a cualquier otro tipo de array que se inicialice al mismo
tiempo que se declare.

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

13

Las cadenas y el control de los datos de entrada:


Para prevenir errores, se puede leer todos los datos de entrada como cadenas y luego convertirlos
al tipo de dato adecuado.
El siguiente ejemplo sirve para leer un nmero entero por teclado. Se utiliza la funcin atoi(), que
convierte una cadena a un nmero entero.
int n;

// El nmero entero que se pretende leer por teclado

char cad[50];

// La cadena que se usar para prevenir errores de lectura

printf("Introduzca un nmero entero");


gets(cad);

// No se lee un nmero entero, sino una cadena

n = atoi(cad);

// Se convierte la cadena a entero

FUNCIONES ESTNDAR PARA MANEJAR CADENAS


Las funciones de librera ANSI C para manejar cadenas suelen empezar por las letras str (de
string, que significa cadena en ingls) y utilizan el archivo de cabecera string.h.

1. gets() y puts()
Para leer por teclado una cadena de caracteres se puede utilizar tambin la funcin scanf() con la
cadena de formato %s. Como las cadenas son vectores, no es preciso anteponer el smbolo & al
nombre de la variable. Sin embargo, es preferible emplear la funcin gets() por estar
especficamente diseada para la lectura de cadenas. Por ejemplo:
char cadena[50];
printf("Introduzca su nombre ");
gets(cadena);

Tanto scanf() como gets() insertan automticamente el carcter \0 al final de la cadena.


De manera anloga podemos emplear la funcin printf() para escribir el contenido de una cadena
en la pantalla, pero preferiremos la funcin puts(), especfica de las cadenas. Por ejemplo:
char cadena[50] = "Hola, mundo";
puts(cadena);
2. strcpy()
Copia el contenido de una cadena en otra, incluyendo el carcter nulo. Su sintaxis es:
strcpy(cadena_origen, cadena_destino);

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

14

3. strlen()
Devuelve la longitud de una cadena, es decir, el nmero de caracteres de que consta, sin contar el
carcter nulo.
Por ejemplo, en este fragmento de cdigo el resultado debe ser 11. Fjate que la variable cadena
tiene una longitud total de 50 caracteres, pero strlen() slo cuenta los que efectivamente se estn
usando, es decir, los que hay hasta el carcter nulo:
char cadena[50] = "Hola, mundo";
int longitud;
longitud = strlen(cadena);
printf("La longitud es %i", longitud);
4. strcmp()
Compara dos cadenas. Devuelve el valor 0 si son iguales, un valor mayor que 0 si la primera es
alfabticamente mayor que la segunda, o un valor menor que 0 en caso contrario. Su sintaxis es
general es:
strcmp(cadena1, cadena2);
Por ejemplo:
char cad1[50], cad2[50];
int comparacion;
printf("Introduzca dos cadenas");
scanf("%s %s", cad1, cad2);
comparacion = strcmp(cad1, cad2);
if (comparacion == 0)
printf("Las dos cadenas son iguales");
5. strcat()
Concatena dos cadenas. Esta funcin aade la cadena2 al final de la cadena1, incluyendo el
carcter nulo.
strcat(cadena1, cadena2);
El resultado de este ejemplo debe ser, otra vez, hola, mundo:
char cad1[50] = "Hola, ";
char cad2[50] = "mundo";
strcat(cad1, cad2);
prinft("%s", cad1);

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

15

6. strchr()
Devuelve la posicin en memoria de la primera aparicin de un caracter dentro de la cadena
posicion = strchr(cadena, caracter)

7. strstr()
Devuelve la posicin en memoria de la primera aparicin de una subcadena dentro de la cadena
posicion = strstr(cadena,subcadena)
Ejemplo general:
#include <stdio.h>
#include <string.h>
...
char color[] = "rojo";
char grosor[] = "grueso";
...
char descripcion[1024];
strcpy(descripcion, "Lapiz color ");
strncat(descripcion, color, 1024);
strncat(descripcion, " de trazo ", 1024);
strncat(descripcion, grosor, 1024);
// descripcion contiene "Lapiz color rojo de trazo grueso"
...
void intercambiar(char vector[], int pos1, int pos2);
void invierte_cadena(char cadena[])
{
int largo = strlen(cadena);
for (int i=0; i < (largo/2); i++) {
intercambiar(cadena, i, (largo-1)-i);
}
}
void intercambiar(char vector[], int pos1, int pos2)
{
char aux=vector[pos1];
vector[pos1]=vector[pos2];
vector[pos2]=aux;
}

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

16

PUNTEROS
#include <stdio.h>
#include <stdlib.h>
int l1 (char c[]);
int l2 (char c[]);
int main(void) {
int x, i, z[10];
int *p;
char vec[50];
printf("ingrese una cadena \n");
fgets( vec, 50, stdin);
printf ("el largo de la cadena es %d \n", l2(vec));
return EXIT_SUCCESS;
}
int l1 (char c[])
{
int i;
for (i=0; c[i] != '\0'; i++)
;
return i;
}
int l2 (char *c)
{
int i;
for (i=0; *c

!= '\0'; c++, i++)

;
return i;
}

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

17

FUNCIONES
Definicin: Grupo de sentencias bajo el mismo nombre que realizan una tarea especfica.
Uso: utilizar el valor retornado por la funcin, almacenndolo en una variable o utilizndolo en una
expresin.

a) PROTOTIPADO DE FUNCIONES
Se realiza despus de las libreras y antes del cuerpo del programa (main). Se compone de:
Tipo_de_dato_de_retorno Nombre_de_la_funcion(parmetros);
Ejemplo: int largo(char cadena[]);

b) DECLARACIN DE FUNCIONES
La funcin se declara por fuera del cuerpo del programa, como subprograma. Las variables de la
funcin son locales, mientras que las declaradas en main son globales.
Tipo_de_dato_de_retorno Nombre_de_la_funcion(parmetros) (idem prototipo, pero sin el ;)
{
Variables

locales;

Sentencias;
Return valor; (si la funcin devuelve un valor)
}

Ejemplo:
int largo(char cadena[])
{
int i;
for(i=0;cadena[i]!=0;i++);
return i;
}

c) INVOCACIN DE FUNCIONES
La llamada a la funcin se realiza desde el cuerpo del programa (main). Consiste en una mencin
al nombre de la funcin seguida, entre parntesis, de los valores que se desean asignar a los
parmetros. Deben aparecer tantos valores como parmetros tenga la funcin, y adems coincidir
en tipo.

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

18

d) PASO DE PARMETROS
Existen dos formas de pasar parmetros:
1. Paso por Valor: Se enva una copia de los parmetros a la funcin, por lo tanto los cambios
que se hagan en ella no son tomados en cuenta dentro de la funcin main()
2. Paso por Referencia: Se enva la direccin de memoria de la variable, por lo tanto los
cambios que haga la funcin si afectan el valor de la variable dentro de la funcin main()
Para pasar valores por referencia, utilizamos un asterisco delante del parmetro.

e) FUNCIONES VOID
Si el Tipo_de_dato_de_retorno es void, se considera que la funcin no devuelve ningn valor y
que, por lo tanto, es un procedimiento. Un ejemplo de procedimiento es la funcin printf.

f) ALOCACIN DINMICA DE MEMORIA


/*
============================================================================
Name
: ADSimple.c
Author
: German
Version
:
Copyright
: Your copyright notice
Description : Ejemplo sencillo de alocacion dinamica de memoria
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i, j;
char *c;
int *pi;
printf ("ingrese la cantidad de elementos");
scanf("%d", &i);
pi = malloc (sizeof(int) * i);
for(j=0 ; j<i ; j++)
{
printf ("ingrese el valor %d\n", j);
scanf("%d", pi+j);
}
for(j=0 ; j<i ; j++)
{
printf (" el valor %d es %d \n", j, *(pi+j));
}
//printf("la cadena es: %s",c);
return EXIT_SUCCESS;
}

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

19

/*
============================================================================
Name
: ADComplejo.c
Author
: German
Version
:
Copyright
: Your copyright notice
Description : Ejemplo complejo de alocacion dinamica de memoria
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
int mystrlen(char *c);
void mystrcpy (char *ori, char *dest);
int main(void) {
int i;
char *c[5];
char aux[1000];
for (i=0;i<5;i++)
{
printf ("ingrese la cadena %d \n", i); //obtenemos la cadena en un
auxiliar
fgets(aux,1000,stdin);
c[i] = malloc (sizeof(char) * mystrlen(aux)); //calculamos el tamao
de la cadena y alocamos el espacio
mystrcpy(aux,c[i]); //copiamos el contenido del auxiliar a la
posicion del vector de cadenas correspondientes
}
for (i=0;i<5;i++)
printf ("ingrese la cadena %d es : %s \n", i, c[i]);
return EXIT_SUCCESS;
}
int mystrlen(char *c)
{
int i=0;
while (*c != '\0')
{
i++;
c++;
}
return i;
}
void mystrcpy (char *ori, char *dest)
{
while (*ori != '\0')
{
*dest = *ori;
dest++;
ori++;
}
*dest = '\0';
}

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

20

MTODOS DE ORDENAMIENTO
Su finalidad es organizar ciertos datos (normalmente arrays o ficheros) en un orden creciente o
decreciente mediante una regla prefijada (numrica, alfabtica, etc) atendiendo al tipo de elemento
que se quiera ordenar.

Tipos

Interna: Los datos se encuentran en memoria (ya sean arrays, listas, etc) y son de acceso
aleatorio o directo (se puede acceder a un determinado campo sin pasar por los anteriores)

Externa: los datos estn en un dispositivo de almacenamiento externo (ficheros) y su


ordenacin es ms lenta que la interna

Ordenacin Interna

1) SELECCIN
Este mtodo consiste en buscar el elemento ms pequeo del array y ponerlo en primera posicin;
luego, entre los restantes, se busca el elemento ms pequeo y se coloca en segundo lugar, y as
sucesivamente hasta colocar el ltimo elemento.

2) BURBUJA
Consiste en comparar pares de elementos adyacentes e intercambiarlos entre s hasta que estn
todos ordenados.
/*
============================================================================
Name
: ordenamiento.c
Author
: German
Version
:
Copyright
: Your copyright notice
Description : test de ordenamiento
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAXLEN 10
//prototipos
void llenarArray(int v[], int l);
void mostrarArray(int v[], int l);
void selecSort(int v[], int l);
void burbuSort(int v[]);
int estaOrdenado(int v[], int l);

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

21

int main(void)
{
int array[MAXLEN];
llenarArray(array, MAXLEN);
mostrarArray(array,MAXLEN);
if (estaOrdenado(array,MAXLEN))
printf ("Esta ordenado!!\n");
else
printf ("Esta desordenado!! \n");
selecSort(array, MAXLEN);
mostrarArray(array,MAXLEN);
if (estaOrdenado(array,MAXLEN) == 1)
printf ("Esta ordenado!!\n");
else
printf ("Esta desordenado!! \n");
/*
llenarArray(array, MAXLEN);
mostrarArray(array,MAXLEN);
burbuSort(array);
mostrarArray(array,MAXLEN);
*/
return EXIT_SUCCESS;
}
//toma el array y su limite. lo llena de elementos aleatorios
void llenarArray(int v[], int l)
{
int i;
srand(time(NULL));
for (i = 0 ; i < l ; i++)
v[i] = rand()%1000;
}
//toma el array y su limite, muestra por pantalla
//posicion a posicion
void mostrarArray(int v[], int l)
{
int i;
for (i = 0 ; i < l ; i++)
printf ("la posicion %d es: %d \n", i, v[i]);
}

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

22

//implementa el ordenamiento por seleccion


void selecSort(int v[], int l)
{
int i,j,aux;
for(i=0;i< l-1;i++)
{
for(j=i+1;j< l ;j++)
if(v[j] < v[i]) // Si el elemento j es menor que el i:
{
aux=v[i]; // Se intercambian los elementos
v[i]=v[j]; // de las posiciones i y j
v[j]=aux; // usando una variable auxiliar.
}
}
}
int estaOrdenado(int v[], int l)
{
int i,j;
for(i=0;i< l-1;i++)
{
for(j=i+1;j< l ;j++)
if(v[j] < v[i]) // Si el elemento j es menor que el i:
{
return 0;
}
}
return 1;
}
//implementa el ordenamiento por burbujeo
void burbuSort(int v[])
{
int i,j,aux;
for(i=0;i<MAXLEN-1;i++) // Hacer N-1 pasadas.
{
for(j=0;j<MAXLEN-i-1;j++) // Mirar los N-i-1 pares.
{
if(v[j+1] < v[j]) // Si el elemento j+1 es menor que el elemento j:
{
aux=v[j+1]; // Se intercambian los elementos
v[j+1]=v[j]; // de las posiciones j y j+1
v[j]=aux; // usando una variable auxiliar.
}
}
}
}

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

23

ALEATORIEDAD
Cuando necesitamos obtener nmeros de forma aleatoria, utilizamos alguna de las siguientes
funciones:

rand()
Esta funcin nos devuelve un nmero entero aleatorio entre 0 y el RAND_MAX (mnimo de 32767,
dependiendo de la librera)
Si queremos acotar el rango, por ejemplo, un nmero aleatorio entre 0 y 10:
numero = rand() % 11;
O de forma ms general, entre 0 y N:
numero = rand() % (N+1);
La operacin mdulo (%) nos da el resto de dividir rand() entre 11. Este resto puede ir de 0 a 10.
De la misma forma, el mdulo de rand() entre N+1 va de 0 a N.
Si queremos, por ejemplo, un rango entre 20 y 30 (de forma ms general, entre M y N con N mayor
que M), obtenemos un nmero entre 0 y 10 y le sumamos 20 (un nmero entre 0 y N-M y le
sumamos M)
numero = rand () % 11 + 20;

// entre 20 y 30

numero = rand () % (N-M+1) + M;

// entre M y N

srand()
Si ejecutamos varias veces nuestro programa, la secuencia de nmeros aleatorios se repite.
El problema es que rand() "calcula" los nmeros aleatorios, partiendo de un nmero inicial (llamado
semilla).
Para evitar este problema tenemos la funcin srand(), a la que se le pasa como parmetro un
nmero que se utilizar como nmero inicial para las cuentas. A esta funcin slo debemos
llamarla una vez en nuestro programa.

Hay dos nmeros que se utilizan habitualmente para ello:

La fecha/hora del sistema: este valor cambia si ejecutamos el programa en distinto instante
de tiempo. Tendramos que arrancar el programa dos veces en el mismo segundo para
obtener la misma secuencia de nmeros aleatorios.
srand (time(NULL));

El nmero de proceso del programa: srand (getpid());

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

24

ESTRUCTURAS
Una estructura es una agrupacin bajo el mismo nombre de varios datos cuyos tipos pueden ser
diferentes.

DECLARACIN DE ESTRUCTURAS
struct nombre_estructura
{
tipo1 dato1;
tipo2 dato2;
...
tipoN datoN;
};

Podemos asignarle un alias o sinnimo al nombre de la estructura, para evitar el tener que poner
"struct nombre_estructura" cada vez, usando la palabra clave typedef, lo que crea un alias a un
tipo:
typedef struct nombre_estructura nuevotipo;
As, podemos escribir nuevotipo en lugar de struct mi_estructura a lo largo del programa, lo cual
es mucho ms legible.

Cada dato que forma parte de la estructura se denomina miembro.


El acceso a los miembros se realiza con el nombre de la variable y el del miembro separados por
un punto, as: variable_estructura.miembro;

PASO DE ESTRUCTURAS A FUNCIONES


Ejemplos basados en la siguiente estructura:
struct datos_carnet
{
long int numero;
char letra;
char nombre[50];
char apellidos[100];
};
struct datos_carnet dni;

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

25

1. Paso de estructuras completas como parmetros


Para pasar la variable dni por valor a una funcin llamada escribir_dni():
escribir_dni(dni);
Y tambin puede pasarse por referencia aadiendo el smbolo &:
escribir_dni(&dni);
A su vez, la funcin escribir_dni() debe especificar en su declaracin si el argumento se pasa por
valor o por variable. El paso por valor se indica as:
void escribir_dni(struct datos_carnet dni)
Mientras que el paso por variable tiene esta forma (usando el smbolo * ):
void escribir_dni(struct datos_carnet* dni)
Dentro de la funcin, el acceso a los miembros de la estructura es diferente si sta ha sido pasada
por valor o por variable. As, el acceso al miembro nombre de la estructura dni, si sta ha sido
pasada por valor, se hace a la manera habitual:
printf("%s", dni.nombre);
Pero si la estructura dni se ha pasado por variable, se desreferencia con: ->:
printf("%s", dni->nombre);

2. Paso de miembros de estructuras como parmetros


Los miembros de las estructuras se pueden manipular como cualquier otro dato del mismo tipo que
el miembro. Por ejemplo, como dni.numero es de tipo entero largo (long int), puede realizarse con
este miembro cualquier operacin que tambin pueda realizarse con un nmero entero largo,
incluido el paso como parmetro a una funcin.
As, para pasar por valor nicamente el miembro dni.numero a una funcin llamada, por ejemplo,
escribir_dni(), haramos esto:
escribir_dni(dni.numero);
En la declaracin de la funcin, el parmetro formal debe ser de tipo long int:
void escribir_dni(long int numero)
Dentro del cuerpo de la funcin, la variable nmero puede usarse como cualquier otra variable de
tipo entero.
Si lo que queremos es pasar el miembro dni.numero por referencia, no por valor, lo haremos igual
que con cualquier dato de tipo entero, es decir, agregando el smbolo & a la llamada:
escribir_dni(&dni.numero);
Y en la declaracin de la funcin el parmetro debe llevar el smbolo * :
void escribir_dni(long int *numero)
En este caso, cada vez que vaya a usarse el parmetro nmero dentro del cdigo de la funcin, al
estar pasado por variable debe ir precedido del smbolo * ; por ejemplo: *numero = 5;

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

26

Ejemplo cdigo Germn:


/*
============================================================================
Name
: estructuras.c
Author
: German
Version
:
Copyright
: Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct triangulo
{
int a;
int b;
int c;
};
typedef struct triangulo triangulo;
struct persona
{
int edad;
char *nombre;
char *apellido;
};
typedef struct persona persona;
int perimetro (triangulo t);
void getTriangulo(triangulo *t);
int main(void) {
triangulo t,z;
persona p;
char aux[1000];
p.edad = 33;
printf("ingrese el nombre: \n");
fgets(aux,1000,stdin);
p.nombre = malloc (sizeof (char) * strlen(aux));
strcpy(p.nombre,aux);
printf ("el nombre de la estructura es %s", p.nombre);
//
//
//
//
//

getTriangulo(&t);
getTriangulo(&z);
printf ("el lado a vale: %d \n", t.a);
printf ("el lado b vale: %d \n", t.b);
printf ("el lado c vale: %d \n", t.c);
return EXIT_SUCCESS;

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

27

int perimetro (triangulo t)


{
return t.a + t.b +t.c;
}
void getTriangulo(triangulo *t)
{
printf ("ingrese el lado a: \n");
scanf ("%d", &t->a);
printf ("ingrese el lado b: \n");
scanf ("%d", &t->b);
printf ("ingrese el lado c: \n");
scanf ("%d", &t->c);
printf ("mensaje dentro de la f %d", t->a);
}
Ejemplo de estructuras con memoria dinmica:
/*
============================================================================
Name
: memdinamica.c
Author
: German
Version
:
Copyright
: Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
struct triangulo {
int a;
int b;
int c;
};
typedef struct triangulo TRI;
void llenarVector(TRI *v, int l);
void mostrarVector(TRI *v, int l);
int main(void) {
int i;
TRI v[2];
/*
printf("ingrese la cantidad de elementos \n");
scanf("%d", &i);
v = malloc(sizeof(TRI) * i);
*/
llenarVector(v,2);
mostrarVector(v,2);
puts("practica de alocacionxxxx dinamica de enteros"); /* prints practica
de alocacion dinamica de enteros */
return EXIT_SUCCESS;
}

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

28

void llenarVector(TRI *v, int l)


{
int x;
for (x = 0; x < l ; x++)
{
printf("ingrese el elemento %d \n", x);
scanf("%d", &((v+x)->a));
printf("ingrese el elemento %d \n", x);
scanf("%d", &((v+x)->b));
printf("ingrese el elemento %d \n", x);
scanf("%d", &((v+x)->c));
}
}
void mostrarVector(TRI *v, int l)
{
int x;
for (x = 0; x < l ; x++)
{
printf(" el elemento %d es %d-%d-%d \n", x, (v+x)->a,(v+x)->b,(v+x)->c );
}
}

LISTAS
DEFINICIN
Una lista es una estructura de datos secuencial.
Una manera de clasificarlas es por la forma de acceder al siguiente elemento:

lista densa: la propia estructura determina cul es el siguiente elemento de la lista. Ejemplo: un
array.

lista enlazada: la posicin del siguiente elemento de la estructura la determina el elemento


actual. Es necesario almacenar al menos la posicin de memoria del primer elemento. Adems
es dinmica, es decir, su tamao cambia durante la ejecucin del programa.

Una lista enlazada se puede definir recursivamente de la siguiente manera:

una lista enlazada es una estructura vaca o

un elemento de informacin y un enlace hacia una lista (un nodo).

Grficamente se suele representar as:

Como se ha dicho anteriormente, pueden cambiar de tamao, pero su ventaja fundamental es que
son flexibles a la hora de reorganizar sus elementos; a cambio se ha de pagar una mayor lentitud a
la hora de acceder a cualquier elemento.

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

29

Implementacin
struct nodo
{
int dato;
struct nodo *sig;
};
typedef struct nodo NODO;

FUNCIONES BSICAS SOBRE LISTAS


1) Verificacin de la cantidad de nodos (debe ser mayor a 1)
if (cantNodos < 1)
{
printf("La cantidad de nodos debe ser mayor a 1 \n");
return 0;
}

2) Creacin de nuevo nodo:


NODO *CrearNodo()
{
NODO *nodoAUX;
nodoAUX = (NODO *) malloc(sizeof(NODO));
printf("Ingrese un valor para el nodo \n");
fflush(stdin);
scanf("%d", &nodoAUX->dato);
nodoAUX->sig = NULL;
return nodoAUX;
}

3) Insertar nodo desordenado:


NODO *InsertarNodoDesordenado(NODO *l,NODO *n)
{
n->sig=l;
return n;
}

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

30

4) Insertar nodo ordenado:


NODO *InsertarNodoOrdenado(NODO *l,NODO *n)
{
NODO *aux;
if (n->dato < l->dato)
{
n->sig = l;
return n;
}
else
{
aux = l;
while (aux->sig != NULL && aux->sig->dato < n->dato )
aux = aux->sig;
if (aux->sig == NULL)
aux->sig = n;
else
{
n->sig=aux->sig;
aux->sig=n;
}
return l;

//llego al final de la lista

}
}

5) Mostrar lista en pantalla:


void MostrarLista(NODO *l)
{
printf("\n****************** display de la lista ******************\n\n");
while (l->sig != NULL)
{
printf ("| %d ", l->dato);
l = l->sig;
}
printf ("| %d | \n", l->dato);
printf("\n****************** display de la lista ******************\n");
}

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

31

6) Buscar un elemento en una lista


int BuscarElementoEnLista (NODO *l,int n)
{
int rdo=0;
if(l->sig==NULL)
{
if(l->dato==n)
rdo=1;
}
while(l->sig!=NULL)
{
if(l->dato==n)
rdo=1;
l=l->sig;
}
return rdo;
}
7)

Eliminar elementos de una lista:


a) Eliminar el primer nodo:

t_nodo *segundo;
if (primero != NULL) {
// Comprobamos que la lista no est vaca
segundo = primero->siguiente;
// Guardamos la referencia al segundo elemento
free(primero);
// Eliminamos el primero (es importante liberar la memoria)
primero = segundo;
// El que era segundo se convierte en primero
}
b) Eliminar un nodo cualquiera: Suponiendo que queremos eliminar el nodo siguiente a
aqul que contiene en dato 7:
t_nodo *anterior, *aux;
// Primera parte: buscar el nodo anterior al que vamos a borrar (contendr el
dato 7)
anterior = primero;
while ((anterior->dato != 7) && (anterior != NULL))
anterior = anterior->siguiente;
// Segunda parte: borrar el nodo siguiente y reasignar los punteros
if (anterior != NULL) {
// Comprobamos que hemos encontrado el
punto de eliminacin
aux = anterior->siguiente;
// aux es
el nodo que queremos eliminar
anterior->siguiente = aux->siguiente; // Reasignamos los enlaces
free(aux);
// Eliminamos el nodo
}
c) Eliminar todos los nodos de una lista:
Para eliminar una lista completa hay que recorrer todos los nodos e ir liberando la memoria de cada
uno, hasta que alcancemos el ltimo nodo (que reconoceremos porque estar apuntando a NULL).
Otra manera de hacerlo es eliminar el primer elemento de la lista repetidamente, segn el algoritmo
que hemos visto antes, hasta que el primer elemento sea NULL. Eso significar que la lista se ha
quedado vaca.

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

32

/*
============================================================================
Name
: listasSimples.c
Author
: German
Version
:
Copyright
: Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct nodo
{
int dato;
struct nodo *sig;
};
typedef struct nodo NODO;
NODO *CrearNodo();
void MostrarLista(NODO *l);
NODO * InsertarNodoOrdenado(NODO *l, NODO *n);
NODO * InsertarNodoDesOrdenado(NODO *l, NODO *n);
int main(void) {
NODO *raiz;
NODO *nodoAux;
NODO *newNodo;
int cantNodos;
int i;
system("clear");
printf("Ingrese la cantidad de nodos a crear: ");
scanf("%d", &cantNodos);
if (cantNodos < 1)
{
printf("la cantidad de nodos debe ser mayor a 1 \n");
return (0);
}
raiz = CrearNodo();
nodoAux = raiz;
for (i = 1; i < cantNodos; i++)
{
newNodo= CrearNodo();
nodoAux = InsertarNodoDesOrdenado(nodoAux, newNodo);
MostrarLista(nodoAux);
}
raiz = nodoAux;
MostrarLista(raiz);
}

Alexis Giorgi / Luca Gonzlez Clavijo

Programacin I

33

NODO * CrearNodo()
{
NODO *nodoAux;
nodoAux = (NODO *) malloc(sizeof(NODO));
printf("ingrese un valor para el nodo \n");
fflush(stdin);
scanf("%d", &nodoAux->dato);
nodoAux->sig = NULL;
return nodoAux;
}
void MostrarLista(NODO *l)
{
printf("\n****************** display de la lista ******************\n\n");
while (l->sig != NULL)
{
printf ("| %d ", l->dato);
l = l->sig;
}
printf ("| %d | \n", l->dato);
printf("\n****************** display de la lista ******************\n");
}
NODO * InsertarNodoOrdenado(NODO *l, NODO *n)
{
NODO *aux;
if (n->dato < l->dato)
{
n->sig = l;
return (n);
}
else
{
aux = l;
while (aux->sig != NULL && aux->sig->dato < n->dato )
aux = aux->sig;
if (aux->sig == NULL)
aux->sig = n;
else
{
n->sig=aux->sig;
aux->sig=n;
}
return (l);

//llego al final de la lista

}
}
NODO * InsertarNodoDesOrdenado(NODO *l, NODO *n)
{
n->sig = l;
return (n);
}

Alexis Giorgi / Luca Gonzlez Clavijo

También podría gustarte