C/Visual C - Valor apuntado

 
Vista:

Valor apuntado

Publicado por Franco Cedillo (36 intervenciones) el 17/07/2005 02:48:52
Hola,
Estoy revisando el tema de punteros.
En una asignación simple de la dirección de una variable entera a un puntero genérico, he realizado la impresión en pantalla valiéndome la variable. ¿Cómo lo hago usando el puntero?

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

void main()
{
void *p; //no reconozco que significa realmente el asterisco
int a=1;
p=&a;
cout<<a<<" ";
cout<<p; //aquí debe ir algo como p*, o *p, o p->this.. no tengo idea
getch();
}

Desearía se absuelva mi duda sobre la sintaxis básica sobre punteros.
- declaración
- asignación
- referenmcia al valor apuntado

Y ahe practicado con punteros a clases, devolver un puntero desde una función, pasar un puntero a una función, punteros a constantes y punteros constantes. Así que trato de ver la convergencia en sus declaraciones y usos. Me confundí cuando halle this y ->.. estos signos también los usan junto con los punteros.

Saludos.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:Valor apuntado

Publicado por fernando.gomez (1603 intervenciones) el 18/07/2005 05:01:45
Hola. Primero, main debe devolver int, no void. Segundo, un puntero es una variable que contiene la dirección en memoria de otra variable. Por ejemplo, int* es un puntero a una variable de tipo entero, long* a una variable de tipo entero largo y char* a una variable de tipo caracter.

Los punteros nacieron en C de la necesidad de que al pasar una variable a --por ejemplo-- una función, la variable de entrada fuese modificada por la función, sin necesidad de depender del valor de retorno. Considera ambos ejemplos:

// ejemplo uno
void foo(int variable)
{
variable += 50;
}

int main()
{
int i = 1;
cout << i << endl;
foo(i);
cout << i << endl;
return EXIT_SUCCESS;
}

// ejemplo 2
void foo(int* p)
{
*p += 50;
}

int main()
{
int i = 1;
cout << i << endl;
foo(&i);
cout << i << endl;
return EXIT_SUCCESS;
}

El primer programa imprime:
1
1
Mientras que el segundo, imprime:
1
51
¿Notas la diferencia? En el primer programa foo no modificó la variable porque se creó una copia de ésta al entrar a la función. En el segundo ejemplo, pasamos la dirección en memoria de i, y entonces el parámetro de foo apuntaba a la variable i original. Por ello es que sí se modificó esa variable.

Ahora bien, void en C significa que el tipo de dato es "desconocido" o mejor dicho, "indefinido". Con void* lo que se pretende es que pases cualquier dirección de memoria, no importando su tipo. Sin embargo, void* es una fuente constante de comportamiento indefinido, así que su uso debería limitarse a lo estríctamente necesario. En C++, deberías usar templates en lugar de void* cada vez que sea posible.

Los punteros se emplean para apuntar hacia bloques de memoria que uno aparta directamente, y del cuál el compilador no se hace responsable. Supongamos que quieres que una variable cualquiera perdure aún después de salir del ámbito de la función. Entonces, empleas un puntero al tipo de dato deseado y la creas y destruyes empleando malloc/free en C, o bien new/delete en C++. Una nota: aunque en C++ también puedes emplear malloc y free, cuando trates con una clase es recomendable que emplees new y delete, ya que aparte de que new ubica memoria y delete la libera, new manda llamar al constructor de la clase y delete al destructor (y eso depende del compilador). Si es una estructura sin métodos, también puedes emplear malloc y free sin problemas.

Otro punto es el operador * de dereferencia. Si p es un puntero a una variable, entonces *p ES el valor de dicha variable. El operador -> te sirve para acceder a los miembros de una clase/estructura/unión de un apuntador. Por ejemplo:

struct A
{
int a, b, c;
};

int main()
{
struct A variable = {10, 20, 30};
struct A* puntero;

puntero = &variable; //puntero apuntará a variable

// imprimen el mismo valor
cout << variable.a << endl;
cout << puntero->a << endl;

// cualquiera de las dos opciones siguientes es exactamente lo mismo
cout << variable.a << endl;
cout << (*puntero).a << endl;
cout << (&variable)->a << endl;

return EXIT_SUCCESS;
}

Finalmente, this es un puntero a la misma estructura/clase que contiene el método ejecutándose al momento. Ejemplo:

class A
{
public:
int a;
void asignar(int a)
{
// a = a; sería incorrecto por ambigüedad en el nombre de la variable. Mejor:
this->a = a; // en este momento, this es un puntero a A.
}
};

int main()
{
A a;
a.asignar(10);
return EXIT_SUCCESS;
}

Saludos.

Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar