Punteros en C: ¿Qué es la programación con punteros en C? Tipos
⚡ Resumen inteligente
En C, los punteros son variables que almacenan la dirección de memoria de otra variable. Permiten la asignación dinámica de memoria, el manejo eficiente de matrices y cadenas, y estructuras de datos complejas, utilizando los operadores de dirección y desreferenciación para leer o modificar valores.

¿Qué es un puntero en C?
A puntero En C, un puntero es una variable que almacena la dirección de otra variable. Un puntero también puede hacer referencia a otro puntero o a una función. Un puntero se puede incrementar o decrementar para apuntar a la siguiente o anterior ubicación de memoria. El propósito de un puntero es ahorrar espacio de memoria y lograr un tiempo de ejecución más rápido.
Cómo utilizar punteros en C
Si declaramos una variable `v` de tipo `int`, `v` almacena un valor. Cada variable, además de su valor, tiene una dirección, es decir, su ubicación en la memoria. La dirección se puede obtener anteponiendo el símbolo `&` al nombre de la variable. Si se imprime la dirección de una variable, aparece como un número aleatorio que puede variar en cada ejecución.
En lugar de almacenar un valor, un puntero almacena la dirección de una variable. Por ejemplo:
int *y = &v;
| VARIABLE | PUNTERO |
|---|---|
| A valor almacenado en un llamado dirección de almacenamiento/memoria. | A variable que puntos a la dirección de almacenamiento/memoria de una alternativa, variable. |
Declarar un puntero
Como variables, punteros en Programación en C Deben declararse antes de poder utilizarse. La declaración de un puntero tiene la siguiente forma:
data_type *pointer_variable_name;
Aquí, tipo de datos es el tipo base del puntero e indica el tipo de la variable a la que apunta el puntero. El asterisco (*), el mismo símbolo que se usa para la multiplicación, es el operador de indirección que declara un puntero. Algunas declaraciones de puntero válidas son:
int *ptr_thing; /* pointer to an integer */ int *ptr1, thing; /* ptr1 points to an int; thing is an int */ double *ptr2; /* pointer to a double */ float *ptr3; /* pointer to a float */ char *ch1; /* pointer to a character */
Inicializar un puntero
Tras declarar un puntero, lo inicializamos con una dirección de variable. Si un puntero no está inicializado y se utiliza, los resultados pueden ser impredecibles y potencialmente desastrosos. Para obtener la dirección de una variable, utilice el operador de ampersand (&) antes del nombre de la variable:
pointer = &variable;
A continuación se muestra un programa sencillo que ilustra el funcionamiento de un puntero:
#include <stdio.h> int main() { int a = 10; // variable declaration int *p; // pointer variable declaration p = &a; // store address of a in pointer p printf("Address stored in p is: %x\n", p); // access the address printf("Value stored in p is: %d\n", *p); // access the value return 0; }
Salida:
Address stored in p is: 60ff08 Value stored in p is: 10
| Operator | Significado |
|---|---|
| * | Cumple dos funciones: declara un puntero y devuelve el valor de la variable a la que hace referencia (desreferenciación). |
| & | Tiene un único propósito: devolver la dirección de una variable. |
Tipos de punteros en C
Puntero nulo
Creamos un puntero nulo asignándole el valor NULL durante la declaración. Esto es útil cuando aún no se ha asignado ninguna dirección al puntero. Un puntero nulo siempre contiene el valor 0.
#include <stdio.h> int main() { int *p = NULL; // null pointer printf("The value inside variable p is: %x", p); return 0; }
Puntero vacío
Un puntero void, también llamado puntero genérico, no tiene ningún tipo de dato estándar. Se crea utilizando la palabra clave void y puede almacenar la dirección de cualquier variable:
#include <stdio.h> int main() { void *p = NULL; // void pointer printf("The size of pointer is: %d\n", sizeof(p)); return 0; }
Punta salvaje
Un puntero se denomina puntero salvaje si no está inicializado con ningún valor. Estos punteros no son eficientes porque pueden apuntar a una ubicación de memoria desconocida, lo que puede causar problemas y provocar que el programa falle. Siempre tenga cuidado con los punteros salvajes.
#include <stdio.h> int main() { int *p; // wild pointer printf("%d", *p); return 0; }
Otros tipos de punteros en C incluyen el puntero colgante, el puntero complejo, el puntero cercano, el puntero lejano y el puntero enorme.
Punteros de acceso directo e indirecto
En C, existen dos formas equivalentes de acceder y manipular el contenido de una variable. El acceso directo utiliza el nombre de la variable directamente, mientras que el acceso indirecto utiliza un puntero a la variable:
#include <stdio.h> int var = 1; /* declare and initialize an int variable */ int *ptr; /* declare a pointer to int */ int main(void) { ptr = &var; /* point ptr to var */ printf("\nDirect access, var = %d", var); printf("\nIndirect access, var = %d", *ptr); *ptr = 48; /* change var through the pointer */ printf("\nIndirect access, var = %d", *ptr); return 0; }
Aritmética de punteros en C
Al trabajar con punteros, observe estas reglas de prioridad. Los operadores * y & tienen la misma prioridad que los operadores unarios (negación !, incremento ++, decremento –). En la misma expresión, los operadores unarios *, &, !, ++ y — se evalúan de derecha a izquierda. Si un puntero P apunta a una variable X, entonces *P se puede usar dondequiera que se pueda escribir X. Las siguientes expresiones son equivalentes:
| expresión | Expresión equivalente |
|---|---|
| Y = *P + 1 | Y = X + 1 |
| *P = *P + 10 | X = X + 10 |
| *P += 2 | X += 2 |
| ++*P | ++X |
| (*P)++ | X ++ |
En el último caso, se requieren paréntesis: dado que los operadores unarios * y ++ se evalúan de derecha a izquierda, sin paréntesis se incrementaría el puntero P, no el objeto al que apunta. Las operaciones aritméticas disponibles para los punteros son la asignación, el incremento y el decremento, y la suma o la resta.tracutilizando un desplazamiento entero, que mueve el puntero esa cantidad de elementos (cada paso es igual al tamaño en bytes del tipo base).
Punteros y arreglos en C con ejemplos
Tradicionalmente, accedemos a los elementos de un array mediante un índice, pero los punteros también facilitan esto. Un puntero configurado con el nombre del array apunta al primer elemento:
#include <stdio.h> int main() { int a[5] = {1, 2, 3, 4, 5}; // array initialization int *p; // pointer declaration p = a; // p points to the first element; same as &a[0] for (int i = 0; i < 5; i++) { printf("%d\n", *p); // print element p++; // move to the next element } return 0; }
Sumar un número a un puntero lo mueve esa cantidad de posiciones hacia adelante. Si p apunta a la ubicación de memoria 0, entonces p + 1 hace que el puntero apunte a la ubicación de memoria 1.
Punteros C y cadenas con ejemplos
Una cadena es una matriz de objetos char que termina con el carácter nulo '\0'. Podemos manipular cadenas usando punteros:
#include <stdio.h> #include <string.h> int main() { char str[] = "Hello Guru99!"; char *p; p = str; printf("First character is: %c\n", *p); p = p + 1; printf("Next character is: %c\n", *p); p = str; // reset the pointer for (int i = 0; i < strlen(str); i++) { printf("%c\n", *p); p++; } return 0; }
Otra forma de trabajar con cadenas es mediante una matriz de punteros:
#include <stdio.h> int main() { char *materials[] = {"iron", "copper", "gold"}; for (int i = 0; i < 3; i++) printf("%s\n", materials[i]); return 0; }
Ventajas de los punteros en C
- Los punteros son útiles para acceder directamente a las ubicaciones de memoria.
- Proporcionan una forma eficiente de acceder a los elementos de una matriz.
- Se utilizan para la asignación y liberación dinámica de memoria.
- Se utilizan para formar estructuras de datos complejas, como listas enlazadas, grafos y árboles.
Desventajas de los punteros en C
- Los punteros son un poco complejos de entender.
- Pueden provocar errores como fallos de segmentación o acceso a una ubicación de memoria no deseada.
- Un valor incorrecto asignado a un puntero puede provocar corrupción de memoria.
- Los punteros también son responsables de las fugas de memoria si esta no se libera.
- Es responsabilidad del programador manejar los punteros con cuidado.
