指针或指针指针

时间:2015-07-29 16:07:14

标签: c pointers

在我继续之前,我想告诉你我是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

2 个答案:

答案 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。