FAQ de punteros (Traducida por Antonio González)

Responder
Mensaje
Autor
gorkau
Site Admin
Mensajes: 396
Registrado: 13/08/2002 11:00 pm
Ubicación: Bilbao
Contactar:

FAQ de punteros (Traducida por Antonio González)

#1 Mensaje por gorkau » 14/04/2007 9:53 am

4.2: Estoy intentando declarar un apuntador y asignarle espacio en memoria, pero no funciona. ¿ Que está incorrecto en el siguiente código ?

char *p;

*p = malloc(10);

A: El apuntador que declaraste es p, no *p. Para que el apuntador apunte hacia algo, debes de usar el nombre del apuntador:

p=malloc(10);

Es cuando manipulas el apuntador a memoria que usas "*" como un operador de indirección.

*p='H';

Ver también las preguntas 1.21, 7.1, 7.3c y 8.3.

Referencias : CT&P Sec. 3.1 p. 28



· 4.3: Hacer *p++ incrementa p, o incrementa a lo que apunta p ?

A: El operador postfijo ++ tiene mas precedencia que los operadores prefijos unarios. Por lo tanto, *p++ es equivalente a (p++); esto incremente p, y regresa el valor al cual apuntaba p antes de incrementarse. Para incrementar el valor apuntado por p, se puede usar (p)++.

Referencias: K&R1 Sec. 5.1 p. 91; K&R2 Sec 5.1 p. 95; ISO Sec. 6.3.2, Sec. 6.3.3; H&S Sec. 7.4.4 pp.192-3, Sec. 7.5 p. 193, Secs. 7.5.7, 7.5.8 pp. 199-200



· 4.8: Tengo una función que acepta un apuntador y supongo que lo inicializa :

void f(int *ip)
{
static int dummy=5;
ip=&dummy;
}

Pero cuando la llamo de esta manera:

int *ip;
f(ip);

El apuntador permanece sin cambio

A: Estás seguro de que la función hace lo que piensas ? Recuerda que los argumentos en C son pasados por valor. La llamada en la función modifica sólo la copia del apuntador. Lo que tu necesitas es pasar la dirección del apuntador ( la función la tomará como un apuntador a un apuntador), or hacer que la función regrese el apuntador.

void f(int **ip)

{

static int dummy=5;

*ip=&dummy;

}

int *ip;

f(&ip);

Ver también las preguntas 4.9 y 4.11

· 4.5: Tengo un apuntador a carácter, ¿Qué sucede al apuntarlo a algunos enteros y moverlo sobre ellos. Por qué no funciona ?

((int*)p)++;

A: En C, un operador de cast no significa : "estos bits son de un diferente tipo y trátalos de acuerdo al tipo que son "; es un operador de conversión, y por definición retornan un valor que no puede ser incrementado con ++. Lo que tu necesitas es:

p=(char*)((int*)p+1);

o mas simple

p+=sizeof(int);

Siempre que sea posible debes de elegir apropiadamente los tipos de apuntadores en primer lugar, en vez de tratar un tipo como otro.

Referencias : K&R2 Sec. A7.5 p. 205; ISO Sec. 6.3.4; Rationale Sec. 3.3.2.4; H&S Sec. 7.1 pp. 179-80.

· 4.9: Puedo usar un apuntador void ** como parámetro para que esa función lo tome como un apuntador genérico por referencia?

A: No existen los apuntadores a apuntadores genéricos en C. void * funciona como un apuntador genérico sólo porque las conversiones son aplicadas automáticamente cuando otro tipo de apuntadores son asignados a y desde void *´s; estas conversiones no pueden ser realizadas ( el nombre correcto del tipo del apuntador es desconocido) si se intenta que void ** apunte a un apuntador de tipo diferente que void *.

· 4.10: Tengo una función

extern int f(int *);

Que toma un apuntador a un entero.¿ cómo puedo pasar una constante por referencia? Intenté

f(&5);

Pero no funciona.


A: No se puede hacer directamente. Debes declarar una variable temporal, y entones pasar su dirección a la función.

int five =5;

f(&five);

Ver también 2.10, 4.8 y 20.1


· 4.11: Existe en C "pasar por referencia"?

A: Realmente no. Estrictamente hablando, C siempre usa paso por valor. Puedes simular el paso por referencia definiendo funciones que acepten apuntadores y usando el operador & cuando las llames y el compilador va a simularlo cuando pases un arreglo a una función ( pasando el apuntador, ver pregunta 6.4 ). C no tiene nada realmente equivalente a paso formal por referencia. ( De otra manera el preprocesador de macros puede proporcionar una forma de "paso por nombre").

Ver también preguntas 4.8 y 20.1

Referencias : K&R1 Sec. 1.8 pp. 24-5, Sec. 5.2 pp. 91-3; K&R2 Sec. 1.8 pp. 27-8, Sec. 5.2 pp. 95-7; ISO Sec. 6.3.2.2; H&S Sec. 9.5 pp. 273-4.

· 4.12: He visto diferentes métodos usados para llamar funciones vía apuntadores. Que hay al respecto ?

A: Originalmente, un apuntador a una función tiene que ser direccionado a una función "real" con el operador * y un par de paréntesis extra, para mantener la precedencia, antes de ser llamada.

int r, func(),(*fp)()=func;

r=(*fp)();

Esto puede ser tomado como que las funciones son siempre llamadas vía apuntadores, y que éstos "reales" nombre de funciones siempre caen implícitamente en apuntadores ( en expresiones, como se hace en las inicializaciones). Este razonamiento (que es usado, de hecho en el ANSI estándar) significa que

r=fp();

es legal y funciona correctamente, mientras fp es el nombre de la función o un apuntador a función. ( El uso ha sido siempre sin ambigüedad, no necesitas tener nada mas que el apuntador a la función seguido por una lista de argumentos, excepto una llamada a la función apuntada). Se permite * en forma explicita.

Ver también pregunta 1.34

Referencias : K&R1 Sec. 5.12 p. 116; K&R2 Sec. 5.11 p. 120; ISO Sec. 6.3.2.2; Rationale Sec. 3.3.2.2; H&S Sec. 5.8 p. 147, Sec. 7.4.3 p. 190.

Responder

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado