Está en la página 1de 17

Captulo 5.

Captulo 5.

Uso avanzado de apuntadores


5. Apuntadores y arreglos multidimensionales
Supongamos que tenemos la siguiente declaraci3n:

int Matriz4][3]={ {8,0,-1},


{4,10,-3},
{23,64,88},
{-9,7,14} };

Matriz
Matriz[0]

-1

Matriz[1]

10

-3

Matriz[2]

23

64

88

Matriz[3]

-9

14

Esto define un arreglo de 2 dimensiones, el cual representa una matriz de 4 renglones por 3 columnas. Al igual que en el caso de
arreglos de una sola dimensi3n, podemos relacionar este arreglo con apuntadores. Esto se logra al considerar la matriz como: un
arreglo unidimensional de arreglos unidimensionales! Nuestro arreglo bidimensional M, en la figura, tiene 4 renglones y 3 columnas.
M es el nombre de todo el arreglo; M[0] se refiere al primer rengl3n de la matriz. M[0][0] se refiere al primer elemento de la matriz.
El compilador trata a ambos M y M[0] como arreglos, pero de tamao diferente, como se muestra con el siguiente c3digo:

printf("Tamao de Matriz\t\t=%d\n", sizeof(Matriz));


printf("Tamao de Matriz[0]\t\t=%d\n", sizeof(Matriz[0]));
printf("Tamao de Matriz[0][0]\t\t=%d\n", sizeof(Matriz[0][0]));
Al correr:

Tamao de Matriz = 24
Tamao de Matriz[0] = 6
Tamao de Matriz[0][0] = 2

El tamao de Matriz[0][0] es 2, como es de esperarse. No obstante, el tamao de Matriz es el tamao del todo el arreglo,

http://sai.uam.mx/apoyodidactico/pa/Unidad5/pauni5.html[03/03/2010 11:54:11 a.m.]

Captulo 5.

y el tamao de Matriz[0] es el tamao de un rengl3n.

Sabemos que el nombre de un arreglo unidimensional es un apuntador al primer elemento. Para una matriz es lo mismo, solo
que el primer elemento es el arreglo Matriz[0], siendo Matriz[0] un apuntador a int. Se tiene que:

Matriz equivale a &Matriz[0] y a &Matriz[0][0].

Matriz y Matriz[rengl3n] son apuntadores constantes. Entonces, Matriz es un apuntador al arreglo Matriz[0], y Matriz[0] es un
apuntador a int. Esto se puede expresar en trminos del operador de indirecci3n como:

Matriz es un apuntador a un arreglo de int.


*Matriz es un apuntador a int. Esto es evidente porque Matriz[0] es un apuntador a int, y *Matriz
Matriz[0] es un apuntador a int.
**Matrizs un int. Esto es evidente porque Matriz[0][0] es un int, y **M atriz
*(Matriz[0]+0)

Matriz[0][0] es un int.

Por otro lado, Matriz[i] es un apuntador al i-es?mo rengl3n de la matriz.

1. Pasando arreglos multidimensionales a funciones.


Tenemos el siguiente c3digo:

#include <stdio.h>
void muestra_matriz(int mat[][3]);
int main(void)
{
int M[4][3]={ {8,0,-1},
{4,10,-3},

{23,64,88},
{-9,7,14} };
muestra_matriz(M);
return (0);
}

http://sai.uam.mx/apoyodidactico/pa/Unidad5/pauni5.html[03/03/2010 11:54:11 a.m.]

*(*Matriz)

*(Matriz+0)

*(Matriz[0])

Captulo 5.

void muestra_matriz(int matriz[][3])


{
int renglon, columna;
for (renglon=0;renglon<4;++renglon) {
for (columna=0;columna<3;++columna)
printf("%d", matriz[rengl3n][columna]);
printf("\n");
}

Este programa muestra la matriz M en la pantalla. En main se declara e inicializa a M. La matriz M es pasada a la funci3n
muestra_matriz, donde es impresa. En la llamada solo se env?a el nombre de la matriz, el cual es enviado a la funci3n.

El argumento matriz es declarado como un arreglo bidimensional de enteros, pero el primer par de corchetes esta vac?o. Esto es
anlogo a cuando se env?a una arreglo unidimensional a una funci3n, y se dejan vac?os los corchetes. Sin embargo, en el caso
de una matriz el segundo par de corchetes, no debe de estar vac?o. El compilador requiere el nmero de columnas para poder
localizar adecuadamente todos los elementos de la matriz.

Anlogamente como una arreglo puede ser pasado como un apuntador a una funci3n, una matriz tambin puede serlo. Un
prototipo alterno para la funci3n muestra_matriz puede ser:

void muestra_matriz(int(*matriz)[3]);

Los parntesis son necesarios por la jerarqu?a de operadores. int (*matriz)[3] declara un apuntador a un arreglo de 3 int.

1. Arreglo de apuntadores
Considera la siguiente declaraci3n:
char *apun_cad[3] ={ "Programar",
"es",
"divertido"};
apun_cad
apun_cad[0]

"Programar"

apun_cad[1]

"es"

apun_cad[2]

"divertido"

http://sai.uam.mx/apoyodidactico/pa/Unidad5/pauni5.html[03/03/2010 11:54:11 a.m.]

Captulo 5.

Un arreglo de apuntadores es un arreglo unidimensional cuyos elementos son apuntadores. El arreglo apun_cad es un arreglo de
apuntadores. Puesto que los [] tienen mayor precedencia que el *, la declaraci3n *apun_cad[3] es equivalente a *(apun_cad[3]) en la
cual tenemos un arreglo en donde cada elemento es un apuntador a char. Analizando la declaraci3n char *(apun_cad[3]), tenemos
que:
apun_cad[3] es de tipo char *.
*(apun_cad[3]) es de tipo char.
Los elementos del arreglo apun_cad son referenciados en la manera usual como, apun_cad[0], apun_cad[1], apun_cad[2], etc. y ambos
que son apuntadores a cadenas se pueden manejar como apuntadores o como cadenas:

apun_cad[1]="Hola";
*(apun_cad[1]+1)=?I?; o apun_cad[1][1] = ?Y?;

Nota que es valida la notaci3n de matrices.

Desde que el nombre de un arreglo es un apuntador al primer elemento del arreglo, y el primer elemento de apun_cad es un apuntador,
apun_cad es un apuntador a apuntador. Desde que el nombre de un arreglo, apun_cad es una apuntador constante. Usando el operador
de indirecci3n para desreferenciar el apuntador apun_cad, tenemos.

apun_cad es un apuntador a apuntador a char.


*apun_cad es un apuntador a char. esto es evidente porque apun_cad[0] es un apuntador a char, y *apun_cad = *(apun_cad+0)
apun_cad[0] es una apuntador a char.
**apun_cad es char. esto es evidente porque apun_cad[0][0] es un char, y **apun_cad = *(*apun_cad)
apun_cad[0][0] es un char.

Recuerda que apun_cad es una apuntador constante, los operadores ++ y -- no deben ser aplicados a apun_cad.

1. Apuntadores a apuntadores
Considera lo siguiente:

char *apun_cad[3] ={ "Programar",


"es",
"divertido"};
char *apun_apun;
apun_apun=apun_cad;
apun_apun apun_cad

http://sai.uam.mx/apoyodidactico/pa/Unidad5/pauni5.html[03/03/2010 11:54:11 a.m.]

*(apun_cad[0]+0)

Captulo 5.

"Programar"

"es"

"divertido"
Podemos accesar los elementos de apun_cad, puesto que es un arreglo, pero por lo mismo no podemos incrementarlo, por que es un
apuntador constante. Por lo tanto, lo que sigues es ilegal:

for (i=0;i<3;i++)
printf("%s", apun_cad++); /* ilegal apun_cad es constante */

Sin embargo, el apuntador variable, apun_apun, se puede declarar de tal forma que se le asigne el primer elemento de apun_cad:

char **apun_apun;
apun_apun=apun_cad;

Despus de la asignaci3n, ambos apuntadores apuntan a la misma localidad de memoria, pero apun_apun si puede ser modificado.
apun_apun es un apuntador a apuntador.
. for (i=0;i<3;i++)
printf("%s", apun_apun++); /* legal apun_cad es una variable */
Analicemos la declaraci3n de apun_apun
char **apun_apun;
apun_apun es de tipo char **.
*apun_apun es de tipo char *.
**apun_apun es de tipo char.

1. Argumentos en la l?nea de comandos.

Un programa puede recibir opcionalmente los argumentos que se escriben en la l?nea de comandos.
Por ejemplo, si nuestro programa se llama letra y lo llamamos as?:
El programa est recibiendo 2 argumentos: -f y archi. Para accesarlos main( ) debe recibir un
entero ( argc ) y un apuntador a un arreglo de apuntadores a caracteres (argv). El entero es el
nmero de argumentos incluyendo el nombre del programa y el apuntador argv apunta a un arreglo
http://sai.uam.mx/apoyodidactico/pa/Unidad5/pauni5.html[03/03/2010 11:54:11 a.m.]

Captulo 5.

de apuntadores a char (al primer elemento); cada apuntador del arreglo apunta al primer carcter
de cada argumento:

argv[0]

argv[1]

argv[3]
NULL

argv /* es de tipo apuntador a apuntador a char */


argv[0] 3 *argv /* es de tipo apuntador a char */
argv[0][1] 3 **argv /* es de tipo char */

Aqu? estamos empleando el concepto de arreglo de apuntadores. Un arreglo de apuntadores se maneja como cualquier otro
arreglo; solo hay que tener mucho cuidado con los tipos. El siguiente programa suma 4 enteros:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int suma, a, b, c, d;
if(argc!=5) {
printf("Numero de argumentos invalido \n");
exit(EXIT_FAILURE);
}
a=atoi(argv[1]);
b=atoi(argv[2]);
c=atoi(argv[3]);
d=atoi(argv[4]);
suma = a + b+ c +d;
printf("La suma es : %i\n", suma);

http://sai.uam.mx/apoyodidactico/pa/Unidad5/pauni5.html[03/03/2010 11:54:11 a.m.]

Captulo 5.

return (0);
}

