简体   繁体   English

指针或指针到指针

[英]Pointer or Pointer-to-Pointer

Before i proceed i wanna tell you that i'm a beginner in c language (6 months) and when I have to use pointers in my programs i'm not 100% sure about them, so please be gentle with me. 在我继续之前,我想告诉你我是C语言的初学者(6个月),当我不得不在程序中使用指针时,我不是100%肯定它们,所以请对我保持温和。

Today i was coding something and at one point i realized that i need the use of swap. 今天我正在编写一些东西,有一次我意识到我需要使用交换。

Option 1: This is what i used: 选项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;
}

And it works fine for what i need: 它可以满足我的需求:

 Before Swap: A = 5 B = 10 
After Swap:
A = 10
B = 5

Latter i decided that in the Program has to be involved pointers and i changed the Program like this: 后来我决定在程序中必须包含指针,我这样更改了程序:

Option 2: 选项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;
}

And again its works fine for what i was needed: 再一次,它可以很好地满足我的需求:

Before Swap:
PA = 5
PB = 10

After Swap:
PA = 10
PB = 5

Now come the interesting part. 现在来有趣的部分。 I was proceeding with the coding and i changed the swap Function by using Pointer-to-Pointer as arguments and i got this: 我正在进行编码,并通过使用Pointer-to-Pointer作为参数来更改交换功能,我得到了:

Option 3: 选项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;
}

And everything was ok: 一切都很好:

 Before Swap: PA = 5 PB = 10 
After Swap:
PA = 10
PB = 5

So here i had to use & operator when i was calling the swap function in main. 因此,当我在main中调用swap函数时,这里必须使用&运算符。 My question is (because i'm confused in here) are Option 2 and Option 3 both Ok to be used or just one of them should be used and why. 我的问题是(因为我在这里感到困惑)选项2和选项3都可以使用还是应该只使用其中之一,为什么? I am not asking for a better coding, I just do not know if option 2 and 3, both are legal or not and why both are working fine. 我不是在要求更好的编码,我只是不知道选项2和3是否合法,以及为什么两者都能正常工作。

LE: @Olaf said that: LE:@Olaf说:

And if you add a third or forth star in swap, it also will be fine. 并且如果您在交换中添加了第三颗或第四颗星,也可以。 Just think about it 考虑一下

Now i am more confused because its not working as he said: 现在我更加困惑,因为它不能像他所说的那样工作:

#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;
}

Output: 输出:

 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 

Nothing is wrong while it is legal and working. 合法且有效时,没有什么错。 The only consideration is how much it is useful and efficient. 唯一的考虑是它有用和有效的程度。 Passing a pointer to pointer the generated code will include a triple addressing, the first addressing will retrieve the address of the pointer to the variable, the second will retrieve the address of the variable from the pointer and last it will get the variable. 将指针传递给指针,生成的代码将包含一个三重寻址,第一个寻址将检索指向该变量的指针的地址,第二个寻址将从该指针中检索变量的地址,最后它将获取该变量。 In your case you are obliged to pass pointers to make the function swap able to modify the two arguments outside the function scope. 在您的情况下,您必须传递指针,以使函数交换能够修改函数范围之外的两个参数。

But passing a pointer of a pointer can have a sense if you consider this code: 但是,如果考虑以下代码,则传递指针的指针可能会有所帮助:

#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;
}

In this case you are swapping pointers, not variables. 在这种情况下,您交换的是指针,而不是变量。 This is very useful when you need to swap large data, like strings, because is much faster than copying back the whole data between objects. 当您需要交换大数据(例如字符串)时,这非常有用,因为它比在对象之间复制整个数据要快得多。

you should well understand difference between pointers and refrences to got the right results 您应该很好地理解指针和引用之间的区别以获得正确的结果

also you should know well difference between calling by value and by pointer and by refrence in functions : 您也应该知道按值,按指针和按引用调用函数之间的区别:

here some examples should clarify the concept to you : 这里有一些例子可以向您阐明这个概念:

 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;

here calling function paramaters by pointer and by refrence : 这里通过指针和引用调用函数参数:

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

note that you should use pointers if you dont want to initialize at decleration of variables , also if you need to assign another variable to the pointer so with pointer you will be able to deal with more than one variable , while refrence when you need to use just one refrence to a variable and stuck with it , the idea is when you want to point to only one variable use refrence. 请注意,如果您不想在变量的初始化时初始化,也应该使用指针,并且如果您需要为该指针分配另一个变量,那么使用指针您将可以处理多个变量,而在需要使用时可以进行刷新只是对一个变量使用了一个引用并一直使用它,其想法是当您只想指向一个使用变量的变量时。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM