¡Bienvenido!

Al registrarte con nosotros, podrás discutir, compartir y enviar mensajes privados con otros miembros de nuestra comunidad.

¡Regístrate ahora!

Punteros en 5 minutos C/C++

  • Iniciador del tema Iniciador del tema IOSTD
  • Fecha de inicio Fecha de inicio
I

IOSTD

Invitado
Piensa en la memoria como una matriz de bits que se agrupan en 8 y forman byte, cada byte tiene una dirrección en esa matriz con el cual lo podemos identificar

Nota: los bits no tienen dirección porque actualmente se trabaja con byte todo los tipos de datos usan byte

Ahora un puntero es una variable que contiene una dirrección de memoria

Para obtener la dirección de memoria de una variable x se usa el operador &

C:
int x;
printf("La dirrección de x es %p, &x);
Esto nos dara la dirrección del primer byte donde se encuentra x pero esto no nos importa lo que nos importa es que esto sea un puntero a x

Ahora como guardo esto pues en una varíable de tipo puntero

int x;
int *puntero = &x;

Recuerda que un puntero de tipo int solo puede contener direcciones de memoria que referencien a una variable de tipo int

Desferenciacion


Cuando tienes un puntero que guarde la dirección de una variable puedes puedes usar la variable original atraves del puntero

Con esto quiero decir que si tiene una variable i y tiene un puntero desferenciado p puedes acceder a i y modificarla desde p

C++:
int i;
int *p = &i;

//i vale 20
i = 20;

//Aqui i vale 30
*p = 30;

Note que el * hace diferentes cosas en los diferentes casos

Y ya con esto puedes pasarle un puntero a una función y desferenciarlo dentro de la función y con ello modificar la variable desde la función ignorando todo XD

Alguna duda o algun error que cometí me dicen!
 
Un poco más de información sobre los punteros.

Conversión explícita de tipo (cast)
Convertir un puntero a otro tipo no convierte su contenido. Esto puede resultar en un valor inconsistente. Por ejemplo, tenemos:
C++:
float foo = 42;
float *pfoo = &foo;
Si hacemos esto:
C++:
int bar = *((int *) pfoo);
Obtenemos el valor 1109917696 (asumiendo que se use IEEE 754), al ser la representación de float distinta a la de int.

Esto es mucho peor en máquinas Big-Endian (ej. PowerPC y MIPS), ya que la posición del primer byte dependería del tamaño del tipo de dato.

Lo correcto sería:
C++:
int bar = (int) (*pfoo);

Aritmética
Los punteros en C/C++ soportan operaciones de suma/resta. Estas funcionan en incrementos equivalentes al tamaño del tipo de datos base:
C++:
uint32_t *foo = (uint32_t *) 0x800;
foo++;
Luego de esto, foo apunta a la dirección 0x804, ya que el tamaño de uint32_t es 4.

En otras palabras, foo[1] es lo mismo que *(foo+1). Lo cual nos lleva al siguiente punto.

Arreglos
En la mayoría de las operaciones, cuando se hace referencia a un arreglo se toma de manera implícita la dirección de su primer elemento. Por ejemplo:
C++:
char foo[] = "hola, mundo!";
char *bar = foo; // nótese la ausencia del &
auto baz = foo; // sigue siendo char*
char first_char = *foo; // 'h'
char second_char = bar[1]; // 'o'
Una excepción notable sería sizeof:
C++:
unsigned size_of_foo = sizeof(foo); // 13, contando el NUL al final del string
unsigned size_of_bar = sizeof(bar); // puede ser 2, 4, 8 o algo más exótico; depende de la ISA
 
Última edición:
Piensa en la memoria como una matriz de bits que se agrupan en 8 y forman byte, cada byte tiene una dirrección en esa matriz con el cual lo podemos identificar
Aclarar que se trata de una matriz de n x 1 (o mejor, un vector en un sub-espacio de Zⁿ; o un arreglo de bytes, para no complicarse), no vaya a ser que alguien se confunda y piense que es una estructura de 2 dimensiones. No voy a profundizar mucho en eso porque da para un tema completo.
 
Atrás