Está en la página 1de 32

INFORMÁTICA II – GRADO EN MATEMÁTICAS

Tema I.- Gestión de memoria -1-

PUNTEROS
Concepto de puntero ................................................................................................................................................ 2
Acceso desde un puntero a su variable apuntada ................................................................................................... 3
Iniciación de un puntero a NULL ........................................................................................................................... 4
Operaciones con punteros ....................................................................................................................................... 5
Constante puntero y puntero a constante ............................................................................................................... 7
Prioridad de los operadores *, ++ y -- sobre el mismo puntero.............................................................................. 7
Punteros y arrays ..................................................................................................................................................... 9
Punteros y vectores ............................................................................................................................................... 9
0022FFEE ............................................................................................................................................................... 9
Vectores de punteros y punteros a vectores ........................................................................................................ 11
Punteros y cadenas de caracteres....................................................................................................................... 11
Punteros y tablas................................................................................................................................................. 12
0022FFDE ............................................................................................................................................................. 12
Ejercicios resueltos ................................................................................................................................................ 14
Ejercicio 1.- Mapa de memoria .......................................................................................................................... 14
Ejercicio 2.- Tabla de direcciones de memoria .................................................................................................. 15
Ejercicio 3.- Recorrido vector con notación punteros ........................................................................................ 16
Ejercicio 4.- Recorrido tabla con notación punteros ......................................................................................... 18
Ejercicio 5.- Lectura elementos vector con notación punteros .......................................................................... 20
Ejercicio 6.- Lectura elementos tabla con notación punteros ............................................................................ 21
Programas complementarios ................................................................................................................................. 22
Ejercicios propuestos ............................................................................................................................................. 23
Ejercicio 7.- Acceder a una variable mediante un puntero ................................................................................ 23
Ejercicio 8.- Ordenar vector de claves sin modificarlo ...................................................................................... 24
Ejercicio 9.- Mapa de caracteres........................................................................................................................ 27
Ejercicio 10.- Recorrido de arrays con notación puntero .................................................................................. 27
Ejercicio 11.- Manejo de una cadena con un puntero a char ............................................................................ 29
Ejercicio 12.- Submatrices simétricas ................................................................................................................ 29
Ejercicio 13.- Rotar una matriz con punteros .................................................................................................... 31

Nota: El tamaño del tipo int y del tipo puntero depende de la plataforma y del compilador. Valores típicos son 2
bytes en entornos MS-DOS y 4 bytes para entorno Windows ó Linux. En los ejemplos de este trma, salvo que se
indique explícitamente lo contrario, se está suponiendo la ocupación del tipo int y del tipo puntero de 4 bytes.
De todas formas, son fácilmente adaptables todos los ejemplos al caso de compiladores con el tipo int y tipo
puntero de 2 bytes.

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria -2-

Concepto de puntero
Cuando una variable se declara, se asocian tres atributos fundamentales a la misma:
− Su nombre
− Su tipo
− Sus direcciones en memoria
Al valor o contenido de una variable se accederá normalmente a través de su nombre. Pero,
como veremos más adelante, también podrá accederse al contenido de la misma si conocemos
su dirección de comienzo en memoria

¿Cómo obtener la dirección de comienzo de una variable en memoria?


La dirección de comienzo de una variable en memoria es un entero sin signo, y puede
obtenerse a través del operador dirección &. Puede además imprimirse en hexadecimal
mediante el especificador de formato %p.

Por tanto, de una variable podremos...


− Acceder al valor que contiene, con nombrevariable
− Acceder a la dirección de comienzo en memoria donde está definida, con
&nombrevariable

A las constantes y expresiones no puede aplicarse el operador dirección (&), sólo a las
variables.

¿Dónde almacenar la dirección de una variable?


Los punteros1 son variables que contendrán un valor que es una dirección de memoria.
En el caso de que esta dirección sea la dirección de comienzo de otra variable declarada en
el programa se dice que el puntero “apunta” o “referencia” a esa variable.
Para declarar una variable puntero se debe indicar el tipo de dato de las variables a las que va
a apuntar. El motivo es que los distintos tipos de datos requieren diferentes cantidades de
memoria para almacenar sus variables. Un puntero sólo almacena la dirección de comienzo
de la variable a la que apunta, pero a través de la declaración del puntero, el compilador
conocerá, a partir de ésta dirección, cuantas más forman la variable a la que referencia.
En la definición de una variable puntero, se hace preceder al nombre de la variable puntero de
un asterisco (*).
tipo_dato_apuntado *nombrepuntero;
Ejemplo,
float f = 123.456; /* Define e inicia una variable float */
float *punt; /* Define un puntero a float */
...
punt = &f; /* asigna la dirección de comienzo en memoria de la
variable f a la variable puntero punt, por tanto
el puntero punt apunta a la variable f */

1
Por supuesto que como los punteros son a su vez variables, están almacenados en algún lugar de la memoria y
tienen su propia dirección

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria -3-

Nombre Dirección
variable comienzo

123.456
f 0022FF44 Direcciones
de memoria
crecientes

0022FF4
punt 0022FF14 4

Esquema 1. Ejemplo gráfico de una variable puntero

Un puntero es una verdadera variable, por lo tanto puede cambiar de valor, es decir, después
de haber asignado una dirección a un puntero, durante la ejecución del programa se le puede
volver a asignar la dirección de otra variable, apuntando por tanto a esa nueva variable y
abandonando la anterior. Pero siempre debe mantenerse la condición de que el tipo de dato de
la variable que se va a apuntar sea del mismo tipo que el del puntero. En caso contrario puede
haber pérdida de información sin que el compilador emita ningún mensaje de error.

¿Cuánto ocupa en memoria una variable puntero?


Un puntero sólo almacena la dirección de comienzo de la variable a la que apunta,
independientemente del tipo de ésta, por tanto una variable puntero ocupará en memoria 2
ó 4 bytes2, es decir, el espacio suficiente para almacenar una dirección de memoria.

Acceso desde un puntero a su variable apuntada


El uso de un puntero para obtener el valor de la variable a la que apunta, es decir, el dato
apuntado, se denomina indirección. Para ello debe de utilizarse el operador indirección
sobre el puntero, el cual permite acceder a la variable cuya dirección está contenida en dicho
puntero. En C este operador lo representa el símbolo asterisco (*).

• Con el nombre de la variable puntero (nombrepuntero), se accede a la dirección de


comienzo de la variable referenciada o apuntada.
• Con el nombre del puntero, aplicando el operador indirección (*nombrepuntero), se
accede al valor de la variable referenciada o apuntada por el puntero.

2
El tipo puntero ocupará 2 o 4 bytes, dependiendo del compilador y la plataforma. En todos los ejemplos de este
documento, salvo que se especifique lo contrario, se considera que el tipo puntero ocupa 4 bytes.

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria -4-

Por ejemplo,
int a = 44, b = 125;
...
int *pnum;
...
pnum = &a;
*pnum = 145;
...
printf("a = %d b = %d\n", a, b);
printf("La dirección de a es %p\n", pnum);
printf("El valor de a es %d\n", *pnum);
printf("La dirección de b es %p\n", &b);

Salida en pantalla:
a = 145 b = 125
La dirección de a es 0022FF44
El valor de a es 145
La dirección de b es 0022FF40

nombre dirección
variable comienzo

145 Direcciones
a 0022FF44 de memoria
crecientes

125
b 0022FF40

0022FF44
pnum

Esquema 2. Operador indirección

Es importante destacar en el anterior ejemplo, que como la dirección de la variable a se asigna


al puntero pnum de la forma pnum = &a, entones, *pnum es equivalente a a, es decir, por
ejemplo, asignar *pnum = 145 es equivalente a asignar a = 145.

Iniciación de un puntero a NULL


C no inicia un puntero cuando se declara, por lo que como cualquier otra variable,
inicialmente una variable puntero no contendrá ningún valor válido, es decir su valor será

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria -5-

indeterminado. Para no confundir éste valor indeterminado con ninguna dirección de memoria
válida, se puede iniciar el puntero a valor nulo (constante NULL). Este valor indicará que el
puntero todavía no apunta a ninguna dirección de memoria válida.
nombrepuntero = NULL;

¡¡¡IMPORTANTE!!! Jamás se debe dejar un puntero sin iniciar, es decir, sin apuntar a una
variable en concreto o a NULL. Nunca hacer lo siguiente:
int *ptr;
*ptr = 10;
ptr está apuntando a cualquier parte, código, datos, pudiendo producirnos el error en
ejecución, puesto que en compilación esto no nos da error, ni siquiera advertencia.

Operaciones con punteros


Asignación de punteros
Es posible asignar un puntero a otro puntero, con la condición de que sean punteros del
mismo tipo. Cuando esta operación se efectúa, los dos punteros apuntarán a la misma
variable, pues contendrán la misma dirección de memoria.

Comparación de punteros
Es posible comparar dos punteros del mismo tipo con el operador igualdad (==), para
comprobar si contienen la misma dirección de memoria, es decir si apuntan a la misma
variable. También es posible utilizar los operadores relacionales >, >=, <, <= con dos
punteros para comparar las posiciones relativas en memoria que ocupan las variables
apuntadas por ellos.

Aritmética de punteros
En C sólo se permiten dos operaciones aritméticas con punteros: adición y sustracción de un
entero a un puntero, y sustracción de punteros

§ Sumar o restar un entero a un puntero


Si se suma o resta un entero a un puntero, se produce un incremento o decremento de la
dirección contenida en dicho puntero. El incremento de un puntero siempre es con
relación al tipo base al que apunta. Lo mismo ocurre con el decremento. Cada vez que se
incremente en una unidad un puntero, éste apuntará al elemento siguiente del tipo del
puntero, no a la dirección de memoria siguiente. En el caso de decremento será el
elemento anterior al que apunte.
Así, si se define un puntero de la forma tipo_puntero *puntero, el número de posiciones
de memoria incrementadas o decrementadas será:
puntero + n = dirección + ( n * sizeof(tipo_puntero) )
Dependiendo del tipo del puntero, se tendrán los siguientes avances:

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria -6-

Tipo de dato apuntado Avance en bytes


char n bytes
int 2n ó 4n bytes (depende del compilador)
long 4n bytes
float 4n bytes
double 8n bytes
long double 10n bytes (depende del compilador)
Tabla 1. Avance de la dirección apuntada dependiendo del tipo del puntero

Por ejemplo, observaremos que incrementar o decrementar en una unidad un puntero a int
significará avanzar dos posiciones de memoria.

short a[4]={1000, 100, 10, 1}; nombre dirección


... variable comienzo
short *pte = &a[0];

a[3] 0022FF46 1
printf("*pte: %hd\n", *pte);
pte++; Direcciones
a[2] 0022FF44 10 de memoria
printf("*pte: %hd\n", *pte);
pte = pte + 2; crecientes
printf("*pte: %hd\n", *pte); a[1] 0022FF42 100
pte = pte - 3;
printf("*pte: %hd\n", *pte); a[0] 0022FF40 1000

Salida en pantalla:
*pte: 1000
*pte: 100
pte 0022FF0C 0022FF4
*pte: 1
0
*pte: 1000

Esquema 3. Aritmética de punteros. Suma o resta de un entero a un puntero

§ Resta de dos punteros


Es una operación que se realiza entre dos punteros del mismo tipo, para conocer el
número de elementos (del tipo de los punteros), que separan las direcciones apuntadas por
los punteros3.

float lista[10];
float *pt1 = &lista[2];
float *pt2 = &lista[7];
...
int d;

3
O dicho de otra forma, el resultado de la resta de dos punteros es la “distancia” entre las direcciones apuntadas
por ellos, no en bytes, sino en datos del tipo de los punteros

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria -7-

d = pt2 - pt1;

d tomará el valor 5, el número de elementos que separan a ambos punteros. Como se


observa, si ambos punteros apuntan a elementos distintos de un mismo vector, entonces el
resultado es el mismo que restar los índices de los elementos a los que se apunta.

Aparte de la adición y sustracción de un entero a un puntero y de la resta de un puntero de


otro, no se puede realizar ninguna operación más. No se puede: multiplicar o dividir punteros,
sumar dos punteros, aplicar desplazamientos de bits y operadores máscara a punteros, ni
sumar ni restar datos del tipo real de un puntero.

Constante puntero y puntero a constante


Para definir un puntero constante se utilizará el siguiente formato:
tipo_dato_apuntado *const nombrepuntero = dirección_de_variable;

A un puntero declarado como constante no puede modificarse su valor, es decir, la dirección


que contiene y a la que apunta. En definitiva, es ilegal una sentencia del tipo
nombrepuntero = &variable;

Para definir un puntero a una constante se utilizará el siguiente formato:


const tipo_dato_apuntado *nombrepuntero = dirección_de_constante;

Por medio de un puntero a constante se puede acceder a la constante apuntada, pero


obviamente no está permitido modificar su valor, es decir, el contenido almacenado en la
posición de memoria a donde apunte,

§ Si se sabe que un puntero siempre apuntará a la misma posición de memoria y nunca


necesitará ser reubicado, se definirá un puntero constante.
§ Si se sabe que el dato apuntado por el puntero nunca necesitará cambiar, se definirá un
puntero a una constante.

Para definir un puntero constante a una constante se utilizará el siguiente formato:


const tipo_dato_apuntado *const nombrepuntero = dirección_de_constante;

Prioridad de los operadores *, ++ y -- sobre el mismo puntero


Todos ellos tienen la misma prioridad y su asociatividad es de derecha a izquierda, por lo
tanto...

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria -8-

Expresión Prioridad Comentario


*++apunt ++, * Primero se incrementa la dirección contenida en apunt y
posteriormente se obtiene el valor apuntado por la nueva
dirección de apunt. La anterior expresión se divide en dos:
primero se evalúa ++apunt y posteriormente *apunt
*(++apunt) ++, * Mismo comportamiento que el caso anterior
++*apunt *, ++ Se incrementa la variable apuntada por apunt
++(*apunt) *, ++ Mismo comportamiento que el caso anterior
*apunt++ *, ++ Primero se obtiene el valor apuntado por apunt y
posteriormente se incrementa la dirección contenida en
apunt
*(apunt++) *, ++ Mismo comportamiento que el caso anterior
(*apunt)++ *, ++ Se incrementa la variable apuntada por apunt

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria -9-

Punteros y arrays
Existe una relación muy estrecha entre arrays y punteros. Como punto de partida, el nombre
de un array es un puntero constante que contiene la dirección del primer elemento de
dicho array.

Punteros y vectores
El nombre del vector (sin índice ni corchetes) es un puntero constante que contiene la
dirección del primer elemento del vector.
Por ejemplo,
short lista[4] = {1000, 100, 10, 1};

nombre dirección Observar la siguiente diferencia:


comienzo *(lista+1) obtiene el valor del 2do elemento de lista: 100
*lista+1 incrementa en 1 el contenido del 1er elemento
lista de lista: de 1000 a 1001

0022FFEE
Son equivalentes...

lista[3] 0022FFF4 1 lista[3] *(lista+3)

lista[2] 0022FFF2 10 lista[2] *(lista+2)


100
lista[1] 0022FFF0 Direcciones lista[1] *(lista+1)
1000 de memoria
lista[0] 0022FFEE crecientes lista[0] *lista

Esquema 4. Punteros y vectores

* El puntero lista contiene la dirección del primer elemento, es decir &lista[0].


* Con *lista accedemos al contenido de la variable apuntada por lista, es decir, a la
variable lista[0].
* lista++ es una operación incorrecta, pues lista es un puntero constante.

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 10 -

De acuerdo a las anteriores afirmaciones, podemos presentar las siguientes equivalencias.

Son equivalentes... Valor Son equivalentes... Valor


lista[0] *lista 1000 &lista[0] lista 0022FFEE
lista[1] *(lista+1) 100 &lista[1] lista+1 0022FFF0
lista[2] *(lista+2) 10 &lista[2] lista+2 0022FFF2
lista[3] *(lista+3) 1 &lista[3] lista+3 0022FFF4
Tabla 2. Equivalencia entre la notación puntero y la notación subíndice para un vector

Escrito de forma genérica,


▪ lista[i] es equivalente a *(lista+i)
▪ &lista[i] es equivalente a lista+i
En general la aritmética de punteros es mucho más rápida que el uso de índices, sobre todo si estamos realizando
un acceso secuencial al array. En el caso de un acceso aleatorio será igual de rápido.

§ Dos vectores no pueden copiarse4 directamente uno en otro, sino que hay que copiarlos
elemento a elemento.
§ Dos vectores no pueden compararse5 directamente para ver si son iguales (contienen los
mismos valores en los elementos de posiciones equivalentes), sino que hay que
compararlos elemento a elemento.

Con el nombre del vector, podemos utilizar bien notación subíndice o bien notación puntero
para acceder a los elementos individuales. Igualmente se puede poner índices a los punteros
que apuntan a vectores. Por ejemplo,
int cad[10];
int *p; /* Definición de un puntero a entero */
int t;
p = cad; /* El puntero p apunta al primer elemento del vector */

cad[t] es equivalente a *(cad + t)


p[t] es equivalente a *(p + t)

p++ es válido, pues p es una variable puntero


cad++ NO es válido, pues cad es un puntero constante

