Saltar al contenido

Intercambio de punteros en C (char, int)

Este grupo especializado despúes de días de trabajo y recopilar de datos, obtuvimos la respuesta, deseamos que te resulte útil para tu proyecto.

Solución:

Lo primero que debe comprender es que cuando pasa algo a una función, ese algo se copia en los argumentos de la función.

Supongamos que tiene lo siguiente:

void swap1(int a, int b) 
    int temp = a;
    a = b;
    b = temp;
    assert(a == 17);
    assert(b == 42);
    // they're swapped!


int x = 42;
int y = 17;
swap1(x, y);
assert(x == 42);
assert(y == 17);
// no, they're not swapped!

Las variables originales no se intercambiarán porque sus valores se copian en los argumentos de la función. Luego, la función procede a intercambiar los valores de esos argumentos y luego regresa. Los valores originales no se modifican, porque la función solo intercambia sus propias copias privadas.

Ahora, ¿cómo solucionamos esto? La función necesita una forma de referirse a las variables originales, no copias de sus valores. ¿Cómo podemos referirnos a otras variables en C? Uso de punteros.

Si pasamos punteros a nuestras variables en la función, la función puede intercambiar los valores en nuestro variables, en lugar de sus propias copias de argumentos.

void swap2(int* a, int* b) 
    int temp = *a;
    *a = *b;
    *b = temp;
    assert(*a == 17);
    assert(*b == 42);
    // they're swapped!


int x = 42;
int y = 17;
swap2(&x, &y); // give the function pointers to our variables
assert(x == 17);
assert(y == 42);
// yes, they're swapped!

Observe cómo dentro de la función no estamos asignando a los punteros, sino a lo que apuntan. Y los punteros apuntan a nuestras variables. x y y. La función está cambiando directamente los valores almacenados en nuestro variables a través de los punteros que le damos. Y eso es exactamente lo que necesitábamos.

Ahora, ¿qué sucede si tenemos dos variables de puntero y queremos intercambiar el punteros mismos (a diferencia de los valores a los que apuntan)? Si pasamos punteros, los punteros simplemente se copiarán (no los valores a los que apuntan) en los argumentos.

void swap3(int* a, int* b) 
    int* temp = a;
    a = b;
    b = temp;
    assert(*a == 17);
    assert(*b == 42);
    // they're swapped!

void swap4(int* a, int* b) 
    int temp = *a;
    *a = *b;
    *b = temp;
    assert(*a == 17);
    assert(*b == 42);
    // they're swapped!


int x = 42;
int y = 17;
int* xp = &x;
int* yp = &y;
swap3(xp, yp);
assert(xp == &x);
assert(yp == &y);
assert(x == 42);
assert(y == 17);
// Didn't swap anything!
swap4(xp, yp);
assert(xp == &x);
assert(yp == &y);
assert(x == 17);
assert(y == 42);
// Swapped the stored values instead!

La función swap3 solo intercambia sus propias copias privadas de nuestros punteros que obtiene en sus argumentos. Es el mismo problema que tuvimos con swap1. Y swap4 está cambiando los valores a los que apuntan nuestras variables, ¡no los punteros! Le estamos dando a la función un medio para referirse a las variables. x y y pero queremos que se refieran a xp y yp.

¿Como hacemos eso? ¡Le pasamos sus direcciones!

void swap5(int** a, int** b) 
    int* temp = *a;
    *a = *b;
    *b = temp;
    assert(**a == 17);
    assert(**b == 42);
    // they're swapped!



int x = 42;
int y = 17;
int* xp = &x;
int* yp = &y;
swap5(&xp, &yp);
assert(xp == &y);
assert(yp == &x);
assert(x == 42);
assert(y == 17);
// swapped only the pointers variables

De esta manera, intercambia nuestras variables de puntero (observa cómo xp ahora apunta a y) pero no los valores a los que apuntan. ¡Le dimos una forma de referirse a nuestras variables de puntero, para que pueda cambiarlas!

A estas alturas, debería ser fácil entender cómo intercambiar dos cadenas en forma de char* variables La función de intercambio necesita recibir punteros para char*.

void swapStrings(char** a, char** b)
    char *temp = *a;
    *a = *b;
    *b = temp;
    assert(strcmp(*a, "world") == 0);
    assert(strcmp(*b, "Hello") == 0);


char* x = "Hello";
char* y = "world";
swapStrings(&x, &y);
assert(strcmp(x, "world") == 0);
assert(strcmp(y, "Hello") == 0);

void intSwap (int *pa, int *pb)
    int temp = *pa;
    *pa = *pb;
    *pb = temp;

Necesitas saber lo siguiente –

int a = 5; // an integer, contains value
int *p; // an integer pointer, contains address
p = &a; // &a means address of a
a = *p; // *p means value stored in that address, here 5

void charSwap(char* a, char* b)
    char temp = *a;
    *a = *b;
    *b = temp;

Entonces, cuando cambias así. Solo se intercambiará el valor. Entonces, para un char* solo su primera char intercambiará

Ahora, si entiendes char* (string) claramente, entonces debes saber que solo necesitas intercambiar el puntero. Será más fácil de entender si lo piensas como un array en lugar de string.

void stringSwap(char** a, char** b)
    char *temp = *a;
    *a = *b;
    *b = temp;

Entonces, aquí está pasando doble puntero porque el inicio de un array en sí mismo es un puntero.

En C, un string, como saben, es un puntero de carácter (char *). Si desea intercambiar dos cadenas, está intercambiando dos punteros de caracteres, es decir, solo dos direcciones. Para realizar cualquier intercambio en una función, debe proporcionarle las direcciones de las dos cosas que está intercambiando. Entonces, en el caso de intercambiar dos punteros, necesita un puntero a otro puntero. Al igual que intercambiar un int, solo necesita un puntero a un int.

La razón por la que su último fragmento de código no funciona es porque espera que intercambie dos punteros de caracteres: ¡en realidad está escrito para intercambiar dos caracteres!

Editar: En su ejemplo anterior, está tratando de intercambiar dos punteros int incorrectamente, como señala R. Martinho Fernandes. Eso intercambiará los dos enteros, si tuvieras:

int a, b;
intSwap(&a, &b);

Aquí puedes ver las reseñas y valoraciones de los lectores

Eres capaz de estimular nuestra investigación exponiendo un comentario o puntuándolo te damos las gracias.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *