Está en la página 1de 30

JAIRO ENRIQUE MARTINEZ BANDA

Punteros como parámetros de


función

1. Paso por referencia

Los parámetros de funciones son variables locales a la función inicializados


con valores en el momento de la llamada a la propia función. Cuando se pasa
una tabla por parámetro, el parámetro es un puntero que toma por valor la
dirección del primer elemento, que es al mismo tiempo la dirección del
bloque de memoria de la tabla. Esta sección tiene como objetivo estudiar el
paso de direcciones de memoria de cualquier tipo de variable, y no solamente
de tablas. Es lo que se llama un «paso por referencia» y se trata de la
referencia a una variable mediante su dirección de memoria. También
detallamos algunos aspectos más específicos relativos al paso de tablas por
parámetro.

a. Caso general de una variable cualquiera

La función modif() tiene un parámetro al que se le asigna el valor 50:

void modif(int e1)


{

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA -1-
JAIRO ENRIQUE MARTINEZ BANDA

e1=50;
}

en el main(), una variable v se inicializa con el valor 10. Se llama a la función


modif() y el valor de v se asigna a su parámetro. El programa es el siguiente:

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

int main()
{
int v=10;
modif(v);
printf("v=%d \n", v);
return 0;
}

¿Qué imprime la función printf()?

… La variable v, local al contexto de la llamada, vale siempre 10.

El parámetro de la función es otra variable, local a la función, a la que se le


asigna un valor en el momento de la llamada. Todas las modificaciones
realizadas a esta variable local a la función modifican únicamente esta
misma variable.

En C, el paso de parámetros se realiza siempre por valor y es únicamente el


valor de las variables lo que se asigna a los

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA -2-
JAIRO ENRIQUE MARTINEZ BANDA

parámetros de las funciones. No es la variable en sí misma lo que pasa a ser


el parámetro de la función.

Sin embargo, si se utiliza un puntero como parámetro de función y se pasa


como valor para el parámetro la dirección de memoria de la variable, es
posible modificar el valor de esta variable pasando su dirección de memoria.
Es un paso por referencia. Por ejemplo:

void modif( int *x)


{
*x=50;
}

La función modif() tiene ahora como parámetro un puntero a entero.


Utilizando el operador * (asterisco), la función modif() va a poder escribir en
la dirección de memoria que se le ha pasado por parámetro en el momento
de la llamada. El programa quedaría de la siguiente manera:

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

int main()
{
int v=10;

printf( "v=%d",v); // v vale 10

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA -3-
JAIRO ENRIQUE MARTINEZ BANDA

modif_( &v ); // paso de la direccin de v al parÆmetro x


printf( "v=%d",v); // v ahora vale 50
return 0;
}

b. Ejemplo: una función que devuelve la hora

El return permite el retorno de un solo valor, lo que no es siempre suficiente y


puede complicar la escritura de funciones. Lo interesante del paso por
referencia es poder transformar parámetros de entrada en parámetros de
salida. Hay, por lo tanto, tantas salidas como se necesiten. A continuación se
muestra como ejemplo una función que devuelve el tiempo en horas, minutos
y segundos.

El tiempo universal se obtiene de la función:

time_t time(time_t*tmp) ;

Esta función devuelve el valor del tiempo según una codificación interna al
sistema, o -1 si es imposible obtenerlo. Este valor también se copia a la
dirección del parámetro, excepto si este es NULL. Este tiempo interno al
sistema debe convertirse, por ejemplo, con la función:

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA -4-
JAIRO ENRIQUE MARTINEZ BANDA

struct tm* localtime(const time_t*tu)

Esta función convierte el valor de tiempo interno, obtenido con time(), a un


formato de tiempo llamado tiempo externo y descrito por la tupla tm
presentada a continuación. El tiempo interno se pasa en el primer parámetro
y la dirección de la tupla tm asignada dinámicamente, y correctamente
inicializada, se devuelve. Una tupla tm incluye:

struct tm{

int tm_year; // nœmero de aæos transcurridos desde 1900


int tm_mon; // nœmero de meses transcurridos desde el inicio
// del aæo
int tm_mday; // da del mes de 1 a 31
int tm_yday; // da del aæo de 0 a 365
int tm_hour; // horas desde el inicio del da de 0 a 23
int tm_min; // minutos de 0 a 59 desde el inicio
//de la hora actual
int tm_sec; // segundos desde el inicio del minuto actual
//de 0 a 59
};

Ahora podemos escribir nuestra función para tener la hora:

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA -5-
JAIRO ENRIQUE MARTINEZ BANDA

void hms(int *h, int *m, int*s)


{
time_t tu; // para obtener el tiempo universal (interno)
struct tm *p; // para obtener el tiempo en formato legible

time(&tu); // paso por referencia de la variable tu


p = localtime(&tu);// paso por referencia de tu solo para lectura
// pero retorno de la direccin de una tupla
// obtenida dinÆmicamente en la funcin

*h = p->tm_hour; // escritura de la hora en la direccin de h


*m = p->tm_min; // escritura de los minutos en la direccin de m
*s = p->tm_sec; // escritura de los segundos en la direccin de s
}

y podemos probarla en un main():

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

int main()
{
int h, m, s;

hms(&h, &m, &s);


printf("%d : %d : %d\n"
,h,m,s);

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA -6-
JAIRO ENRIQUE MARTINEZ BANDA

return 0;
}

c. Paso por referencia de una tupla

Sea la tupla t_trol:

typedef struct trol{


int x,y;
int color;

}t_trol;

Se puede tener una función de inicialización con un puntero de tipo t_trol*


como parámetro:

void init(t_trol*p)
{
p->x=rand()%800;
p->y=rand()%600;
p->color=rand()%256;
}

Y en alguna parte, la llamada:

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA -7-
JAIRO ENRIQUE MARTINEZ BANDA

t_trol t;
init(&t); // paso de la direccin de la struct t_trol

En el caso de la tabla de punteros, no hay que olvidar asignar los punteros. En


efecto, si se escribe por ejemplo:

t_trol* ALL[10];
int i;
for (i=0; i<10; i++){
init(ALL[i]); // ¡ERROR! ALL[i] NO ASIGNADO
}

provoca un error de ejecución, ALL[i] no tiene una dirección de memoria


reservada. Por lo tanto, hay que añadir previamente la asignación de memoria
(sea en el mismo sitio, o en cualquier otra parte en el programa):

for (i=0; i<10; i++){


ALL[i]=(t_trol*)malloc(sizeof(t_trol));
init(ALL[i]); // OK, ALL[i] ASIGNADO
}

d. Paso por referencia de una variable puntero

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA -8-
JAIRO ENRIQUE MARTINEZ BANDA

El puntero es una variable como cualquier otra y, como tal, se puede pasar un
puntero por referencia, es decir, se puede pasar como valor del parámetro la
dirección de una variable puntero. La dirección de una variable puntero es un
puntero... de puntero. A continuación se muestra un ejemplo de una función
de asignación de memoria dinámica para una tabla de float que no utiliza el
sistema de retorno:

void asigna_mem(float**f,int tam)


{
*f=(float*)malloc(sizeof(float)*tam);
}

y la llamada en un main():

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

int main()
{
float*tab;
int i;
asigna_mem(&tab,10);
for (i=0; i<10; i++){
tab[i]= (rand()%10000)/100.0;
printf("%f ",tab[i]);
}

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA -9-
JAIRO ENRIQUE MARTINEZ BANDA

putchar(\n);

return 0;
}

Son exactamente las mismas operaciones que para todas las variables,
excepto que la variable en cuestión es un puntero y se usa a continuación
como puntero. De este modo, en la función asigna_mem(), la expresión *f es
de tipo float*, lo que permite una asignación dinámica de una tabla de float.

Otro ejemplo: queremos una función de asignación de memoria para


matrices de enteros que no use el mecanismo de retorno. Una matriz es un
puntero a punteros a int (int**) y la dirección de un puntero a punteros es un
puntero... a punteros a punteros, un int***:

void asigna_mem(int***m,int t1, int t2)


{
int i;
*m=(int**)malloc(sizeof(int*)*t1);
for (i=0; i<t1; i++)
(*m)[i]=(int*)malloc(sizeof(int)*t2);
}

¡Atención! Los paréntesis (*mat)[i] son necesarios

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 10 -
JAIRO ENRIQUE MARTINEZ BANDA

porque el operador corchetes [ ] es prioritario sobre el operador