4
vector1 = vector2 es ilegal porque vector1 es un puntero constante
5
vector1 == vector2 no compara contenidos sino la dirección de memoria de comienzo de los vectores, por lo
que siempre el resultado será “falso”

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 11 -

Vectores de punteros y punteros a vectores

Vector de punteros
tipo_dato vector[N]; define un vector de N elementos
tipo_dato *vector[N]; define un vector de N elementos que son punteros

Por ejemplo,
int *ptr[10];

define un vector de 10 punteros a int. Cada elemento del vector prt será un puntero, por lo
que serán válidas sentencias del tipo
ptr[3] = &var; donde var será una variable int
ptr[4] = NULL; iniciamos a NULL

Puntero a un vector
tipo_dato (*puntero)[N]; define un puntero a un vector de N elementos
tipo_dato *(*puntero)[N]; define un puntero a un vector de N punteros

Por ejemplo,
int (*ptr)[10]; define un puntero a un vector de 10 int
int *(*ptr)[10]; define un puntero a un vector de 10 punteros a int

Punteros y cadenas de caracteres


Teniendo en cuenta, que las siguientes definiciones son equivalentes
tipo_dato *puntero; tipo_dato puntero[];
es posible considerar dos tipos de definición de cadenas, ambas equivalentes

char cadena[] = "MENSAJE DE EJEMPLO";


o bien
char *cadena = "MENSAJE DE EJEMPLO";

También es posible definir un vector de cadenas de caracteres como en el siguiente ejemplo


char *cadena[7] = {"Lunes", "Martes", "Miércoles", "Jueves",
"Viernes", "Sábado", "Domingo"};

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 12 -

Punteros y tablas
Podremos pensar en una tabla de f filas y c columnas como un vector de f elementos, donde
cada elemento es a su vez un vector de c elementos.
short mat[4][3] = {0, 1, 2, 10, 11, 12, 20, 21, 22, 30, 31, 32};

El nombre de la tabla (sin índices ni corchetes) será por tanto una puntero constante que
contiene la dirección del primer elemento, es decir de la primera fila de la tabla. Por tanto será
un puntero constante a un vector.

elemento direcciones
tabla mat

0022FFF5 32
mat[3][2] 0022FFF4
0022FFF3 31
mat[3][1] 0022FFF2 fila 3
0022FFF1 30
mat[3][0] 0022FFF0
0022FFEF 20
mat[2][2] 0022FFEE
0022FFED 21 Direcciones
fila 2 de memoria
mat[2][1] 0022FFEC
0022FFEB crecientes
20
mat[2][0] 0022FFEA
0022FFE9 12
mat[1][2] 0022FFE8
0022FFE7 11
mat[1][1] 0022FFE6 fila 1
0022FFE5 10
mat[1][0] 0022FFE4
0022FFE3 2
mat[0][2] 0022FFE2
0022FFE1 1
mat[0][1] 0022FFE0
mat 0022FFDF 0 fila 0
0022FFDE mat[0][0] 0022FFDE

Esquema 5. Punteros y tablas

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 13 -

De acuerdo a las anteriores afirmaciones, podemos presentar las siguientes equivalencias.


Son equivalentes...
*mat mat[0] fila [0] de mat puntero al primer elemento de fila [0] de mat
*(mat+1) mat[1] fila [1] de mat puntero al primer elemento de fila [1] de mat
*(mat+2) mat[2] fila [2] de mat puntero al primer elemento de fila [2] de mat
*(mat+3) mat[3] fila [3] de mat puntero al primer elemento de fila [3] de mat
Son equivalentes... Valor Son equivalentes... Valor
**mat mat[0][0] 0 **(mat+2) mat[2][0] 20
*(*mat+1) mat[0][1] 1 *(*(mat+2)+1) mat[2][1] 21
*(*mat+2) mat[0][2] 2 *(*(mat+2)+2) mat[2][2] 22
**(mat+1) mat[1][0] 10 **(mat+3) mat[3][0] 30
*(*(mat+1)+1) mat[1][1] 11 *(*(mat+3)+1) mat[3][1] 31
*(*(mat+1)+2) mat[1][2] 12 *(*(mat+3)+2) mat[3][2] 32
Tabla 3. Equivalencia entre la notación puntero y la notación subíndice para una tabla

Escrito de forma genérica,


▪ *(mat+f) es equivalente a mat[f]
▪ mat[f][c] es equivalente a *(*(mat+f)+c)
§ Dos tablas no pueden copiarse6 directamente una en otra, sino que hay que copiarlos
elemento a elemento.
§ Dos tablas no pueden compararse7 directamente para ver si son iguales (contienen los
mismos valores en los elementos de posiciones equivalentes), sino que hay que
compararlas elemento a elemento.
Con el nombre de la tabla, podemos utilizar bien notación subíndice o bien notación puntero
para acceder a los elementos individuales. Igualmente se puede poner índices a los punteros
que apuntan a tablas. Por ejemplo,
int mat[10][20];
int (*pt)[]; /* Definición de un puntero a vector */
int f,c;
pt = mat;
mat[f][c] es equivalente a *(*(mat+f)+c)
pt[f][c] es equivalente a *(*(pt+f)+c)

6
tabla1 = tabla2 es ilegal porque tabla1 es un puntero constante
7
tabla1 == tabla2 no compara contenidos sino la dirección de memoria de comienzo de las tablas, por lo que
siempre el resultado será “falso”

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 14 -

Ejercicios resueltos

Ejercicio 1.- Mapa de memoria


Presentar el mapa de memoria de la siguiente declaración de variables
long double num = 52.75;
float tab[] = {1.5, 2.5 ,3.5};
long double *p = &num;
char msg[]= "HOLA";

Programa escrito en lenguaje C


Ver fuente mapam.c

Ejemplo de ejecución del programa


DIRECCION TAMAÑO VALOR
--------- ------ --------
num 0022FF38 8 52.75
tab[2] 0022FF28 4 3.50
tab[1] 0022FF24 4 2.50
tab[0] 0022FF20 4 1.50
p 0022FF1C 4 0022FF38
msg[4] 0022FF04 1 - 0
msg[3] 0022FF03 1 A-65
msg[2] 0022FF02 1 L-76
msg[1] 0022FF01 1 O-79
msg[0] 0022FF00 1 H-72

NOTA: Al ejecutar el programa, los valores absolutos de las direcciones que se presentan en
pantalla pueden variar respecto a las presentadas en el anterior ejemplo. Lo importante no es
el valor absoluto de la dirección, sino observar el incremento en posiciones de memoria que
se produce en la disposición de unas variables y otras.
Igualmente, el tamaño del tipo int y del tipo puntero puede variar dependiendo del
compilador. En el ejemplo ambos se consideran de 4 bytes.

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 15 -

Ejercicio 2.- Tabla de direcciones de memoria


Un programa en C contiene las siguientes definiciones
float vector1[10] = {1.3, 20};
float vector2[10] = {0};
int lista[3] = {10, 20, 30};
float numero = 123.45;
char letra = 'K';
char *pc;
float *pf;
...
pc = &letra;
pf = &numero;

Suponiendo que las direcciones de comienzo de las variables lista, numero y letra son
respectivamente 0022FED0, 0022FECC y 0022FEC3, y que tanto el tipo int como el tipo
puntero ocupan 4 bytes, indica...
1. El valor de &numero
2. Qué valor es asignado a pc
3. El valor de *pf
4. El valor de lista
5. El valor de &lista[0]
6. El valor de *lista
7. El valor de lista[0]
8. El valor de *(lista+2)
9. El valor de *lista+2
10. El valor de &lista[2]

Solución
Según nos indica el enunciado del problema, en teoría, el mapa de memoria de las anteriores
declaraciones será:
Variable Dirección comienzo Tamaño Valor
vector1[9] 0022FF28 4 0
vector1[8] 0022FF24 4 0
... ... ... ...
vector1[1] 0022FF08 4 20
vector1[0] 0022FF04 4 1.3
vector2[9] 0022FF00 4 0
vector2[8] 0022FEFB 4 0
... ... ... ...
vector2[1] 0022FEE0 4 0
vector2[0] 0022FEDB 4 0
lista[2] 0022FED8 4 30

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 16 -

Variable Dirección comienzo Tamaño Valor


lista[1] 0022FED4 4 20
lista[0] 0022FED0 4 10
numero 0022FECC 4 123.45
pc 0022FEC8 4 K
pf 0022FEC4 4 123.45
letra 0022FEC3 1 K

Por tanto, la respuesta a las cuestiones planteadas es la siguiente:


1. 0022FECC 6. 10
2. 0022FEC8 7. 10
3. 123.45 8. 30
4. 0022FED0 9. 12
5. 0022FED0 10. 0022FED8

Ejercicio 3.- Recorrido vector con notación punteros

Ejemplo de recorrido de un vector utilizando punteros

En el siguiente fragmento de código se accede a los elementos de un vector utilizando


notación de subíndices, de forma que se carga en cada elemento el valor de su índice.

#include <stdio.h>
#define DIM 10

void main(void) {
int k;
float v[DIM];

for (k=0; k<DIM; k++)


v[k] = k;
}

Modificarlo para utilizar notación de punteros para recorrerlo.

Solución
Una primera forma sería simplemente utilizar la notación de punteros sobre el propio nombre
del vector, recordando que en el caso de vectores v[k] es equivalente a *(v+k)

#include <stdio.h>
#define DIM 10

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 17 -

void main(void) {
int k;
float v[DIM];

for (k=0; k<DIM; k++)


*(v+k) = k;
}

Una segunda forma podría ser utilizar un puntero a float en el que cargamos la dirección de
comienzo del vector v, y el cual vamos incrementando para que vaya apuntando a cada uno de
los elementos del vector v.

#include <stdio.h>
#define DIM 10

void main(void) {
int k;
float v[DIM];
float *p;

p = v;
for (k=0; k<DIM; k++)
{ *p = k;
p++;
}
}

Las dos sentencias del cuerpo del bucle for, podrían sustituirse por simplemente *p++ = k;
Primero se evalúa el operador indirección (*) y posteriormente el post-incremento (++), por
ello primeramente se modifica la variable apuntada por el puntero p y posteriormente se
incrementa la dirección contenida en el puntero p.

Lo que no es posible es realizar el bucle for de la forma


for (k=0; k<DIM; k++)
{ *v = k;
v++;
}
o de la forma
for (k=0; k<DIM; k++)
*v++ = k;

debido a que v++ es ilegal al ser v un puntero constante.

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 18 -

Ejercicio 4.- Recorrido tabla con notación punteros

Ejemplo de recorrido de una tabla utilizando punteros

En el siguiente fragmento de código se accede a los elementos de una tabla utilizando


notación de subíndices, de forma que se imprime cada elemento en pantalla.

#include <stdio.h>
#define FIL 10
#define COL 7

void main(void) {
int f, c;
double mt[FIL][COL];
...
for (f=0; f<FIL; f++)
{ for (c=0; c<COL; c++)
printf("%5.2lf", mt[f][c]);
printf("\n");
}
}

Modificarlo para utilizar notación de punteros para recorrerla.

Solución
Una primera forma puede ser utilizar la notación de punteros sobre el propio nombre de la
tabla, recordando que en el caso de tablas mt[f][c] es equivalente a *(*(mt+f)+c)
...
for (f=0; f<FIL; f++)
{ for (c=0; c<COL; c++)
printf("%5.2lf", *(*(mt+f)+c));
printf("\n");
}

