在C中交换指针(char,int)

Man*_*ete 32 c pointers

当我在C中交换指针时,我一直在努力理解不同的行为.如果我想交换两个int指针,那么我可以做

void intSwap (int *pa, int *pb){
    int temp = *pa;
    *pa = *pb;
    *pb = temp;
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我想交换两个char指针,我需要做类似的事情

void charSwap(char** a, char** b){
    char *temp = *a;
    *a = *b;
    *b = temp;
}
Run Code Online (Sandbox Code Playgroud)

因为如果我这样做

void charSwap(char* a, char* b){
    char temp = *a;
    *a = *b;
    *b = temp;
}
Run Code Online (Sandbox Code Playgroud)

编译器抱怨表达式*a =*b,因为它无法更改值.如果我想交换两个strings(即char* s1= "Hello"; char* s2="Bye";)如何做到这一点?

你能给我一点帮助吗?我想真正了解它是如何工作的,所以在获得正确答案之前我不需要经历反复试验.我希望它对许多其他人有用.

R. *_*des 102

您需要了解的第一件事是,当您将某些内容传递给函数时,会将某些内容复制到函数的参数中.

假设您有以下内容:

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!
Run Code Online (Sandbox Code Playgroud)

原始变量不会被交换,因为它们的值被复制到函数的参数中.然后函数继续交换这些参数的值,然后返回.原始值不会更改,因为该功能仅交换其自己的私有副本.

现在我们如何解决这个问题?该函数需要一种方法来引用原始变量,而不是它们的值的副本.我们如何在C中引用其他变量?使用指针.

如果我们将指针传递到我们的变量到函数,该函数可以在交换价值我们的变量,而不是自己的说法副本.

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!
Run Code Online (Sandbox Code Playgroud)

注意函数内部我们没有分配指针,而是指定它们指向的内容.指针指向我们的变量xy.该功能直接改变存储在价值观我们通过我们给它的指针变量.而这正是我们所需要的.

现在如果我们有两个指针变量并希望交换指针本身(而不是它们指向的值)会发生什么?如果我们传递指针,指针将被简单地复制(而不是它们指向的值)到参数.

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!
Run Code Online (Sandbox Code Playgroud)

该函数swap3仅交换它在参数中获得的指针的私有副本.这与我们遇到的问题相同swap1.并且swap4正在改变我们的变量指向的值,而不是指针!我们给函数一个引用变量的方法x,y但我们希望它们引用xpyp.

我们怎么做?我们传递他们的地址!

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
Run Code Online (Sandbox Code Playgroud)

这样它会交换我们的指针变量(注意xp现在指向的方式y),但不是它们指向的值.我们给它一个方法来引用我们的指针变量,所以它可以改变它们!

到现在为止,应该很容易理解如何以char*变量的形式交换两个字符串.交换函数需要接收指针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);
Run Code Online (Sandbox Code Playgroud)

  • 好东西,这是我有过的最好的C课程之一! (4认同)
  • 让答案只关注一件事可能会更好,但为了这个例子正确,我们需要 `swapStrings(const char** a, const char** b)` (2认同)
  • @kaizer.se 感谢您注意到这一点!我从答案中删除了 `const` 以避免混淆。 (2认同)

Rif*_*fat 5

void intSwap (int *pa, int *pb){
    int temp = *pa;
    *pa = *pb;
    *pb = temp;
}
Run Code Online (Sandbox Code Playgroud)

你需要知道以下内容 -

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
Run Code Online (Sandbox Code Playgroud)
void charSwap(char* a, char* b){
    char temp = *a;
    *a = *b;
    *b = temp;
}
Run Code Online (Sandbox Code Playgroud)

所以,当你像这样交换.只交换值.因此,char*只有他们的第一个char将交换.

现在,如果你清楚地理解char*(字符串),那么你应该知道,你只需要交换指针.如果你认为它是一个array而不是字符串,这将更容易理解.

void stringSwap(char** a, char** b){
    char *temp = *a;
    *a = *b;
    *b = temp;
}
Run Code Online (Sandbox Code Playgroud)

所以,这里你传递的是双指针,因为array它本身就是一个指针.