Hola @Julia13
En C, un puntero es una variable que hace referencia a una dirección de memoria, que a su vez hace referencia a un dato.
Teniendo el siguiente código:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int x;
int *y = &x;
x = 3;
return EXIT_SUCCESS;
}
Se crean dos variables. Una de tipo entero y otra un puntero que apunta a un entero.
Primero se asigna el valor
3 en la variable
x, y después se asigna el valor de
x a
y. Se puede notar claramente un operador
*, que desreferencia y permite la lectura y la escritura de lo que haya allí en esa variable.
En realidad esta no es la única forma de asignar un valor de una variable a otra.
y = &x;
Lo que hará el operador
& será obtener la dirección de
x y se la asignará a
y, entonces ahora las dos variables apuntarán al mismo dato, pero para acceder a él, es de forma distinta.
Los punteros también son muy útiles para manejar arreglos y que a su vez pueden ser pasados a funciones.
#include <stdio.h>
#include <stdlib.h>
int sum_array(int *array, int length)
{
int result = 0;
while (length--)
result += array[length];
return result;
}
int main(void)
{
int n_array[] = { 1, 2, 3, 4 };
int result = sum_array(n_array, sizeof(n_array)/sizeof(n_array[0]));
return EXIT_SUCCESS;
}
Lo que sucede en este pequeño programa es que se pasa a la función dos argumentos: el primero es la dirección donde comienza el arreglo y el segundo argumento es la cantidad de elementos que contiene.
En realidad no se ve prácticamente nada de lo que sucede. Veamos este pequeño programa en
nasm:
section .data
n_array: dq 1, 2, 3, 4
n_array_length: equ ($-n_array)/8
section .text
global _start
_start:
mov rsi, n_array
mov rcx, n_array_length
xor rax, rax
xor rbx, rbx
.loop:
add rax, [rsi+rbx*8]
inc rbx
loop .loop
Si mira en la sección de datos se creó
n_array, que básicamente es el inicio del arreglo de datos que se ven allí. Si mira la línea
8 se coloca la dirección de inicio en el registro
rsi, y mucho después en el bucle
.loop, se comienza a obtener los datos para sumarlo en el acumulador
rax. Vea [rsi+rbx*8], prácticamente sería como un equivalente al operador
* de C, ya que se obtiene ese dato al que apunta el resultado de la operación de sumar el registro
rsi con
rbx (multiplicado por 8, ya que cada dato del arreglo n_array pesa 8 bytes).
Este programa no se debe ejecutar como uno común, ya que nunca le pide al sistema que salga, pero para estos fines, está perfecto. Hay que mirar desde el depurador, que en mi caso es gdb.
(gdb) break _start
Breakpoint 1 at 0x201160
(gdb) r
Starting program: /tmp/main
Breakpoint 1, 0x0000000000201160 in _start ()
(gdb) disassemble _start
Dump of assembler code for function _start:
=> 0x0000000000201160 <+0>: movabs $0x202180,%rsi
0x000000000020116a <+10>: mov $0x4,%ecx
0x000000000020116f <+15>: xor %rax,%rax
0x0000000000201172 <+18>: xor %rbx,%rbx
End of assembler dump.
(gdb) disassemble '_start.loop'
Dump of assembler code for function _start.loop:
0x0000000000201175 <+0>: add (%rsi,%rbx,8),%rax
0x0000000000201179 <+4>: inc %rbx
0x000000000020117c <+7>: loop 0x201175 <_start.loop>
End of assembler dump.
(gdb) nexti
0x000000000020116a in _start ()
(gdb)
0x000000000020116f in _start ()
(gdb)
0x0000000000201172 in _start ()
(gdb)
0x0000000000201175 in _start.loop ()
(gdb)
0x0000000000201179 in _start.loop ()
(gdb)
0x000000000020117c in _start.loop ()
(gdb)
0x0000000000201175 in _start.loop ()
(gdb)
0x0000000000201179 in _start.loop ()
(gdb)
0x000000000020117c in _start.loop ()
(gdb)
0x0000000000201175 in _start.loop ()
(gdb)
0x0000000000201179 in _start.loop ()
(gdb)
0x000000000020117c in _start.loop ()
(gdb)
0x0000000000201175 in _start.loop ()
(gdb)
0x0000000000201179 in _start.loop ()
(gdb)
0x000000000020117c in _start.loop ()
(gdb)
0x000000000020117e in ?? ()
(gdb) print $rax
$1 = 10
(gdb)
Se recorre todo el arreglo haciendo la misma operación y al final el resultado estará en el registro rax.
Espero le haya servido.
~ DtxdF