Una segunda forma puede ser utilizar la notación combinada de subíndice y puntero sobre el
propio nombre de la tabla, recordando que mt[f][c] es equivalente a *(mt[f]+c).
No se suele utilizar esta notación debido a que no aporta claridad, sino todo lo contrario.
...
for (f=0; f<FIL; f++)
{ for (c=0; c<COL; c++)
printf("%5.2lf", *(mt[f]+c));
printf("\n");
}

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 19 -

También podría haberse combinado el subíndice en la posición de columnas y la notación de


punteros en la de filas, de la siguiente forma (*(mt+f))[c].
...
for (f=0; f<FIL; f++)
{ for (c=0; c<COL; c++)
printf("%5.0lf", (*(mt+f))[c]);
printf("\n");
}

Ninguna de las dos notaciones anteriores se suele utilizar debido a que no aportan claridad,
sino todo lo contrario.

Sabiendo que una tabla se almacena en memoria de forma lineal fila a fila, comenzando la
primera fila en la posición más baja de memoria ocupada por la tabla, podemos presentar una
tercera forma de recorrerla. Para ello se definirá un puntero del tipo base de la tabla, que
apunte a su primer elemento, y se irá calculando la posición de memoria donde se van
encontrando cada uno de los elementos de la tabla, a base de sumar la longitud de las filas
desde el comienzo de la tabla y los elementos desde el comienzo de la fila donde está situado
el elemento al que se desea acceder.
Observemos que la asignación pmt = *mt es correcta debido a que *mt es un puntero al
primer elemento de la primera fila de la tabla, es decir, un puntero a double.

...
double *pmt;
...
pmt = *mt;
for (f=0; f<FIL; f++)
{ for (c=0; c<COL; c++)
printf("%5.2lf", *(pmt + f*COL + c));
printf("\n");
}

Una cuarta forma, también aprovechando el almacenamiento secuencial de las tablas en


memoria, es hacer que un puntero del tipo base de la tabla recorra la misma, incrementándolo
tantas veces como elementos tenga la tabla.
...
double *pmt = *mt;
...
for (f=0; f<FIL; f++)
{ for (c=0; c<COL; c++)
printf("%5.2lf", *pmt++);
printf("\n");
}

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 20 -

Un simplificación al anterior fragmento de código, utilizando sólo un bucle, puede ser el


siguiente.
...
double *pmt = *mt;
...
for (k=0; k<FIL*COL; k++)
{ printf("%5.0lf", *pmt++);
if ( (k+1) % COL == 0 )
printf("\n");
}

Ejercicio 5.- Lectura elementos vector con notación punteros

Ejemplo de uso de punteros para la lectura de datos de un vector

En el siguiente fragmento de código se leen los elementos de un vector utilizando notación de


subíndices.

#include <stdio.h>
#define DIM 10

void main(void) {
int k;
float v[DIM];
...
for (k=0; k<DIM; k++)
{ printf("Elemento [%d]?: ", k+1);
scanf("%f", &v[k]);
}
...
}

Modificarlo para utilizar notación de punteros para recorrerlo.

Solución
Si recordamos que
&v[i] es equivalente a v+i

Por ello el anterior fragmento de código podría reescribirse como


...
for (k=0; k<DIM; k++)
{ printf("Elemento [%d]?: ", k+1);
scanf("%f", v+k);
}
...

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 21 -

Ejercicio 6.- Lectura elementos tabla con notación punteros

Ejemplo de uso de punteros para la lectura de datos de una tabla

En el siguiente fragmento de código se leen los elementos de una tabla utilizando notación de
subíndices.

#include <stdio.h>
#define FIL 10
#define COL 7

void main(void) {
int f, c;
double mt[FIL][COL];
...
for (f=0; f<FIL; f++)
for (c=0; c<COL; c++)
{ printf("Elemento [%d][%d]?: ", f+1, c+1);
scanf("%lf", &mt[f][c]);
}
...
}

Modificarlo para utilizar notación de punteros para leer los elementos.

Solución
Si recordamos que
mt[f][c] es equivalente a *(*(mt+f)+c)
entonces se deduce que
&mt[f][c] es equivalente a *(mt+f)+c

Por ello el anterior fragmento de código podría reescribirse como


...
for (f=0; f<FIL; f++)
for (c=0; c<COL; c++)
{ printf("Elemento [%d][%d]?: ", f+1, c+1);
scanf("%lf", *(mt+f)+c);
}
...

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 22 -

Programas complementarios

Se presentan a continuación varios programas ejemplo que permiten comprobar el


comportamiento de los punteros en C.

Nombre Descripción / Comentarios


desbord2.c Programa: Desbordamiento de índices en matrices unidimensionales.
Descripción: No existe comprobación de límites en ejecución. Es decir
si la matriz tiene TAM elementos, es posible seguir escribiendo valores
por encima del índice TAM-1, o por debajo del índice 0, sin que esto
produzca un error de ejecución.
Es un programa similar al fuente desborda.c visto en temas anteriores,
pero en éste se añade la presentación de las direcciones de las variables
declaradas, para comprobar su posición contigua en memoria.
memlista.c Programa: Mapa de memoria de un vector.
Descripción: Realiza el mapa de memoria de una vector, y comprueba
el comportamiento de un puntero al tipo base del vector, desplazándose
por el mismo.
Para el manejo del vector utiliza la característica de que el nombre del
mismo es un puntero a su primer elemento.
aripunte.c Programa: Combinación de los operadores * y ++.
Descripción: Realiza el mapa de memoria de un vector, y comprueba el
comportamiento de un puntero al tipo base del vector, sobre el que
actúan simultáneamente los operadores * y ++.
memmatriz.c Programa: Mapa de memoria de una matriz bidimensional.
Descripción: Realiza el mapa de memoria de una matriz bidimensional,
y comprueba el comportamiento de un puntero al tipo base de la matriz,
desplazándose por la misma.
Hay que recordar que:
- Una matriz bidimensional es una matriz unidimensional cuyos
elementos (filas) son a su vez matrices unidimensionales.
- El nombre de la matriz bidimensional es un puntero al primer
elemento de la misma (primera fila).

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 23 -

Ejercicios propuestos

Ejercicio 7.- Acceder a una variable mediante un puntero

Realizar un programa que declare una variable entera var_a y un puntero a entero p_var_a.

El programa deberá realizar las siguientes acciones.


Todas las lecturas serán de teclado y las escrituras serán en pantalla.

1. Leer un valor para la variable var_a.


2. Escribir el contenido de la variable var_a.
3. Apuntar a la variable var_a con el puntero p_var_a.
4. Utilizar el puntero p_var_a para escribir el contenido de la variable var_a.

5. Utilizar el puntero p_var_a para leer un valor para la variable var_a.


6. Escribir el contenido de la variable var_a.
7. Utilizar el puntero p_var_a para escribir el contenido de la variable var_a.

8. Escribir la dirección de la variable var_a utilizando el operador dirección.


9. Utilizar el puntero p_var_a para escribir la dirección de la variable var_a.
10. Escribir la dirección de la variable p_var_a.
11. Escribir el contenido de la variable p_var_a.

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 24 -

Ejercicio 8.- Ordenar vector de claves sin modificarlo

Realizar un programa que lea de teclado 15 claves (números enteros) y las almacene en un
vector. Una clave será un número entero.

El programa, al realizar la lectura de las claves deberá garantizar:


− que todas ellas se encuentran en el rango 1000 a 7000.
− que el usuario no teclea claves repetidas.
En caso contrario, se solicitaría de nuevo el tecleo de la clave. El programa no puede volver a
solicitar todas las claves introducidas hasta ese momento, sino sólo la última recibida que no
supera las validaciones.

Posteriormente el programa deberá mostrar ordenadas las claves introducidas, pero sin
modificar el vector de claves. Para ello, se deberá utilizar un vector de punteros que apunten a
cada una de las claves.
También mostrará por último las claves en el orden original en que fueron introducidas, para
efectivamente comprobar que el vector original no se ha modificado.

Ayuda.
La forma de rellenar el vector de punteros es comprobar de una en una, comenzando por la
clave 1000 y hasta la 7000, si la clave se encuentra en el vector de claves, y si así fuera,
obtenemos la dirección del elemento del vector de claves y la incluimos en el primer puntero
libre del vector de punteros. Esto nos obliga a llevar un segundo índice sobre el vector de
punteros que nos vaya determinando el siguiente puntero libre.

Finalmente, recorreremos el vector de punteros y presentaremos el elemento al que apunta


cada uno de ellos. Así, las claves aparecerán en pantalla en orden.

Por último, recorreremos el vector de claves original y presentaremos cada una de sus claves.
Así, las claves aparecerán en pantalla en el orden original en que fueron introducidas.

A modo de ayuda, se presentan los siguientes algoritmos en pseudocódigo que pueden


resolver el problema.

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 25 -

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 26 -

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 27 -

Ejercicio 9.- Mapa de caracteres

Se dispone de un vector vletras de caracteres, cargado con los siguientes valores.

A F H K L O S U X Z

Realizar un programa que le solicite al usuario la introducción de caracteres, simulando en


entrada una tabla de 3x4. Es decir, le iremos solicitando:

Introduzca carácter [1][1]:


Introduzca carácter [1][2]:
Introduzca carácter [1][3]:

Introduzca carácter [3][3]:
Introduzca carácter [3][4]:

El programa deberá disponer de una matriz interna de punteros a char, también de dimensión
3x4, que llamaremos mapa. En cada elemento de mapa se introducirá el siguiente valor:
− Cada vez que se teclee un carácter, se buscará en vletras, y si se encuentra, en el
elemento de mapa correspondiente a las coordenadas del carácter leído se
introducirá la dirección del elemento de vletras.
− En caso de no encontrase se introducirá NULL.

Posteriormente el programa deberá presentar la tabla tecleada por el usuario, recorriendo la


matriz mapa y mostrando el valor del elemento al que apunta cada puntero. En caso de que el
puntero esté a NULL, se presentará un carácter asterisco (*).

Ejercicio 10.- Recorrido de arrays con notación puntero

Realizar un programa que declare en memoria:


- un array unidimensional de int, que llamaremos vector, de DIM elementos (DIM=7) y
con valores:
{25, 40, 55, 70, 85, 100, 115}

- una array bidimensional de int, que llamaremos tabla, de FIL x COL elementos (FIL = 3,
COL = 4) y con valores:
{ 15, 25, 35, 45,
115, 125, 135, 145,
215, 225, 235, 245}

Implementar en el programa estos tres procesos sobre el array unidimensional vector.

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 28 -

1) Recorrido y presentación en pantalla utilizando un índice.

2) Recorrido y presentación en pantalla utilizando el nombre del array como puntero


constante (que apunta al primer elemento del array), y aritmética de punteros. No se permite
notación de subíndices.

3) Recorrido y presentación en pantalla utilizando una variable puntero al tipo base del array,
y aritmética de punteros. No se permite notación de subíndices.

Está claro que el resultado en pantalla de las anteriores tres implementaciones debe de ser el
mismo.

Implementar en el programa estos tres procesos sobre el array bidimensional tabla.

1) Recorrido y presentación en pantalla utilizando dos índices.

2) Recorrido y presentación en pantalla utilizando el nombre de la tabla como puntero


constante a filas (apunta a la primera fila del array), y aritmética de punteros. No se permite
notación de subíndices.

3) Aprovechando el almacenamiento secuencial de los arrays bidimensionales en memoria,


realizar el recorrido y presentación en pantalla mediante una variable puntero al tipo base,
incrementando este puntero, mediante aritmética de punteros, tantas veces como elementos
tenga el array bidimensional.

Está claro que el resultado en pantalla de las anteriores tres implementaciones debe de ser el
mismo.

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 29 -

Ejercicio 11.- Manejo de una cadena con un puntero a char

