C/C++ · 11 min read · Oct 11, 2025
Aprendiendo C/C++ Paso a Paso - Página 9
09. Paso a Paso C/C++ — Programación en C - Punteros
Punteros
| | 1. Acerca de la Memoria
- Esquema de Direccionamiento
- Cómo encontrar la dirección de una Variable
- Punteros
- Aritmética de Punteros
- Punteros y Arreglos
- Punteros y Cadenas
- Glosario |
1. Acerca de la Memoria
La computadora tiene la característica de almacenar datos y manipularlos. El almacenamiento de datos requiere un dispositivo de almacenamiento, que sea cómodo para almacenar y recuperar datos de manera rápida y precisa sin confusión. Comúnmente, la computadora tiene que comprometerse con dos métodos de almacenamiento.
| | |
SRAM Memoria de Acceso Aleatorio Estática
DRAM Memoria de Acceso Aleatorio Dinámica
EEPROM Memoria de Solo Lectura Programable Electrónicamente Borrable
Los chips de memoria pueden almacenar datos, instrucciones y resultados intermedios y finales. La memoria está organizada en bytes, cada byte capaz de almacenar un carácter de información. Cada byte de memoria tiene una dirección o número de ubicación, que lo identifica de manera única. El tamaño de la memoria se mide en kilobytes (KB), megabytes (Mb), gigabytes o terabytes (TB).
RAM:
El dispositivo de memoria es una ubicación de almacenamiento para guardar información.
El recurso vital de la computadora, la memoria, se asigna a cada una de las variables después de su declaración en el programa C. El tipo de variable decide el número de bytes de memoria que se asignarán a cada variable.
| |
|
2. Esquema de Direccionamiento
| |
|
La imagen anterior te dice la siguiente información.
| | 1. La RAM es una memoria temporal y una parte de la computadora.
- Puede contener el valor del programa.
- Cada byte en la RAM está identificado con un número positivo único llamado dirección.
- Las direcciones son como números, así como lo son para las casas en una calle.
- El número comienza en 0 y sube desde allí 1-2-3 y así sucesivamente.
- Si tenemos 640 KB de memoria, la dirección más alta es 655,359; para 1 MB de memoria es 1,048,575.
- Nuestro programa, cuando se carga en la memoria, ocupa un cierto rango de estas direcciones.
- Eso significa que cada variable y cada función en nuestro programa comienza en una dirección particular. |
3. Cómo encontrar la dirección de una Variable
En la última sección, el punto 8 dice que cada variable/función comienza en una dirección particular. Las direcciones son números positivos únicos en formato hexadecimal.
Encontrar la dirección de una variable es una tarea simple a través del operador & ( dirección de).
& ( dirección de ) - Puede decirte la dirección de la variable / función en el programa actual.
El siguiente programa demuestra cómo encontrar la dirección de una variable ‘a’
| | / 58_address.c /
#include
int main()
{
int a = 10;
printf(“\n Valor de A es : %d”, a);
printf(“\n Dirección de A es : %d”, &a);
return 0;
} |
Reemplaza los valores de formato marcados anteriormente con el siguiente formato para obtener el valor absoluto de la dirección hexadecimal.
0x%x
Ej.
printf("\nDirección de A es : 0x%x", &a);Programa para encontrar la dirección de la función ‘disp()’
| | / 59_address.c /
#include
void disp()
{
printf(“\nHola”);
printf(“\n¿Cómo estás?”);
printf(“\nTú”);
} int main()
{
disp();
printf(“\nDirección de disp() : 0x%x”, &disp);
return 0;
} |
4. Punteros
De acuerdo con la última sección, sabemos cómo encontrar y mostrar la dirección de una variable/función.
Esta vez aprenderemos cómo almacenar la dirección de una variable/función en otra variable.
Nota: Las variables pueden contener valores constantes.
| | Intenta con lo siguiente: int a, b;
a = 5; / Válido /
b = &a; / Inválido / Nuevamente intenta con lo siguiente: int a, b;
a = 5; / Válido /
b = &a; / Válido */ |
b = &a; ¡correcto! Sí, las variables (variables generales) no pueden contener direcciones. Pero las variables precedidas con ‘*’ (Variables Puntero) pueden contener tanto valores constantes como la dirección de otras variables/funciones.
Puntero: Variable que contiene valores de dirección.
| | Variables (Generales)
La variable general realiza solo una operación para contener valores constantes | Variables puntero (Variables precedidas con ‘*’)
Las variables puntero pueden realizar dos operaciones para contener valores constantes así como valores de dirección de otras variables/funciones |
Referencia a / Puntero a / Contenido en dirección (*)
int *ptr;Para los no iniciados, esta es una sintaxis bastante extraña. El asterisco significa puntero a. Así, la declaración define la variable ptr como un puntero a int. Esta es otra forma de decir que la variable puede contener la dirección de variables enteras.
| | Si lo llamamos, tipo puntero, podríamos escribir la declaración así.
puntero ptr; /* inválido */
``` El problema es que el compilador necesita saber qué tipo de variable apunta el puntero. |
| | Declaración de una variable puntero
char *cptr; /* Puntero a carácter */
int *iptr; /* Puntero a int */
float *fptr; /* Puntero a float */
struct emp *e; /* Puntero a datos abstractos emp e */ |
#### Accediendo a la variable apuntada:
Aquí hay una forma especial de acceder a los valores de una variable usando su dirección en lugar de su nombre.
| | /* 60_addr.c */
#include
int main()
{
int var1 = 11; /* variable var1 = 11 */
int *ptr; /* Variable ptr como puntero a */
ptr = &var1; /* Mantener la dirección de var1 en ptr */
printf("Valor de var1 es %d", *ptr); /* Puntero a la dirección de var1 */
return 0;
} |
| |  |
Si la declaración es printf ("%d", ptr); entonces muestra el valor de ptr, es decir, la dirección de var1, pero la declaración anterior puede mostrar el contenido de la dirección, que se almacenó en la variable ptr.
Programa para demostrar el uso de Dirección_De y Puntero_A
| | /* 61_ptrdemo.c */
#include
int main()
{
int a = 10, *p; /* Entero a y puntero p */
p = &a; /* Asignar dirección de a a p */
printf("\nValor de A : %d", a); /* Contenido de a */
printf("\nDirección de A : 0x%x", &a); /* Dirección de a */
printf("\nValor de P : 0x%x", p); /* Contenido de p */
printf("\nDirección de P : 0x%x", &p); /* Dirección de p */
printf("\nContenido en dirección de a : %d", *p); /* Puntero a &a */
return 0;
} |
#### 5. Aritmética de Punteros
Todas las variables pueden soportar operaciones aritméticas, así como también podemos realizar operaciones aritméticas en punteros. El lenguaje C/C++ puede soportar 4 operaciones aritméticas en punteros, a saber.
| | Operación
Adición
Sustracción
Incremento
Decremento | Símbolo
+
-
++
-- |
Nota: La característica principal de la aritmética de punteros es que los operadores anteriores se aplican en bytes con referencia a su tipo de variable.
| | /* 62_ptr.c */
/* Demostración de aritmética de punteros */
#include
int main()
{
int a, *p;
a = 100;
p = &a;
(*p)++; /* Incrementar puntero a (contenido en dirección) en 1 */
printf("%d", *p);
return 0;
} |
| | Salida
101 |
Demostración de la aritmética de punteros, Incrementar el valor de la dirección
| | /* 63_ptr.c */
/* Incrementar el valor de la dirección en 1 */
#include
int main()
{
int a, *p;
a = 100;
p = &a;
*p++; /* Incrementar el valor de la dirección en p en 1 */
printf("%d", *p);
return 0;
} |
| | Salida
Salida inesperada |
El programa anterior ilustra los operadores aritméticos con respecto tanto al valor como a la incrementación de la dirección. p es una variable puntero y a se asigna con 100, así como p se asigna con la dirección de a.
Ahora *p++ afecta a incrementar o realmente saltar la memoria en 2 bytes para obtener una nueva dirección y su contenido.
Si es **(*p)++, entonces el contenido apuntado por p** es 100, se incrementa, resultando en 101.
#### 6. Punteros y Arreglos
En el lenguaje C/C++, los tipos de datos punteros y arreglos se asemejan entre sí. Los elementos del arreglo se refieren así como la variable puntero, ambos se utilizan para contener la dirección de los elementos de datos en memoria.
| | char name[20];
O
char *name ;
char months[12][10];
O
char **months; |
Hay una estrecha asociación entre punteros y arreglos. Aquí hay una revisión sobre arreglos.
| | /* 64_ptrarr.c */
#include
int main()
{
int i, a[5] = { 56, 43, 78, 98, 12 };
for( i = 0; i < 5; i++)
printf("\n%d", a[i]);
return 0;
} |
Hay una posibilidad de acceder a los elementos del arreglo usando la notación de puntero.
Encuentra la salida del siguiente programa.
| | /* 65_ptrarr.c */
#include
int main()
{
int i, a[5] = { 56, 43, 78, 98, 12 };
for( i = 0; i < 5; i++)
printf("\n%d", *(a + i) );
return 0;
} |
Sigue el siguiente programa:
| | /* 66_ptrarr.c */
#include
int main()
{
int i, a[ ] = { 56, 43, 78, 98, 12 }, *p;
p = a;
for( i = 0; i < 5; i++)
printf("\n%d", *(p + i) );
return 0;
} |
Aquí hay un enfoque más fácil para imprimir los elementos del arreglo dado (no se requiere tamaño).
| | /* 67_ptrarr.c */
#include
int main()
{
int i, a[ ] = { 56, 43, 78, 98, 12 }, *p;
p = a;
while (*p) /* o for(int i = 0; i<5; i++ ) */
printf("\n%d", *p++);
return 0;
} |
#### 7. Punteros y Cadenas
Una cadena es una colección de caracteres que incluye espacios. Esta vez discutimos cómo manejar cadenas usando punteros. No más discusiones para crear confusión. Aquí está la tarea simple para verificar tanto puntero como arreglo de cadenas.
Hay una sutil diferencia entre cadenas y punteros, sigue el programa.
| | /* 68_ptrstr.c */
#include
int main()
{
char str1[ ] = "Te gustaría explorar C.";
char *str2 = "Te gustaría explorar C.";
puts(str1);
puts(str2);
str1++; /* Expresión inválida */
str2++; /* Expresión válida */
puts(str2); /* imprime ou gustaría explorar…… */
return 0;
} |
Cadenas como Argumentos de Función
Una variable puntero es más flexible que las variables de arreglo, aquí está el programa para demostrar y mostrar una cadena con notación de puntero.
| | /* 69_ptrarr.c */
#include
void disp(char *p);
int main()
{
char str[ ] = "¡Hola!!..¡Hola!!.. ¿Los punteros pueden manejarlo?";
disp(str);
return 0;
} void disp(char *p)
{
while(*p)
printf("%c", *p++);
} |
Arreglo de punteros a cadenas
Hay una desventaja al almacenar un arreglo de cadenas, en que los subarreglos que contienen la cadena deben tener todos la misma longitud. Por lo que se desperdicia espacio cuando las cadenas son más cortas que los subarreglos.
Aquí está la solución:
| | /* 70_strings.c */
#include
int main()
{
char *weeks[7 ] = { "Domingo", "Lunes", "Martes", "Miércoles",
"Jueves", "Viernes", "Sábado" };
int i;
for( i = 0; i<7; i++)
puts(weeks[ i ] );
return 0;
} |
Cuando las cadenas no son parte de un arreglo, C/C++ las coloca contiguas en memoria, por lo que no hay espacios desperdiciados.
**/* Un programa de ejemplo para contener un arreglo de punteros de tipo ‘int’ */**
| | /* 71_ptrarr.c */
#include
int main()
{
int *arr[4]; /* Arreglo de punteros a int */
int i = 31, j = 5, k = 19, l = 71, m;
arr[0] = &i;
arr[1] = &j;
arr[2] = &k;
arr[3] = &l;
for(m = 0; m <= 3; m++)
printf("\n%d", *(arr[m]) );
return 0;
} |
Una mirada a las Funciones de Biblioteca
Ya estamos familiarizados con las funciones estándar de cadenas. Tienen argumentos de cadena que se especifican usando notación de puntero,
Si tenemos claro el concepto de punteros y cadenas, podemos escribir nuestras propias funciones de cadena.
Aquí hay un programa de ejemplo para copiar cadenas.
**/* Copia una cadena a otra con punteros */**
| | /* 72_strcpy1.c */
#include
void strcpy1(char * dest, char *src);
int main()
{
char *str1 = "¿Cómo puedo aprender más sobre C/C++ !!!";
char *str2;
strcpy1(str2, str1);
puts(str2);
return 0;
} void strcpy1(char * dest, char *src)
{
while(*src)
*dest++ = *src++;
*dest = '\0';
} |
#### 8. Glosario
| Dirección | Un valor que apunta a una ubicación en memoria. Un puntero contiene la dirección o ubicación de un valor, en lugar del valor en sí. |
| Arreglo | Un arreglo es una colección de elementos de datos del mismo tipo. |
| Contiguo | Una característica de almacenamiento que especifica que los valores se almacenan en ubicaciones consecutivas, ya sea en memoria o en disco. |
| Función | Una serie de instrucciones para realizar una tarea específica, que se puede combinar con otras funciones para crear un programa. |
| Memoria | Descriptivo de un dispositivo o medio que puede aceptar datos, mantenerlos y entregarlos a demanda en un momento posterior. Sinónimo de almacenamiento. |
| Puntero | Contiene la dirección o ubicación de memoria de un valor, en lugar del valor en sí. |
| RAM | (Memoria de Acceso Aleatorio) 1. Un dispositivo de almacenamiento estructurado de tal manera que el tiempo requerido para recuperar datos no se ve afectado significativamente por la ubicación física de los datos. 2. La *sección de almacenamiento primaria* de una computadora personal. |
| Cadena | Un arreglo capaz de almacenar cero o más caracteres. En C, una cadena se declara como un arreglo de caracteres con el carácter NULL (\0) agregado para especificar el final de la cadena. |
| Variable | Un nombre asociado con una ubicación en memoria cuyo valor puede cambiar durante la ejecución del programa. | Recibe nuevas publicaciones en tu bandeja de entrada.
No spam. Cancela la suscripción en cualquier momento.