Anda di halaman 1dari 26

CURSOS DE INICIACIN A LINUX Y C MARZO DEL 2007

Sergio lvarez Martnez

Punteros

GRUB-UAH

Punteros

Qu es un puntero?

Es una variable que en lugar de contener un valor numrico o de otro tipo definido por nosotros, contiene la direccin correspondiente a una posicin en la memoria, de forma que nos proporciona informacin para poder acceder a lo que Dios quiera que contenga esa posicin de memoria.
2

GRUB-UAH

Punteros

Punteros y posiciones de memoria

Supongamos que tenemos un mueble con varias cajas. Cada caja est numerada de forma ordenada para diferenciarse unas de otras. Cada caja contiene tambin una variable diferente. La caja 1 tiene una variable tipo char con valor 'A', la caja 2 tiene un entero con valor 116 y la caja 3, un puntero que apunta a la caja 2, es decir, que tiene valor 2 ya que es as como hemos numerado esa caja. Si nosotros somos una funcin a la que nos han otorgado el conocimiento de lo que hay en la caja n3, podemos acceder tambin (y manipular) el contenido de la caja 2, porque tenemos las instrucciones de cmo llegar a ella. Sin embargo la caja 1 ser inaccesible.
3

GRUB-UAH

Punteros

Del mismo modo, ya que los punteros son tambin variables y con un valor numrico (aunque desconocido para nosotros), se puede crear un puntero que apunte a otro puntero. Es decir, un puntero que nos diga la direccin en la que se encuentra otro puntero. Ms adelante veremos un par de ejemplos que nos demostrarn la utilidad de stos.

GRUB-UAH

Punteros

Tipos de punteros

Normalmente, un puntero cuando es declarado tiene ya asignado el tipo de datos de la variable a la que va a apuntar. Si declaramos un puntero a entero ste slo podr apuntar a variables de tipo entero. En el caso de puntero a void dejamos como indefinido el tipo de datos al que apunta el puntero, de forma que podr variar sobre la marcha.
5

GRUB-UAH

Punteros

Declaracin de punteros

Para declarar un puntero se procede de la misma forma que cualquier otro tipo de datos, introduciendo el tipo de datos al que va a apuntar el puntero (void o nada si indefinido) seguido de un asterisco. Ej: char* pcar int* pint char** ppcar
6

GRUB-UAH

Punteros

Cmo hacer que un puntero apunte

Para que un puntero apunte a una direccin de memoria, dado que no conocemos la direccin de nuestras variables, utilizamos el operador &. Si introducimos & seguido de una variable estamos invocando a su direccin de memoria, en vez de al contenido de esa direccin que es lo que normalmente obtendramos si no utilizramos &.
Ejemplo: char car1 = 'A'; si imprimimos el valor de car1 obtendramos 'A', pero si lo hacemos con &car1 obtendramos una direccin de memoria

GRUB-UAH

Punteros

Un par de ejemplos

char car1 = 'A'; char car2 = 'B'; char* puntero = &car1; car1 = 'C'; car2 = *puntero;

Cules serian los valores de car1 y car2 al final del cdigo?


8

GRUB-UAH

Punteros

La respuesta es

car1 = 'C' car2 = 'C'

Nota: el operador * delante de un puntero tiene el efecto contrario que & delante de una variable, ya que nos devuelve el valor que contiene la direccin apuntada por el puntero que le sigue.

GRUB-UAH

Punteros

Indicar cules de las siguientes afirmaciones son incorrectas y podran producir errores, tendiendo char car = 'A'; char* puntero = &car;:

A) car = *puntero; B) car = &car; C) car = &puntero; D) puntero = *puntero; E) puntero = *(&puntero); F) puntero = *car; G) *puntero = letra; H) &puntero = letra;
10

GRUB-UAH

Punteros

Son incorrectas B, C, D, F y H.

Qu es E? E no es incorrecta porque ningn valor se sale de su rango. Es una asignacin que introduce a puntero la informacin que contiene (*) la direccin de memoria en la que se encuentra puntero (&), como esto es otra direccin de memoria (la de car) y puntero debe contener direcciones de memoria, esto es correcto (y equivalente a poner puntero = puntero)

11

GRUB-UAH

Punteros

Punteros que apuntan a nil

Cuando un puntero no es asignado o el valor al que apuntaba ha dejado de existir, se dice que el puntero apunta a nil o que no apunta a nada. Tenemos que tener mucho cuidado de no acceder nunca a un puntero que posiblemente est apuntando a nil ya que nos encontraremos con una Violacin de segmento.
12

GRUB-UAH

Punteros

Cadenas de caracteres

En C, no existe el tipo de datos string como tal sino que se utiliza como una lista de caracteres. Declarado como char* podemos introducirle como valor una cadena de caracteres entre comillas dobles (). Aunque sea un puntero, al asignarle una cadena con comillas dobles le decimos al C que lo que queremos es crear una cadena de caracteres.
13

GRUB-UAH

Punteros

Entonces, Si utilizamos comillas dobles, char* ya no es un puntero?

Lo es, ya que se comportar como una lista. Es decir, si declaramos char* cadena = hola; estamos declarando 5 caracteres y un puntero al primero de ellos, de forma que cada carcter tenga un puntero asignado al que le sigue. Decimos 5 caracteres porque toda cadena tiene como ltimo el '\0' que indica final de cadena.
14

GRUB-UAH

Punteros

Cadenas de caracteres

No hay que confundir el carcter 'h' de la cadena h. El primero contiene el valor de un carcter en la tabla ASCII, el segundo contiene un puntero a la cabeza de una lista de 2 caracteres ('h' seguido de '\0').

15

GRUB-UAH

Punteros

Typecasting

Cuando un puntero no tiene un tipo especifico al que apuntar, se utiliza el typecasting para redirigirlo a un tipo o a otro. Si un puntero est apuntando a un entero, para acceder a dicho entero debemos especificar qu esperamos encontrar. Esto es necesario ya que debemos saber el tamao de los datos a los que queremos acceder. Esto se especifica, poniendo entre parntesis el tipo, antes de especificar el nombre del puntero.

16

GRUB-UAH

Punteros

Ejemplo:

void* p; int a; p = &a; int b = (int*)p;

17

GRUB-UAH

Punteros
Moraleja:
When a void* pointer is set to an integer, it becomes the integer, when a void* pointer is set to a char, it becomes the char. Be a void* my friend.
18

GRUB-UAH

Punteros

Punteros y registros:

Cuando queremos acceder a un elemento de un registro por medio de un puntero, se hace como en cualquier otro tipo de datos, pero para simbolizar que lo que queremos ver es el campo del registro, utilizamos, en lugar del punto (.) los smbolos de guin y mayor que (->) para que C identifique que estamos accediendo al registro por medio de un puntero y no directamente.
19

GRUB-UAH

Punteros

Violacin de Segmento, Qu es?

Cuando nos pongamos a programar con punteros es muy comn tener este tipo de errores. Un programador que acostumbre a trabajar con punteros automticamente distingue que una violacin de segmento se debe a un mal uso de algn puntero, normalmente porque le hemos asignado un valor que no es una direccin de memoria, o que es una direccin que se sale del rango de memoria asignado al programa.
20

GRUB-UAH

Punteros

Funciones: Paso por referencia y por valor

Como vimos en el tema anterior, las funciones en que todas su variables se pasan por valor, slo puede tener un valor de salida. Esto se puede resolver utilizando el Paso por referencia. Cuando queremos que una funcin modifique unos de sus parmetros de entrada de forma que al terminar sta, el valor quede modificado en memoria, utilizamos el paso por referencia. (En Pascal, el paso por referencia se haca aadiendo VAR al parmetro en cuestin en la declaracin de la funcin)
21

GRUB-UAH

Punteros

Paso por referencia en C

En C, para realizar un paso por referencia, pasamos como parmetro a la funcin, en lugar de una variable del tipo que queremos que nos modifique, un puntero a esa variable. As, si tenemos en memoria un carcter y a la funcin le pasamos la direccin a ese carcter, sta podr modificar lo que se encuentre en esa direccin, modificando as el contenido de ese carcter fuera de la funcin.
22

GRUB-UAH

Punteros

Paso por referencia en C

Por lo tanto, para crear una funcin que utilice un paso por referencia, lo hacemos como en el ejemplo: int cambiarcar( char* entrada_ref ); Y para llamar a la funcion... char caracter = 'A'; int n = cambiarcar( &caracter );
23

GRUB-UAH

Punteros

Listas

Del mismo modo que un char* se puede utilizar como un puntero a carcter o como una lista de caracteres (en la que el puntero indica la cabeza de la lista), se puede crear una lista de cualquier otro tipo. Para trabajar con una lista lo hacemos de la misma forma que si trabajsemos con un vector, teniendo en cuenta que es un tipo de datos dinmico.
24

GRUB-UAH

Punteros

Listas

Si declaramos un int* lista, podemos utilizarlo como lista, de forma que lista[0] ser su primer elemento, lista[1] el segundo, y as hasta que en algn momento un puntero, en lugar de apuntar al siguiente elemento, apunta a nil, es decir, que no tiene una direccin definida, por lo que deducimos que la lista ha llegado a su fin.
25

GRUB-UAH

Punteros

Rizando el rizo, uso de los puntero a puntero

Como explicamos al principio del tema, existen punteros que apuntan a la posicin en memoria de otro puntero. Esto tiene muchos usos, por ejemplo el paso por referencia a una funcin de lo que ya era un puntero. O bien para crear listas de listas, o listas de cadenas de caracteres (char**) o listas de listas de listas, etc...
26

Anda mungkin juga menyukai