在我继续之前,我想告诉你我是c语言的初学者(6个月),当我必须在我的课程中使用指针时,我不能100%肯定他们,所以请温柔地对待我。
今天我正在编写一些东西,但有一次我意识到我需要使用swap。
选项1: 这是我用过的:
#include <stdio.h>
void swap(int *pa, int *pb){
int temp;
temp = *pa;
*pa = *pb;
*pb = temp;
}
int main(void){
int a = 5;
int b = 10;
printf("Before Swap:\n");
printf("A = %d\nB = %d\n\n",a,b);
swap(&a,&b);
printf("After Swap:\n");
printf("A = %d\nB = %d\n",a,b);
return 0;
}
它适用于我需要的东西:
Before Swap: A = 5 B = 10
After Swap:
A = 10
B = 5
后来我决定在程序中必须涉及指针,我改变了这个程序:
选项2:
#include <stdio.h>
void swap(int *pa, int *pb){
int temp;
temp = *pa;
*pa = *pb;
*pb = temp;
}
int main(void){
int a = 5;
int b = 10;
int *pa = &a;
int *pb = &b;
printf("Before Swap:\n");
printf("PA = %d\nPB = %d\n\n",*pa,*pb);
swap(pa,pb);
printf("After Swap:\n");
printf("PA = %d\nPB = %d\n",*pa,*pb);
return 0;
}
它再次适用于我需要的东西:
Before Swap:
PA = 5
PB = 10
After Swap:
PA = 10
PB = 5
现在来到有趣的部分。 我正在进行编码,我通过使用Pointer-to-Pointer作为参数来改变交换功能,我得到了这个:
选项3:
#include <stdio.h>
void swap(int **ppa, int **ppb){
int temp;
temp = **ppa;
**ppa = **ppb;
**ppb = temp;
}
int main(void){
int a = 5;
int b = 10;
int *pa = &a;
int *pb = &b;
printf("Before Swap:\n");
printf("PA = %d\nPB = %d\n\n",*pa,*pb);
swap(&pa,&pb);
printf("After Swap:\n");
printf("PA = %d\nPB = %d\n",*pa,*pb);
return 0;
}
一切都很好:
Before Swap: PA = 5 PB = 10
After Swap:
PA = 10
PB = 5
所以我必须使用&amp;我在main中调用swap函数时的运算符。 我的问题是(因为我在这里感到困惑)选项2和选项3都可以使用,或者只使用其中一个以及为什么。 我不是要求更好的编码,我只是不知道选项2和3,两者是否合法以及为什么两者都正常工作。
L.E: @Olaf说:
如果您在交换中添加第三颗或第四颗星,它也会没问题。试想一下
现在我更加困惑,因为它没有像他说的那样工作:
#include <stdio.h>
void swap(int ****pa, int ****pb){
int temp;
temp = ****pa;
****pa = ****pb;
****pb = temp;
}
int main(void){
int a = 5;
int b = 10;
int *pa = &a;
int *pb = &b;
printf("Before Swap:\n");
printf("PA = %d\nPB = %d\n\n",*pa,*pb);
swap(&pa,&pb);
printf("After Swap:\n");
printf("PA = %d\nPB = %d\n",*pa,*pb);
return 0;
}
输出:
program.c: In function ‘main’: program.c:21:14: error: passing argument 1 of ‘swap’ from incompatible pointer type [-Werror] swap(&pa,&pb); ^ program.c:3:10: note: expected ‘int ****’ but argument is of type ‘int **’ void swap(int ****pa, int ****pb){ ^ program.c:21:18: error: passing argument 2 of ‘swap’ from incompatible pointer type [-Werror] swap(&pa,&pb); ^ program.c:3:10: note: expected ‘int ****’ but argument is of type ‘int **’ void swap(int ****pa, int ****pb){ ^ cc1: all warnings being treated as errors
答案 0 :(得分:4)
在法律和工作中没有错。 唯一的考虑因素是它有多少有用和高效。将指针传递给指针生成的代码将包括三重寻址,第一个寻址将检索指向变量的指针的地址,第二个将从指针检索变量的地址,最后它将获得变量。 在您的情况下,您必须传递指针以使函数交换能够修改函数范围之外的两个参数。
但是如果你考虑这段代码,那么传递指针的指针就有意义了:
#include <stdio.h>
void swap(int **ppa, int **ppb){
int *pTemp = *ppb;
*ppb = *ppa;
*ppa = pTemp;
}
int main(void){
int a = 5;
int b = 10;
int *pa = &a;
int *pb = &b;
printf("Before Swap:\n");
printf("PA = %d\nPB = %d\n\n",*pa,*pb);
swap(&pa,&pb);
printf("After Swap:\n");
printf("PA = %d\nPB = %d\n",*pa,*pb);
return 0;
}
在这种情况下,您正在交换指针,而不是变量。当您需要交换大数据(如字符串)时,这非常有用,因为它比在对象之间复制整个数据要快得多。
答案 1 :(得分:1)
你应该很好地理解指针和参考之间的区别,以获得正确的结果
你也应该清楚通过值和指针调用以及函数中的引用之间的区别:
这里有一些例子应该向你澄清这个概念:
int myAge=39;
cout<< "myAge is locate at " << &myAge << endl; // address of myAge in memory
int* agePtr=&myAge;
cout<<"Address of pointer "<< agePtr << endl;
cout<< " Data at memory address "<< *agePtr << endl;
int badNums[5]={4, 13, 14, 24, 34};
int* numArrayPtr = badNums;
cout<< "Address " << numArrayPtr << " Value " << *numArrayPtr << endl;
numArrayPtr++; // get next value in Array
cout<< "Address " << numArrayPtr << " Value " << *numArrayPtr << endl;
cout<< "Address " << badNums << " Value " << *badNums << endl;
这里通过指针和参考调用函数参数:
void makeMeYoung(int* age) {
cout<< " I used to be " << *age << endl;
*age = 21;
}
void actYourAge(int& age){
age = 39;
}
makeMeYoung(&myAge);
cout << "I'm "<< myAge << " years old now" << endl; // 21
int& ageRef= myAge;
cout<<"myAge : " << myAge << endl; // 21
ageRef++;
cout<<"myAge : " << myAge << endl; // 22
actYourAge(ageRef);
cout<<"myAge : " << myAge << endl; // 39
请注意,如果你不想在变量的变量处初始化,你应该使用指针,如果你需要为指针指定另一个变量,那么使用指针你将能够处理多个变量,而当你指望时我只需要对一个变量使用一个参考并坚持使用它,这个想法就是当你只想指向一个变量时使用refrence。