From feb4088f040b7dc80822a5c0c4c690798235f200 Mon Sep 17 00:00:00 2001 From: Jeovani Marcos Morales Nieto Date: Sun, 17 Mar 2024 07:58:20 +0100 Subject: [PATCH 1/5] Create Punteros.md --- tutorials/learn-c.org/es/Punteros.md | 55 ++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 tutorials/learn-c.org/es/Punteros.md diff --git a/tutorials/learn-c.org/es/Punteros.md b/tutorials/learn-c.org/es/Punteros.md new file mode 100644 index 000000000..30790d3ae --- /dev/null +++ b/tutorials/learn-c.org/es/Punteros.md @@ -0,0 +1,55 @@ + +Tutorial -------- + +Los punteros también son variables y juegan un papel muy importante en el lenguaje de programación C. Se utilizan por varias razones, tales como: + +* Cadenas * Asignación de memoria dinámica * Envío de argumentos de funciones por referencia * Construcción de estructuras de datos complicadas * Apuntando a funciones * Construcción de estructuras de datos especiales (es decir, árbol, intentos, etc.) +Y muchos más. + +### ¿Qué es un puntero? + +Un puntero es esencialmente una variable entera simple que contiene una ** dirección de memoria ** que apunta a un valor, en lugar de contener el valor real en sí. + +La memoria de la computadora es un almacén secuencial de datos y un puntero apunta a una parte específica de la memoria. Nuestro programa puede usar punteros de tal manera que los punteros apunten a una gran cantidad de memoria, dependiendo de cuánto decidamos leer a partir de ese momento. + +### Cadenas como punteros + +Ya hemos hablado de las cadenas, pero ahora podemos profundizar un poco más y comprender qué son realmente las cadenas en C (que se llaman C-Strings para diferenciarlas de otras cadenas cuando se mezclan con C++). + +La siguiente línea: char * nombre = "John"; + +hace tres cosas: + +1. Asigna una variable local (pila) llamada ` nombre` , que es un puntero a un solo carácter. 2. Hace que la cadena "John" aparezca en algún lugar de la memoria del programa (después de compilarlo y ejecutarlo, por supuesto). 3. Inicializa el argumento ` nombre ` para señalar dónde reside el carácter ` J ` (que es seguido por el resto de la cadena en la memoria). + +Si intentamos acceder a la variable ` nombre` como una matriz, funcionará y devolverá el valor ordinal del carácter ` J` , ya que la variable ` nombre` en realidad apunta exactamente al comienzo de la cadena. + +Como sabemos que la memoria es secuencial, podemos asumir que si avanzamos en la memoria al siguiente carácter, recibiremos la siguiente letra de la cadena, hasta llegar al final de la cadena, marcado con un terminador nulo. (el carácter con el valor ordinal de 0, anotado como ` \0 ` ). + +### Desreferenciación + +La desreferenciación es el acto de hacer referencia a dónde apunta el puntero, en lugar de a la dirección de memoria. Ya estamos usando la desreferenciación en matrices, pero aún no lo sabíamos. El operador de corchetes - ` [0] ` por ejemplo, accede al primer elemento de la matriz. Y dado que las matrices son en realidad punteros, acceder al primer elemento de la matriz es lo mismo que desreferenciar un puntero. La desreferenciación de un puntero se realiza utilizando el operador de asterisco ` * ` . + +Si queremos crear una matriz que apunte a una variable diferente en nuestra pila, podemos escribir el siguiente código: /* definir una variable local a */ int a = 1; /* define una variable de puntero y apúntala a usando el operador & */ int * pointer_to_a = &a; printf("El valor a es %d\n", a); printf("El valor de a también es %d\n", *pointer_to_a); + + +Observe que usamos el operador ` & ` para señalar la variable ` a` , que acabamos de crear. + +Luego nos referimos a él utilizando el operador de desreferenciación. También podemos cambiar el contenido de la variable desreferenciada: int a = 1; int * puntero_a_a = &a; /* cambiemos la variable a */ a += 1; /* ¡acabamos de cambiar la variable nuevamente! */ *puntero_a_a += 1; /* imprimirá 3 */ printf("El valor de a ahora es %d\n", a); + + +Ejercicio -------- + + +Cree un puntero a la variable local ` n ` llamada ` pointer_to_n ` y utilícelo para aumentar el valor de ` n ` en uno. + +Código del tutorial ------------- #include int main() { int n = 10; / * su código va aquí * // * código de prueba * / if (pointer_to_n!= &n) return 1; si (*pointer_to_n! = 11) devuelve 1; printf("¡Listo!\n"); devolver 0; } } + + +Resultado esperado --------------- + ¡Listo! + + + +Solución -------- #include int main() { int n = 10; int * pointer_to_n = &n; *pointer_to_n += 1; / * código de prueba */ if (pointer_to_n!= &n) devuelve 1; si (*pointer_to_n! = 11) devuelve 1; printf("¡Listo!\n"); devolver 0; } } } + From d8e75b5071bb63374550770a7859183c279b0ff1 Mon Sep 17 00:00:00 2001 From: Jeovani Marcos Morales Nieto Date: Sun, 17 Mar 2024 08:09:50 +0100 Subject: [PATCH 2/5] Update Punteros.md --- tutorials/learn-c.org/es/Punteros.md | 81 +++++++++++++++++++++++----- 1 file changed, 69 insertions(+), 12 deletions(-) diff --git a/tutorials/learn-c.org/es/Punteros.md b/tutorials/learn-c.org/es/Punteros.md index 30790d3ae..6e87419f4 100644 --- a/tutorials/learn-c.org/es/Punteros.md +++ b/tutorials/learn-c.org/es/Punteros.md @@ -1,14 +1,20 @@ -Tutorial -------- - +Tutorial +-------- Los punteros también son variables y juegan un papel muy importante en el lenguaje de programación C. Se utilizan por varias razones, tales como: -* Cadenas * Asignación de memoria dinámica * Envío de argumentos de funciones por referencia * Construcción de estructuras de datos complicadas * Apuntando a funciones * Construcción de estructuras de datos especiales (es decir, árbol, intentos, etc.) +* Strings +* Asignación de memoria dinámica +* Envío de argumentos a funciones por referencia +* Construcción de estructuras de datos complicadas +* Apuntar a funciones +* Construcción de estructuras de datos especiales (es decir, árbol, intentos, etc.) + Y muchos más. ### ¿Qué es un puntero? -Un puntero es esencialmente una variable entera simple que contiene una ** dirección de memoria ** que apunta a un valor, en lugar de contener el valor real en sí. +Un puntero es esencialmente una variable entera simple que contiene una **dirección de memoria** que apunta a un valor, en lugar de contener el valor real en sí. La memoria de la computadora es un almacén secuencial de datos y un puntero apunta a una parte específica de la memoria. Nuestro programa puede usar punteros de tal manera que los punteros apunten a una gran cantidad de memoria, dependiendo de cuánto decidamos leer a partir de ese momento. @@ -16,11 +22,15 @@ La memoria de la computadora es un almacén secuencial de datos y un puntero apu Ya hemos hablado de las cadenas, pero ahora podemos profundizar un poco más y comprender qué son realmente las cadenas en C (que se llaman C-Strings para diferenciarlas de otras cadenas cuando se mezclan con C++). -La siguiente línea: char * nombre = "John"; +La siguiente línea: + + char * nombre = "John"; hace tres cosas: -1. Asigna una variable local (pila) llamada ` nombre` , que es un puntero a un solo carácter. 2. Hace que la cadena "John" aparezca en algún lugar de la memoria del programa (después de compilarlo y ejecutarlo, por supuesto). 3. Inicializa el argumento ` nombre ` para señalar dónde reside el carácter ` J ` (que es seguido por el resto de la cadena en la memoria). +1. Asigna una variable local (pila) llamada ` nombre` , que es un puntero a un solo carácter. +2. Hace que la cadena "John" aparezca en algún lugar de la memoria del programa (después de compilarlo y ejecutarlo, por supuesto). +3. Inicializa el argumento ` nombre ` para señalar dónde reside el carácter ` J ` (que es seguido por el resto de la cadena en la memoria). Si intentamos acceder a la variable ` nombre` como una matriz, funcionará y devolverá el valor ordinal del carácter ` J` , ya que la variable ` nombre` en realidad apunta exactamente al comienzo de la cadena. @@ -30,26 +40,73 @@ Como sabemos que la memoria es secuencial, podemos asumir que si avanzamos en la La desreferenciación es el acto de hacer referencia a dónde apunta el puntero, en lugar de a la dirección de memoria. Ya estamos usando la desreferenciación en matrices, pero aún no lo sabíamos. El operador de corchetes - ` [0] ` por ejemplo, accede al primer elemento de la matriz. Y dado que las matrices son en realidad punteros, acceder al primer elemento de la matriz es lo mismo que desreferenciar un puntero. La desreferenciación de un puntero se realiza utilizando el operador de asterisco ` * ` . -Si queremos crear una matriz que apunte a una variable diferente en nuestra pila, podemos escribir el siguiente código: /* definir una variable local a */ int a = 1; /* define una variable de puntero y apúntala a usando el operador & */ int * pointer_to_a = &a; printf("El valor a es %d\n", a); printf("El valor de a también es %d\n", *pointer_to_a); +Si queremos crear una matriz que apunte a una variable diferente en nuestra pila, podemos escribir el siguiente código: + /* definir una variable local a */ + int a = 1; + /* define una variable de puntero y apúntala a usando el operador & */ + int * pointer_to_a = &a; + printf("El valor a es %d\n", a); + printf("El valor de a también es %d\n", *pointer_to_a); Observe que usamos el operador ` & ` para señalar la variable ` a` , que acabamos de crear. -Luego nos referimos a él utilizando el operador de desreferenciación. También podemos cambiar el contenido de la variable desreferenciada: int a = 1; int * puntero_a_a = &a; /* cambiemos la variable a */ a += 1; /* ¡acabamos de cambiar la variable nuevamente! */ *puntero_a_a += 1; /* imprimirá 3 */ printf("El valor de a ahora es %d\n", a); +Luego nos referimos a él utilizando el operador de desreferenciación. También podemos cambiar el contenido de la variable desreferenciada: + int a = 1; + int * pointer_to_a = &a; -Ejercicio -------- + /* cambiemos la variable a */ + a += 1; + /* ¡acabamos de cambiar la variable nuevamente! */ + *pointer_to_a += 1; + /* imprimirá 3 */ + printf("El valor de a ahora es %d\n", a); +Ejercicio +-------- Cree un puntero a la variable local ` n ` llamada ` pointer_to_n ` y utilícelo para aumentar el valor de ` n ` en uno. -Código del tutorial ------------- #include int main() { int n = 10; / * su código va aquí * // * código de prueba * / if (pointer_to_n!= &n) return 1; si (*pointer_to_n! = 11) devuelve 1; printf("¡Listo!\n"); devolver 0; } } +Código del tutorial +------------- +``` +#include + +int main() { + int n = 10; + /* your code goes here */ -Resultado esperado --------------- + /* testing code */ + if (pointer_to_n != &n) return 1; + if (*pointer_to_n != 11) return 1; + + printf("Done!\n"); + return 0; +} +``` +Resultado esperado +--------------- ¡Listo! +Solución +-------- +``` +#include + +int main() { + int n = 10; + + int * pointer_to_n = &n; + *pointer_to_n += 1; -Solución -------- #include int main() { int n = 10; int * pointer_to_n = &n; *pointer_to_n += 1; / * código de prueba */ if (pointer_to_n!= &n) devuelve 1; si (*pointer_to_n! = 11) devuelve 1; printf("¡Listo!\n"); devolver 0; } } } + /* testing code */ + if (pointer_to_n != &n) return 1; + if (*pointer_to_n != 11) return 1; + printf("Done!\n"); + return 0; +} +``` From a896d7a6943ecb5ce5655b79cbcc99b19134b4a7 Mon Sep 17 00:00:00 2001 From: Jeovani Marcos Morales Nieto Date: Sun, 17 Mar 2024 08:11:09 +0100 Subject: [PATCH 3/5] Rename Punteros.md to Pointers.md --- tutorials/learn-c.org/es/{Punteros.md => Pointers.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tutorials/learn-c.org/es/{Punteros.md => Pointers.md} (100%) diff --git a/tutorials/learn-c.org/es/Punteros.md b/tutorials/learn-c.org/es/Pointers.md similarity index 100% rename from tutorials/learn-c.org/es/Punteros.md rename to tutorials/learn-c.org/es/Pointers.md From 8aba095f7e31ca4e14bf968de5d1f95e1c5e2f14 Mon Sep 17 00:00:00 2001 From: Jeovani Marcos Morales Nieto Date: Sun, 17 Mar 2024 08:43:58 +0100 Subject: [PATCH 4/5] Create Pointer Arithmetics.md --- .../learn-c.org/es/Pointer Arithmetics.md | 176 ++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 tutorials/learn-c.org/es/Pointer Arithmetics.md diff --git a/tutorials/learn-c.org/es/Pointer Arithmetics.md b/tutorials/learn-c.org/es/Pointer Arithmetics.md new file mode 100644 index 000000000..29c12406a --- /dev/null +++ b/tutorials/learn-c.org/es/Pointer Arithmetics.md @@ -0,0 +1,176 @@ + +Tutorial +--------- + +Anteriormente aprendiste qué es un puntero y cómo manipularlo. En este tutorial aprenderá las operaciones aritméticas con punteros. +Hay múltiples operaciones aritméticas que se pueden aplicar en punteros C: ++, —, -, + + +### Incrementar un puntero con (++) +Al igual que cualquier variable, la operación ++ aumenta el valor de esa variable. En nuestro caso aquí, la variable es un puntero, por lo tanto, cuando aumentamos su valor, estamos aumentando la dirección en la memoria a la que apunta ese puntero. +Combinemos esta operación con una matriz en nuestro ejemplo: + + #include + + int main() + { + int intarray[5] = {10,20,30,40,50}; + + int i; + for(i = 0; i < 5; i++) + printf("intarray[%d] tiene valor %d - y dirección @ %x\n", i, intarray[i], &intarray[i]); + + + int *intpointer = &intarray[3]; //apunta al 4º elemento del array + printf("dirección: %x - tiene valor %d\n", intpointer, *intpointer); //imprimir la dirección del 4º elemento + + intpointer++; //ahora incrementa la dirección del puntero para que apunte al 5º elemento del array + printf("dirección: %x - tiene valor %d\n", intpointer, *intpointer); //imprimir la dirección del 5º elemento + + return 0; + } + +Disminuyendo un puntero con (- -) +Al igual que en nuestro ejemplo anterior, aumentamos la dirección apuntada del puntero en uno usando el operador ++, podemos disminuir la dirección apuntada en uno usando el operador de decremento (- -). + +``` +#include + +int main() +{ + int intarray[5] = {10,20,30,40,50}; + + int i; + for(i = 0; i < 5; i++) + printf("intarray[%d] tiene valor %d - y dirección @ %x\n", i, intarray[i], &intarray[i]); + + + int *intpointer = &intarray[4]; //señala el 5º elemento de la matriz + printf("dirección: %x - tiene valor %d\n", intpointer, *intpointer); //imprime la dirección del 5º elemento + + intpointer--; //ahora disminuye la dirección del punto para que apunte al 4º elemento del array + printf("dirección: %x - tiene valor %d\n", intpointer, *intpointer); //imprime la dirección del 4º elemento + + return 0; +} +``` +### Agregar punteros con (+) +Anteriormente aumentamos en uno la dirección a la que apunta un puntero. También podemos aumentarlo en un valor entero como: + +``` +#include + +int main() +{ + int intarray[5] = {10,20,30,40,50}; + + int i; + for(i = 0; i < 5; i++) + printf("intarray[%d] tiene valor: %d - y dirección @ %x\n", i, intarray[i], &intarray[i]); + + + int *intpointer = &intarray[1]; //señala el 2º elemento de la matriz + printf("dirección: %x - tiene valor %d\n", intpointer, *intpointer); //imprime la dirección del 2º elemento + + intpointer += 2; //ahora desplaza por dos la dirección del punto para que apunte al 4º elemento del array + printf("dirección: %x - tiene valor %d\n", intpointer, *intpointer); //imprime la dirección del 4º elemento + + return 0; +} +``` +Observe cómo en la salida la dirección cambió 8 pasos en la memoria. Quizás te preguntes ¿por qué? + +La respuesta es simple: debido a que nuestro puntero es un puntero int y el tamaño de una variable int es de 4 bytes, la memoria se puede desplazar en 4 bloques. En nuestro código cambiamos 2 (agregamos +2) a la dirección inicial para que sean 2 x 4 bytes = 8. + +### Restar punteros con (-) +De manera similar podemos restar: + + #include + + int main() + { + int intarray[5] = {10,20,30,40,50}; + + int i; + for(i = 0; i < 5; i++) + printf("intarray[%d] tiene valor: %d - y dirección @ %x\n", i, intarray[i], &intarray[i]); + + int *intpointer = &intarray[4]; //apunta al 5º elemento de la matriz + printf("dirección: %x - tiene valor %d\n", intpointer, *intpointer); //imprime la dirección del 5º elemento + + intpointer -= 2; //ahora desplaza en dos la dirección del punto para que apunte al 3er elemento de la matriz + printf("dirección: %x - tiene valor %d\n", intpointer, *intpointer); //imprime la dirección del 3er elemento + + return 0; + } +nuevamente la dirección se desplaza en bloques de 4 bytes (en el caso de int). + +### Otras operaciones +Hay más operaciones como comparación >, <, ==. La idea es muy similar a comparar variables, pero en este caso estamos comparando direcciones de memoria. + +Ejercicio +---- +Copie las últimas tres direcciones de intarray en parray, que es una matriz de punteros a un int. + +Código de Tutorial +------------- + #include + + int main() { + int intarray[5] = {10,20,30,40,50}; + //-----------------------^ + int *pointer = &intarray[2]; + + // Array de 3 punteros + int *parray[3]; + + // Copia las tres últimas direcciones de intarray en parray + // Usar parray y puntero + int i; + for (i = 0; i < 3; i++) { + // Inserte aquí el código + } + + // Código de prueba + for (i = 0; i < 3; i++) { + if (parray[i] == &pointer[i]) { + printf("Coinciden!\n"); + } else { + printf("Fallan"); + } + } + + return 0; + } + +Salida Esperada +--------------- + ¡Coinciden! + ¡Coinciden! + ¡Coinciden! + +Solución +-------- + #include + + int main() { + int intarray[5] = {10,20,30,40,50}; + //-----------------------^ + int *pointer = &intarray[2]; + + int *parray[3]; + + int i; + for (i = 0; i < 3; i++) { + parray[i] = pointer + i; + } + + for (i = 0; i < 3; i++) { + if (parray[i] == &pointer[i]) { + printf("¡Coinciden!\n"); + } else { + printf("Falla\n"); + } + } + + return 0; + } From f39c0cdacde525699ab5e12c8c706aa5e49276f4 Mon Sep 17 00:00:00 2001 From: Jeovani Marcos Morales Nieto Date: Sun, 17 Mar 2024 08:46:44 +0100 Subject: [PATCH 5/5] Update Pointers.md --- tutorials/learn-c.org/es/Pointers.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tutorials/learn-c.org/es/Pointers.md b/tutorials/learn-c.org/es/Pointers.md index 6e87419f4..28ddb2e5b 100644 --- a/tutorials/learn-c.org/es/Pointers.md +++ b/tutorials/learn-c.org/es/Pointers.md @@ -76,13 +76,13 @@ Código del tutorial int main() { int n = 10; - /* your code goes here */ + /* tu código va aquí */ - /* testing code */ + /* código de prueba */ if (pointer_to_n != &n) return 1; if (*pointer_to_n != 11) return 1; - printf("Done!\n"); + printf("Listo!\n"); return 0; } ```