asterisco *. Sin paréntesis *mat[i] se interpreta como *(mat[i]).

Para comprobar la asignación dinámica realizada, a continuación se muestra


una función de inicialización y una función de visualización:

void inicializa(int**mat, int t1, int t2)


{
int i, j;
for (i=0; i<t1; i++)
for (j=0; j<t2; j++)
mat[i][j]=rand()%100;
}

void muestra(int**mat, int t1, int t2)


{
int i, j;
for (i=0; i<t1; i++){
for (j=0; j<t2; j++)
printf("%3d",mat[i][j]);
putchar(\n);
}
}

y las llamadas en un main():

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 11 -
JAIRO ENRIQUE MARTINEZ BANDA

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

int main()
{
int**mat;

asigna_mem(&mat,,
5 10); // direccin de mat pasada por referencia
inicializa(mat,,
5 10); // valor de mat (direccin de la matriz)
muestra(mat,,
5 10);
return 0;
}

Último ejemplo, retomemos nuestra tupla t_trol:

typedef struct trol{


int x,y;
int color;

}t_trol;

y modifiquemos la inicialización de forma que integremos la asignación de


memoria del puntero pasando el puntero por referencia:

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 12 -
JAIRO ENRIQUE MARTINEZ BANDA

void inicializa(t_trol**p)
{
*p=(t_trol*)malloc(sizeof(t_trol));
(*p)->x=rand()%800;
(*p)->y=rand()%600;
(*p)->color=rand()%256;
}

La expresión *p es de tipo t_trol* y los paréntesis son necesarios alrededor de


*p porque la flecha es prioritaria sobre el asterisco. Sin paréntesis:

*p->x es equivalente a *(p->x)

lo que supone que el campo x es de tipo puntero (y atención al error si es


realmente el caso).

La inicialización de una tabla de punteros t_trol* puede ser objeto de una


función aparte:

void inicializacin(t_trol* t[])


{
int i;
for (i=0; i<NUMMAX; i++)
inicializa(&t[i]); // paso de la direccin del puntero i en

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 13 -
JAIRO ENRIQUE MARTINEZ BANDA

// la tabla
}

A continuación se muestra el programa completo:

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

#define NUMMAX 100


typedef struct trol{
int x,y;
int color;

}t_trol;

void inicializa(t_trol**p)
{
*p=(t_trol*)malloc(sizeof(t_trol));
(*p)->x=rand()%800;
(*p)->y=rand()%600;
(*p)->color=rand()%256;
}

void inicializacin(t_trol* t[])


