当我在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)
注意函数内部我们没有分配指针,而是指定它们指向的内容.指针指向我们的变量x和y.该功能直接改变存储在价值观我们通过我们给它的指针变量.而这正是我们所需要的.
现在如果我们有两个指针变量并希望交换指针本身(而不是它们指向的值)会发生什么?如果我们传递指针,指针将被简单地复制(而不是它们指向的值)到参数.
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但我们希望它们引用xp和yp.
我们怎么做?我们传递他们的地址!
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)
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它本身就是一个指针.