La funci3n atoi convierte una cadena a int.


La funci3n exit termina la ejecuci3n del programa. La macro EXIT_FAILURE indica que el programa no termino bien.

1. Asignaci3n dinmica de memoria.

Un programa en C puede almacenar informaci3n en la memoria principal de dos maneras. La primera se basa en el uso de
variables globales y locales. En el caso de las variables globales, el almacenamiento se mantiene fijo a lo largo de la
ejecuci3n del programa. Para las variables locales, el almacenamiento se asigna de la pila de la computadora. Tanto para el
almacenamiento de variables globales como de variables locales, es preciso que el programador conozca de antemano la
cantidad de espacio en memoria que necesitar en cada situaci3n.

La segunda manera de almacenar informaci3n es por medio del sistema de asignaci3n dinmica de memoria. En este
mtodo, el espacio de memoria para almacenamiento se asigna segn se necesite del rea de memoria libre mont3n,
devolvindose a la misma cuando se haya dejado de utilizar. La regi3n de memoria libre se encuentra entre el rea de
almacenamiento permanente del programa y la pila, dentro del segmento de datos.

Una ventaja de usar la asignaci3n dinmica de memoria es que la misma zona de memoria puede ser utilizada muchas veces
para almacenar datos distintos a lo largo de la ejecuci3n del programa. Esto es, en un momento dado se pueden almacenar
datos de un tipo y liberar ese espacio de memoria cuando ya no se necesiten almacenar esos datos, y a continuaci3n emplear
esa zona de memoria para almacenar otro tipo de datos.

El estndar ANSI de C define cuatro funciones para el sistema de asignaci3n dinmica de memoria: malloc(), calloc(),
free() y realloc(). Donde malloc() y free() son las funciones que constituyen el ncleo del sistema de asignaci3n dinmica
de memoria.

Las funciones definidas por el estndar ANSI requieren del archivo header stdlib.h, para poder ejecutarse.

Las principales funciones de asignaci3n dinmica de memoria, que proporciona ANSI C, se presentan a continuaci3n:

2. malloc().

http://sai.uam.mx/apoyodidactico/pa/Unidad5/pauni5.html[03/03/2010 11:54:11 a.m.]

Captulo 5.

Sintaxis:
void *malloc(size_t tam)

La funci3n malloc() regresa un apuntador a la direcci3n de la primera localidad del bloque de memoria que acaba de asignar. Este
apuntador debe ser forzado, por medio de un molde (cast), al tipo de dato para el cual se est reservando memoria, con el fin de
poder acceder correctamente a cada dato. El argumento de la funci3n especifica el nmero de bytes que se van a reservar de
memoria. Si no hay suficiente memoria para satisfacer la petici3n, malloc() regresa un apuntador nulo. Es importante que antes de
usar el apuntador se verifique que ste no es nulo, por que si se intenta usar un apuntador nulo, lo ms probable es que se produzca
la detenci3n del programa.

A continuaci3n se presenta un ejemplo que expone como se emplea esta funci3n:

#include <stdlib.h>
int *asigna_mem(void)
{
int *punt;
punt = malloc(100*sizeof(int));
if (punt==NULL){
printf("Falla en la asignaci3n de memoria. \n");
exit(EXIT_FAILURE);
}
return punt;
}

3. calloc().

Sintaxis:

http://sai.uam.mx/apoyodidactico/pa/Unidad5/pauni5.html[03/03/2010 11:54:11 a.m.]

Captulo 5.

void *calloc(size_t num, size_t tam)

La funci3n calloc() regresa un apuntador a la direcci3n de la primera localidad del bloque de memoria que acaba de asignar. Este
apuntador debe ser forzado, por medio de un molde (cast), al tipo de dato para el cual se est reservando memoria, con el fin de
poder acceder correctamente a cada dato. La cantidad de memoria que se asigna est determinada por el producto (num)(tam), donde
tam est dado en bytes y representa el tamao asociado al tipo de dato, y num es el nmero de datos que se desea almacenar. Si no
hay suficiente memoria para satisfacer la petici3n, calloc() regresa un apuntador nulo. Es importante que antes de usar el apuntador se
verifique que ste no es nulo.

El siguiente ejemplo muestra el uso de calloc():

#include <stdlib.h>
#include <stdio.h>
float *aparta_mem(void)
{
float *punt;
punt = (float *) calloc(80, sizeof(float));
if (punt==NULL){
printf("Falla en la asignaci3n de memoria.");
exit(EXIT_FAILURE);
}
return punt;
}

1. realloc()

Sintaxis:

void *realloc(void *ptr, size_t nuevotam)

http://sai.uam.mx/apoyodidactico/pa/Unidad5/pauni5.html[03/03/2010 11:54:11 a.m.]

Captulo 5.

Esta funci3n cambia el tamao de la memoria asignada. La zona de memoria asignada est apuntada por ptr, y cambia al
tamao indicado por nuevotam. El valor de nuevotam, en bytes, puede ser mayor o menor que el actual.

Esta funci3n regresa un apuntador al bloque de memoria asignado, ya que es posible que realloc() tenga que mover el bloque
de memoria para aumentar su tamao. De ocurrir esto, el contenido del bloque antiguo se copia al nuevo.

El apuntador que regresa realloc() debe ser forzado, por medio de un molde (cast), al tipo de dato para el cual se est
cambiando el tamao de memoria, con el fin de poder acceder correctamente a cada dato.

La funci3n falla si no hay suficiente memoria libre en el mont3n para asignar nuevotam bytes. Si ocurre esto, realloc()
regresa un apuntador nulo.

El siguiente ejemplo muestra como se emplea esta funci3n:


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
char *punt;
punt = (char *) malloc(17);
if (punt==NULL){
printf("Falla en la asignaci3n de memoria. \n");
exit(EXIT_FAILURE);
}
strcpy(punt, "Las quince letras");
punt = (char *) realloc(punt, 18);
if (punt==NULL){
printf("Falla en la asignaci3n de memoria. \n");
exit(EXIT_FAILURE);
}
strcat(punt, ".");
printf(punt);

http://sai.uam.mx/apoyodidactico/pa/Unidad5/pauni5.html[03/03/2010 11:54:11 a.m.]

Captulo 5.

free(punt);
return 0;
}

2. free()

Sintaxis:

void free(void *ptr)

La funci3n free() retorna al mont3n, el bloque de memoria apuntado por ptr. Esto permite que la memoria liberada se pueda
volver a asignar posteriormente.

La funci3n free() s3lo puede liberar memoria que previamente fue asignada por medio de las funciones calloc(), malloc() y
realloc(). Si se trata liberar de memoria usando un apuntador que no fue devuelto por alguna de las funciones antes
mencionadas, lo ms probable es que se destruya el sistema de gesti3n de memoria, provocando la detenci3n del sistema.

El uso de free() se muestra en el ejemplo utilizado para explicar la funci3n realloc().

3. Apuntadores a estructuras

Considera lo siguiente:

struct fecha {
int mes;
int dia;

http://sai.uam.mx/apoyodidactico/pa/Unidad5/pauni5.html[03/03/2010 11:54:11 a.m.]

Captulo 5.

int anio;
};
struct fecha hoy, *apun_fecha;

apun_fecha = &hoy;

(*apun_fecha). mes = 10; apun_fecha


(*apun_fecha).dia = 14;

apun_fecha

(*apun_fecha).anio = 95; apun_fecha

mes = 10;
dia = 14;
anio = 95;

apun_fecha hoy
10

mes

14

dia

95

anio

Hemos visto que un apuntador puede ser definido para apuntar a un tipo de dato bsico como son los int o las char, o a un
arreglo. Pero los apuntadores pueden tambin definirse para apuntar a una estructura, como se ve en la figura. En la figura se
emplea la estructura fecha definida como:

struct fecha {
int mes;
int dia;
int anio;
};

Al igual que definimos variables de tipo estructura fecha, como:

struct fecha hoy, maniana;

podemos definir una variable tipo apuntador estructura fecha:

struct fecha *apun_fecha;

http://sai.uam.mx/apoyodidactico/pa/Unidad5/pauni5.html[03/03/2010 11:54:11 a.m.]

Captulo 5.

Los apuntadores pueden emplearse de la manera usual:

apun_fecha = &hoy;

Una vez que la asignaci3n ha sido hecha, cualquier miembro de la estructura puede ser indirectamente acezada a travs de
apun_fecha como:

(*apun_fecha).mes = 10;
(*apun_fecha).dia = 14;
(*apun_fecha).anio = 95;

Se requieren los parntesis por que el operador miembro de estructura (.) Tiene mayor precedencia que el operador de
indirecci3n (*). Los apuntadores a estructuras son muy a menudo usados en C, por esa raz3n existe un operador especial
para accesar indirectamente los miembros de unas estructura. Este es el operador a estructura,. Por lo tanto, las asignaciones
anteriores pueden codificarse como:

apun_fecha

mes = 10;

apun_fecha

dia = 14;

apun_fecha

anio = 95;

Lo cual es mas corto y fcil de leer.

A continuaci3n un programa de ejemplo de apuntadores a estructuras. Este programa lee una lista de empleados y la imprime.
El tamao del arreglo se determina dinmicamente usando la funci3n calloc. La macro Resetea_entrada elimina caracteres
nueva l?nea extras.

#include <stdlib.h>
#include <stdio.h>
#define Resetea_entrada while(getchar()!=?\n?)
typedef struct {
char nombre[20];
int edad;
float sal_men;

http://sai.uam.mx/apoyodidactico/pa/Unidad5/pauni5.html[03/03/2010 11:54:11 a.m.]

Captulo 5.

} persona;
void lee_emp(persona *apun_emp)
int main(int argc,char *argv[])
{
persona *empleados;
int num_de_emp;,i;
if (argc == 2) {
num_de_emp = atoi(argv[1]);
if((empleados = persona)calloc(num_de_emp,sizeof(persona)))==NULL) {
printf("Ya no hay memoria\a\n");
exit(EXIT_FAILURE);
}
for(i=0;i<num_de_emp;++i)
lee_emp(&empleados[i]);
printf("\n");
for(i=0;i<num_de_emp;++i)
printf ("Empleado #%i:\n"\
" Nombre: %s:\n"\
" Edad: %d:\n"\
" Salario: %.2f\n",i+i,empleados[i].nombre,
empleados[i].edad,empleados[i].men_sal);
}
else
printf("Usario: %s num_de_empleados\n",argv[0]);
return(0);
}
void lee_emp(persona *apun_emp)
{
printf("Nombre del empleado: ");
gets(apun_emp

nombre);

printf("Edad del empleado: ");


scanf("%i",&apun_emp

edad);

http://sai.uam.mx/apoyodidactico/pa/Unidad5/pauni5.html[03/03/2010 11:54:11 a.m.]

Captulo 5.

Resetea_entrada;
printf("Salario del empleado: ");
scanf("%f",&apun_emp

men_sal);

Resetea_entrada;
}

4. Apuntadores a funciones.

