Contenido del Curso
Fundamentos de C
Fundamentos de C
Funciones, Arreglos y Dos Punteros
Funciones con Punteros
Vamos a experimentar con una función básica para modificar el valor de nuestros datos. Por ejemplo, imagina que necesitas una función que convierta kilo-Ohms a Ohms (1 kOhm = 1000 Ohm).
Main
#include <stdio.h> void Ohm(double R) { R = R * 1000; } int main() { double r = 1.5; // kOhm printf("The value of resistance before using function: %f\n", r); Ohm(r); printf("The value of resistance after using function: %f", r); return 0; }
Nuestro intento de cambiar el valor de la variable r
fue infructuoso. Esto se debe a que la función recibe una copia de la variable r
, no el valor real en sí.
Para que nuestro programa funcione como se pretende, necesitamos pasar la dirección de la variable r
a la función. Como resultado, la función Ohm
debería aceptar double*
en lugar de solo double
.
Main
#include <stdio.h> void Ohm(double* R) { // dereferencing the entered address and changing the object it points to *R = *R * 1000; } int main() { double r = 1.5; // kOhm printf("The value of resistance before using function: %f\n", r); Ohm(&r); printf("The value of resistance after using function: %f\n", r); return 0; }
Nota que referenciamos la variable r
dos veces. Después de invocar la función Ohm
, el valor de r
es alterado. Esto se debe a que la función recibió la dirección original de la variable r
, no una mera copia, y luego modificó el valor en esa dirección particular.
Además, una función puede devolver un puntero a un objeto que ha generado:
Main
#include <stdio.h> #include <stdlib.h> int* func() { int* x = (int*)malloc(sizeof(int)); printf("Address into function: %p\n", x); return x; } int main() { int* pointerToFunc = func(); printf("Address after using function: %p\n", pointerToFunc); return 0; }
¿Son los Arreglos Simplemente Punteros?
¿Qué predices que ocurrirá si se añade un número a una dirección?
Main
#include <stdio.h> int main() { int x = 100; int* pX = &x; printf("Address: %p | Adress + 1: %p", pX, pX + 1); return 0; }
Cuando se añade un número (pX + 1
) a una dirección, ¡se obtiene la dirección de la siguiente celda de memoria!
Vamos a escribir un bucle para navegar por la "secuencia" de RAM:
Main
#include <stdio.h> int main() { int* pX = NULL; // pointer to `int` type (4 bites) for (int i = 0; i < 3; i++) printf("Address: %p\n", pX + i); return 0; }
Hemos proyectado tres pasos adelante. Es evidente a partir de las direcciones derivadas que hay una jerarquía clara.
Dado que el tipo int
ocupa 4 bytes, avanzamos 4 bytes con cada paso. ¡Este comportamiento es sorprendentemente similar a un arreglo!
¡Parece que un arreglo es esencialmente una dirección fija (representada por el nombre del arreglo) junto con memoria asignada. Los índices de los elementos representan su desplazamiento desde la dirección del elemento inicial!
Esta noción puede ser validada con el siguiente programa:
Main
#include <stdio.h> int main() { int array[] = {1,2,3,4,5}; printf("Address of array: %p\n", array); for(int i = 0; i < 5; i++) printf("Value: %d | Address of element with index %d: %p\n", *(array + i), i , &array[i]); return 0; }
Como se observa, no recorremos directamente el arreglo. Únicamente utilizamos su dirección, específicamente la dirección de su elemento inicial.
¡Gracias por tus comentarios!