Realizar un programa que solicite introducir por teclado una frase y posteriormente un
carácter.

El programa deberá presentar en pantalla:


• la longitud de la frase.
• las veces que se encuentra el carácter en la misma.
• las posiciones en las que se encuentra el carácter en la misma.
o deberá definirse un vector donde se almacenarán estas posiciones según se
vayan calculando, y posteriormente, recorriendo este vector, se mostrarán en
pantalla.

Otros requisitos:
• El programa deberá ser lo más eficiente posible, de forma que la cadena sólo podrá
recorrerse una vez.

• Debe usarse notación puntero. No puede utilizarse notación subíndice.

• Para leer la cadena utilizar gets().

Ejercicio 12.- Submatrices simétricas

Se dispone de una matriz de 10x10 elementos enteros.


Realizar un programa que determine y presente en pantalla todas las submatrices 3x3
incluidas en la primera, y que sean simétricas.
La matriz 10x10 puede leerse de teclado o bien incluirse en el programa de forma constante,
iniciándola en su declaración.

El algoritmo que se propone para resolver el problema es el siguiente:


Recorreremos la matriz 10x10 desde su elemento [0][0] hasta su elemento [7][7], tomando
cada uno de estos elementos como el primer elemento de una submatriz de 3x3, y por tanto
comprobando si dicha submatriz es simétrica.
Para mayor simplicidad del algoritmo de comprobación de simétrica, los 9 elementos que
forman la submatriz, puede ser copiados sobre una matriz auxiliar de dimensión 3x3 y sobre
la misma realizar el algoritmo de comprobación de simétrica.

En caso de serlo, guardaremos la dirección del primer elemento de la submatriz en un vector


de punteros.

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 30 -

Este vector de punteros deberá haberse declarado de dimensión 64, que son como máximo el
número de submatrices 3x3 incluidas en una 10x10. Además deberá haberse iniciado al
principio con todos los punteros a NULL, para poder distinguir aquellos no usados.

Finalmente, el programa recorrerá el vector de punteros y sabiendo que cada elemento


contiene la dirección del primer elemento de una matriz 3x3, presentará cada una de las
matrices en pantalla.

NOTA: Todos los valores literales incluidos en el enunciado deberán declararse como
constantes en el programa, deduciendo los que sea posibles. Por ejemplo:
// Dimensiones matriz de entrada
#define FIL 10
#define COL FIL

// Dimensiones submatrices
#define SMFIL 3
#define SMCOL SMFIL

// Dimensión máxima hasta donde investigar las submatrices


#define FILMAX FIL–SMFIL // 10 – 3 = 7
#define COLMAX FILMAX

// Número máximo de submatrices


#define MAXSM (FILMAX+1)*(COLMAX+1) // 8 * 8 = 64

Conjunto de datos de pruebas


Dada la matriz 10x10 que se presenta, se resaltan las submatrices 3x3 simétricas que incluye.

1 52 7 3 8 6 12 45 2 98
52 3 74 6 52 17 67 23 45 34
7 74 6 8 11 54 32 97 2 12
75 50 52 11 9 3 65 19 2 38
51 12 26 95 56 68 21 2 5 59
45 1 16 85 96 21 93 38 59 6
52 85 96 6 36 2 38 9 8 45
12 63 73 91 18 15 75 45 85 41
23 17 91 6 30 98 25 6 76 62
30 9 18 30 47 23 4 32 98 58

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 31 -

Ejercicio 13.- Rotar una matriz con punteros

Crear un programa que llamaremos rotarmatriz.c.


Leerá una matriz cuadrada de números enteros por teclado (matriz1). Deberá permitir trabajar
con matrices de hasta 7 x 7 elementos.
Los números que se introduzcan deben ser positivos, mayores que cero y no sobrepasar el
valor 50.
Todos los anteriores valores literales deberán ser declarados en el programa como constantes.

El programa solicitará por teclado la dimensión de matriz1 (sólo el número de filas, por
ejemplo, al ser cuadrada), y validará que no supera el máximo establecido. Si el valor tecleado
no es correcto deberá volverse a solicitarse repetidamente hasta que el usuario introduzca un
valor correcto.

Posteriormente solicitará uno tras otro los elementos de la matriz1, validando igualmente que
están dentro de los límites indicados. En cualquiera de las entradas, si se detecta un valor no
correcto, deberá volverse a solicitar repetidamente hasta que el usuario introduzca un valor
correcto.
Para la introducción de cada valor, es necesario indicar al usuario las coordenadas del
elemento que se está solicitando, con un mensaje del tipo
Introduzca el elemento [m,n]:
El valor de m y n, para el mensaje al usuario, deben de comenzar en [1,1].

El objetivo de programa es presentar en pantalla esta matriz rotada 90º hacia la derecha, pero
siguiendo exactamente el algoritmo que se detalla a continuación.

Internamente el programa utilizará una segunda matriz (matriz2) de punteros a enteros, y con
la misma dimensión física que matriz1.
El programa codificarás un algoritmo para rotar matriz1 sobre matriz2, pero en matriz2
deberá cargar no el valor del elemento de matriz1, sino el puntero a su posición.
Por último, el programa deberá presentar:
§ La matriz introducida, recorriendo matriz1 y presentando el valor de sus elementos.
§ La matriz rotada 90º hacia la derecha, recorriendo matriz2 y presentando el valor
apuntado por sus elementos, al ser punteros.

Departamento de Informática y Automática – Universidad de Salamanca


INFORMÁTICA II – GRADO EN MATEMÁTICAS
Tema I.- Gestión de memoria - 32 -

Se muestra un ejemplo a continuación.

Matriz que se introduce


1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16

Matriz rotada 90º que se debe presentar


13 9 5 1
14 10 6 2
15 11 7 3
16 12 8 4

Departamento de Informática y Automática – Universidad de Salamanca

También podría gustarte