Un uso ms avanzado de los apuntadores son los apuntadores a funciones. Desde que las funciones
ocupan un rea de memoria, C puede definir un apuntador a ellas. Los apuntadores a funciones se
emplean por 2 razones. Primero una funci3n no puede ser pasada a otra funci3n como un
argumento, pero un apuntador si. Segundo, una funci3n no se puede almacenar en un arreglo o una
estructura, pero un apuntador si puede serlo. Una funci3n puede llamarse por medio de un apuntador
que apunta a ella. As?, varias funciones pueden llamarse usando la misma instrucci3n de llamado.
En el siguiente ejemplo, apun_fun es un apuntador a una funci3n divide, la cual regresa un flotante y
que requiere 2 argumentos enteros. Este apuntador se inicializa igualndolo al nombre de cualquier
funci3n que regrese un entero. As? como el nombre de un arreglo es un apuntador constante al
primer elemento, el nombre de una funci3n es un apuntador constante que apunta al c3digo
ejecutable de la funci3n. Esta vez, main usa un apuntador a funci3n para llamar a la funci3n
divide.

#include <stdio.h>
float divide(int,int);
int main(void)
{
float (*apun_fun)(int,int);
float respuesta;
apun_fun=divide;
respuesta = (*apun_fun)(3,2);
printf("respuesta=%.1f\n",respuesta);
return (0);
}
float divide(int op1,int op2)
http://sai.uam.mx/apoyodidactico/pa/Unidad5/pauni5.html[03/03/2010 11:54:11 a.m.]

Captulo 5.

{
float resultado;
resultado = (float)op1/(float)op2;
return (resultado);
}

Cuando trabajamos con apuntadores a funciones, el ANSI C requiere conocer el tipo de valor regresa
la funci3n, as? como el numero y tipos de parmetros que requiere. Para declarar la variable
apun_fun para ser del tipo "un apuntador a una funci3n que regresa un float y que requiere dos
argumentos de tipo int", se usa la declaraci3n:

float (*apun_fun)(int,int);.
Los parntesis en torno a *apun_fun son requeridos porque el operador de llamada (), tiene mayor
precedencia que el operador de indirecci3n *, y *apun_fun() podr?a ser interpretado por el
compilador como *(apun_fun()), la cual es una funci3n llamada apun_fun la que regresa un
apuntador.

El ejemplo anterior muestra como usar apuntadores a funci3n, pero no da una ventaja con respecto a
la manera usual de llamada funciones. Un uso apropiado de loas apuntadores a funci3n los tenemos
en la implantaci3n de mens. Dado que se puede definir un arreglo de apuntadores a funciones, es
viable usar este ltimo para crear un men. El arreglo mapea las opciones del usuario con la
ejecuci3n de los comandos. En este arreglo se puede buscar y ejecutar la opci3n ms rpido que
con un switch o un if. A continuaci3n te damos un ejemplo de ello.

Una estructura llamada comando se define para que contenga 2 miembros, un apuntador al nombre del
comando, y un apuntador a la funci3n correspondiente que se llama:

struct cmd {
char *nombre_cmd;
int (*apun_fun)();
}

Un vector, donde cada elemento es del tipo estructura comando, puede ser inicializado para que
contenga todos los nombres de los comandos y los correspondientes nombres de las funciones:

struct cmd tabla[]={ {"sumar",sumaritem},

http://sai.uam.mx/apoyodidactico/pa/Unidad5/pauni5.html[03/03/2010 11:54:11 a.m.]

Captulo 5.

{"borrar",borraritem},
{"listar",listaritem},
{"salir",terminar} };

Cuando se escribe el nombre del comando por parte del usuario, en la tabla se puede buscar, y la
funcin apropiada puede ser llamada, como sigue:

typedef enum {FALSO,CIERTO} bool;


char comando[10]; /*comando dado por el usuario */
int num_de_cmd: /* total de numero de comandos en la tabla */
bool cmd_no_hallado = CIERTO;
prinf("Dar comando: ");
gets(comando);
for (i=0;((i<num_de_cmd) && (cmd_no_hallado));++i) {
if (!strcmp(comando,tabla[i].monbre_cmd)) {
resultado = (*tabla[i].apun_fun)(); /* ejecutar funci3n */
cmd_no_hallado = FALSO;
}
}

http://sai.uam.mx/apoyodidactico/pa/Unidad5/pauni5.html[03/03/2010 11:54:11 a.m.]

También podría gustarte