c - 指针或指针到指针

标签 c pointers

在继续之前,我想告诉你,我是 C 语言的初学者(6 个月),当我必须在程序中使用指针时,我对它们不是 100% 确定,所以请对我温柔一点。

今天我正在编码一些东西,有一次我意识到我需要使用交换。

选项 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

现在有趣的部分来了。 我正在继续编码,并通过使用指针到指针作为参数更改了交换函数,我得到了这个:

选项 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

因此,当我在 main 中调用交换函数时,我必须使用 & 运算符。 我的问题是(因为我在这里很困惑)选项 2 和选项 3 都可以使用,还是只应该使用其中之一以及为什么。 我并不是要求更好的编码,我只是不知道选项 2 和 3 是否合法以及为什么两者都工作正常。

L.E: @Olaf 说:

And if you add a third or forth star in swap, it also will be fine. Just think about it

现在我更困惑了,因为它不像他说的那样工作:

#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

最佳答案

只要合法且有效,就没有任何问题。 唯一需要考虑的是它的有用性和效率有多大。将指针传递给指针,生成的代码将包括三重寻址,第一个寻址将检索变量指针的地址,第二个将从指针检索变量的地址,最后将获取变量。 在您的情况下,您必须传递指针以使函数交换能够修改函数范围之外的两个参数。

但是如果您考虑以下代码,传递指针的指针可能是有意义的:

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

在这种情况下,您交换的是指针,而不是变量。当您需要交换大数据(例如字符串)时,这非常有用,因为它比在对象之间复制回整个数据要快得多。

关于c - 指针或指针到指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31705703/

相关文章:

c - atoi 的 Valgrind 错误

c - 使用结构和数组的 Strcmp 的 If 语句不起作用

c++ - 安全/正确使用指针

c - 在 C 中的堆上分配数组

c - 指针未设置为结构数组的元素

c - 结构数组崩溃程序 C

c - 为什么这段 Prolog+C 代码失败了?

c++ - ICMP 校验和错误

C++ 使用指向模板对象的指针

c - c中int指针的用法