{
int i;
for (i=0; i<NUMMAX; i++)
init(&t[i]);

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 14 -
JAIRO ENRIQUE MARTINEZ BANDA

void muestra(t_trol*t[])
{
int i;
for (i =0; i<NUMMAX; i++){
printf("%4d %4d %4d\n"
,t[i]->x,t[i]->y,t[i]->color);
}
}
int main()
{
t_trol* ALL[NUMMAX];

inicializa(ALL);
muestra(ALL);
return 0;
}

2. Tablas dinámicas por parámetro

En el caso de una tabla estática como parámetro de función, solo la primera


dimensión de la tabla se convertía a puntero. Por ejemplo, si se trata de una
matriz de enteros, una tabla de dos dimensiones, la matriz se convertía en
puntero de tablas de enteros y, por esta razón, el tamaño de la segunda
dimensión debía especificarse. Este funcionamiento es idéntico sea cual sea
el número de dimensiones de la tabla estática que figura como parámetro de
la función: solo la

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 15 -
JAIRO ENRIQUE MARTINEZ BANDA

primera dimensión se convierte a puntero y el resto de las dimensiones son el


tipo del puntero; sus tamaños deben especificarse.

A continuación se muestra una pequeña prueba para ver las compatibilidades


e incompatibilidades entre tres formas de tablas bastante parecidas, aunque
diferentes:

#define TY 3 // nœmero de filas


#define TX 8 // nœmero de columnas

char mat1[TY][TX]; // matriz estÆtica de char


char*mat2[TY]; // tabla estÆtica de punteros de char
char**mat3; // matriz dinÆmica de char O
// tabla dinÆmica de punteros a char

Escribir tres funciones idénticas de visualización con cada tabla distinta por
parámetro:

void test1 ( char**tab )


void test2 ( char* tab
[ ] )
void test3 ( char tab
[ ][TX] )

/* contenido de las tres:


{

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 16 -
JAIRO ENRIQUE MARTINEZ BANDA

int x,y;
putchar(\n);
for (y=0;y<TY;y++){
putchar(\t);
for (x=0; x<TX; x++)
putchar(tab[y][x]);
putchar(\n);
}
putchar(\n);
}

¿Cómo se comporta la función test1 con los parámetros mat1, mat2 y mat3?

¿Cómo se comporta la función test2 con los parámetros mat1, mat2 y mat3?

¿Cómo se comporta la función test3 con los parámetros mat1, mat2 y mat3?

Obtenemos las compatibilidades e incompatibilidades siguientes:

Tipos pasados Tipos de parámetros


por parámetro

(char**tab) (char* tab[ ]) (char tab[ ][TX])

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 17 -
JAIRO ENRIQUE MARTINEZ BANDA

char mat1[TY] NO NO OK
[TX]

char*mat2[TY] OK OK NO

char**mat3 OK OK NO

El siguiente programa permite comprobarlo:

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

int main(int argc, char *argv[])


{
// declaraciones de las tablas
char mat1[TY][TX];
char*mat2[TY];
char**mat3;
int y,x;

// las tablas se asignan memoria si fuera necesario y se inicializan


// con los mismos valores
for (y=0; y<TY; y++)
for (x=0; x<TX; x++)
mat1[y][x]= 0+x;

for (y=0; y<TY; y++){

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 18 -
JAIRO ENRIQUE MARTINEZ BANDA

mat2[y]=(char*)malloc(sizeof(char)*TX);
for (x=0; x<TX; x++)
mat2[y][x]= 0+x;
}

mat3=(char**)malloc(sizeof(char*)*TY);
for (y=0;y<TY;y++){
mat3[y]=(char*)malloc(sizeof(char)*TX);
for (x=0; x<TX; x++)
mat3[y][x]= 0+x;
}

// primera serie de pruebas con mat1 como parÆmetro para cada funcin
printf("TEST 1 Paso de: char mat1[TY][TX] \n\n"
);

printf("llamada de la funcin f(char**tab) : "


"Warning y cuelgue\n"
);
//test1(mat1);
putchar(\n);
printf("llamada de la funcin f(char* tab[]) : "
"Warning y cuelgue\n"
);
// test2(mat1);
putchar(\n);
printf("llamada de la funcin f(char tab[][TX]): ok\n"
);
test3(mat1);

// serie 2 con mat2


printf("TEST 2 Paso de: char *mat2[TY] \n\n"
);
printf("llamada de la funcin f(char**tab) : ok\n"
);
test1(mat2);

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 19 -
JAIRO ENRIQUE MARTINEZ BANDA

printf("llamada de la funcin f(char* tab[]) : ok\n"


);
test2(mat2);
printf("llamada de la funcin f(char tab[][TX]) : "
"Warning y resultados inesperados\n\n"
);
test3(mat2);

// serie 3 con mat3


printf("TEST 3 Paso de: char**mat3 \n\n");
printf("llamada de la funcin f(char**tab) : ok\n"
);
test1(mat3);
printf("llamada de la funcin f(char* tab[]) : ok\n"
);
test2(mat3);
printf("llamada de la funcin f(char tab[][TX]): "
"Warning y resultados inesperados\n\n"
);
test3(mat3);
return 0;
}

3. Puesta en práctica: paso por referencia

a. Paso por referencia, conocimientos básicos

Ejercicio 1

En un programa, una función inicializa dos enteros y un real con valores


aleatorios. Otra función muestra los valores obtenidos. El programa finaliza si
lo solicita el usuario.

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 20 -
JAIRO ENRIQUE MARTINEZ BANDA

Ejercicio 2

En un programa, una función devuelve el cociente y el resto de la división de


un entero p entre un entero q; p y q se obtienen o bien de forma aleatoria o
bien los entra el usuario. El programa finaliza si lo solicita el usuario.

Ejercicio 3

En una función, los valores de dos variables pasadas por referencia se


intercambian. Escribir un programa con:

ˇ
Introducción de valores y visualización.
ˇ
Intercambio de valores.
ˇ
Visualización del resultado.
ˇ
Salir o volver a empezar.

Ejercicio 4

Sea una tupla que incluya una posición (número real), un desplazamiento
(número real), una letra (entero) y un color (entero). En un programa:

ˇ
Definir un tipo y declarar dos tuplas.
ˇ
Escribir una función que permite inicializar dos tuplas en una sola
llamada (las tuplas se pasan por referencia).
ˇ
Escribir una función que permita intercambiar los contenidos de
ambas tuplas.
ˇ
Salir o volver a empezar.

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 21 -
JAIRO ENRIQUE MARTINEZ BANDA

Ejercicio 5

En un programa:

ˇ
Escribir una función de asignación dinámica de memoria para una
tabla de n enteros (el tamaño se obtiene o bien por el usuario o bien
de forma aleatoria).
ˇ
Escribir una función de inicialización con valores comprendidos entre
un valor umbral bajo y un valor umbral alto proporcionados como
parámetros de la función.
ˇ
Escribir una función de obtención de los valores umbral (bajo y alto).
ˇ
Escribir una función de visualización de una tabla de n elementos.
ˇ
Escribir una función que permita al contexto de la llamada determinar
los valores máximo y mínimo de una tabla de enteros de tamaño n
pasada por parámetro. La función no devuelve nada. Los valores
deben poder obtenerse en el contexto de la llamada sin uso de
variables globales.

Comprobar en un programa que se detenga cuando el usuario lo solicite.

b. Paso por referencia, operadores bit a bit

Ejercicio 6

Realizar en C una librería para programar microcontroladores. A continuación,


algunas de las funciones que se deben escribir:

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 22 -
JAIRO ENRIQUE MARTINEZ BANDA

bit_clear() Sintaxis: bit_clear(var,bit)

Tarea: poner a 0 el bit "bit" de la variable "var"

Ejemplo: bit_clear(a, 3); // pone a 0 el bit 3 de a

bit_set() Sintaxis: bit_set(var, bit)

Tarea: poner a 1 el bit "bit" de la variable "var"

Ejemplo: bit_set(a,5); // pone a 1 el bit 5 de a

bit_test() Sintaxis: bit_test(var, bit)

Tarea: prueba el estado del bit "bit" de la variable


"var"

Ejemplo: a=2;

bit_test(a, 2); // devuelve 1, bit 2 de a igual a 1

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 23 -
JAIRO ENRIQUE MARTINEZ BANDA

get_bytet() Sintaxis: get_byte(var,b)

Tarea: devuelve el valor del byte "b" de la variable


"var"

Ejemplo: a=0xFF00;

get_oct(a,2); // devuelve 255

set_byte() Sintaxis: set_byte(var,b,val)

Tarea: asigna "val" al byte "b" de la variable "var"

Ejemplo: a=0 ;

set_oct(&a,0,0xF); // asigna el valor decimal 15 al


byte 0 de a

set_high() Sintaxis: set_high(var,b)

Tarea: pone a 1 los bits del byte "b" de la variable


"var"

Ejemplo: a=0

set_high(&a,3); // pone a 1 los 8 bits del œltimo


byte de a

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 24 -
JAIRO ENRIQUE MARTINEZ BANDA

set_low() Sintaxis: set_low(var,b)

Tarea: pone a 0 los bits del byte "b" de la variable


"var"

Ejemplo: a=7654

set_low(&a,0); // pone a 0 los 8 bits del primer


byte de a

rotate_left() Sintaxis: rotate_left(var,b,n)

Tarea: rotacin izquierda de n posiciones del byte


"b"

Ejemplo: a=512;

rotate_left(&a,2,3); // rota tres bits a la


izquierda el byte 2 de a

rotate_right() Sintaxis: rotate_right(var,b,n)

Tarea: rotacin derecha de n posiciones del byte "b"

Ejemplo: a=512;

rotate_right(&a,2,3); // rota tres bits a la


derecha el byte 2 de a

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 25 -
JAIRO ENRIQUE MARTINEZ BANDA

c. Paso de punteros por referencia

Ejercicio 7

En un programa, en el bucle principal:

ˇ
Los tamaños de una tabla de float y el tamaño de una tabla de
enteros se determinan al azar.
ˇ
Una función asigna memoria dinámicamente a las dos tablas a la
vez.
ˇ
Una función inicializa ambas tablas.
ˇ
Una función muestra ambas tablas.
ˇ
Salir o volver a empezar. Atención a la memoria.

Ejercicio 8

En un programa:

ˇ
El usuario entra el tamaño de una matriz.
ˇ
La matriz se asigna dinámicamente en un procedimiento (sin
retorno).
ˇ
Una función inicializa la matriz con valores.
ˇ
Una función muestra la matriz.
ˇ
Salir o volver a empezar. Atención a la memoria.

Ejercicio 9

En un programa, cuatro cadenas de caracteres se declaran de la siguiente


forma:

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 26 -
JAIRO ENRIQUE MARTINEZ BANDA

char*s1,*s2,*s3,*s4;

ˇ
Una función permite introducir las cuatro cadenas a la vez.
ˇ
Una función permite visualizarlas una por una.
ˇ
Salir o volver a comenzar.

Ejercicio 10

En un juego hay trols con una posición (x,y) y un color.

ˇ
Definir una tupla t_trol (ver en este capítulo - secciones Principios de
un puntero - Caso de las tablas de punteros y Punteros como
parámetros de función - Paso por referencia de una tupla, para
typedef).
ˇ
Escribir una función de asignación de memoria dinámica para una
tabla de t_trol de 5 dimensiones con uso de return.
ˇ
Escribir una función de asignación de memoria dinámica para una
tabla de t_trol de 5 dimensiones sin uso de return.

A continuación, siempre sin return, descomponer la asignación de memoria


escribiendo una función para cada dimensión (para cada nueva dimensión
llamar a la función de la dimensión anterior, como una especie de cascada).

ˇ
Escribir una función que asigne memoria dinámicamente a una tabla
de una dimensión de t_trol cuyo tamaño viene dado por parámetro.
ˇ
Escribir una función que asigne memoria dinámicamente a una tabla
de dos dimensiones cuyos tamaños vienen dados

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 27 -
JAIRO ENRIQUE MARTINEZ BANDA

por parámetro.
ˇ
Escribir una función que asigne memoria dinámicamente a una tabla
de tres dimensiones cuyos tamaños vienen dados por parámetro.
ˇ
Escribir una función que asigne memoria dinámicamente a una tabla
de cuatro dimensiones cuyos tamaños vienen dados por parámetro.
ˇ
Escribir una función que asigne memoria dinámicamente a una tabla
de cinco dimensiones cuyos tamaños vienen dados por parámetro.

En un main, dar un ejemplo de llamada que permita crear una tabla de t_trol
de 5 dimensiones cada una de ellas entrada por el usuario. Probar los
programas y añadir inicialización y visualización.

d. Paso de tablas dinámicas

Ejercicio 11

En un programa, se declara una tabla dinámica:

int *tab;

A partir de estos prototipos:

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 28 -
JAIRO ENRIQUE MARTINEZ BANDA

void asigna_mem1 (int**t, int tam);


void asigna_mem2 (int tam);
int* asigna_mem3 (int tam);
void inicializa1 (int t[], int tam);
void inicializa2 (int**t);
void inicializa3 (int*t);
int* inicializa4 (void);

¿Qué funciones pueden usar tab como argumento? Escribir las funciones
designadas como válidas y realizar un programa de prueba. Dar las razones
por las que las otras han sido rechazadas.

Ejercicio 12

En un programa, se declara una matriz dinámica:

int **mat;

A partir de estos prototipos:

void asigna_mem1 (int***m, int fil, int col);


int** asigna_mem2 (int fil, int col);
int* asigna_mem3 (int*m[],int fil,int col);
void inicializa1 (int m[][]);
void inicializa2 (int**m, int fil, int col);
void inicializa3 (int*t, int fil);
int** inicializa4 (void);

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 29 -
JAIRO ENRIQUE MARTINEZ BANDA

¿Qué funciones pueden usar tab como argumento? Escribir las funciones
designadas como válidas y realizar un programa de prueba. Dar las razones
por las que las otras han sido rechazadas.

© Éditions ENI - Todos los derechos reservados - Copia personal de JAIRO ENRIQUE MARTINEZ BANDA - 30 -

También podría gustarte