首页 > 解决方案 > 指针混淆:c 中的交换方法

问题描述

#include<stdio.h>
void swap(int *a,int *b){
    int p=*b;
    *b=*a;
    *a=p;

    /*int *p=b;
    b=a;
    a=p;
    */
}

int main(){
    int a,b;
    scanf("%d %d",&a,&b);
    swap(&a,&b);
    printf("%d %d",a,b);
}

以上是代码。

如果我将 3 5 作为输入,那么它应该交换它的值,并且 5 3 应该作为输出输出。我通过尝试 int p=*b 得到了答案

但是我也尝试了评论部分,但它没有用。

所以,我检查了他们在交换和主要的地址。

在交换 int *a 和 int *b 他们的地址改变了

但是,当我回到 main 时, a 和 b 的地址没有改变......

所以首先我想:它在 main 中没有改变,因为参数 int *a,int *b 是局部变量吗?

但我也了解到,当指针和参数用作参数时,它们的值可以改变,不像其他变量......

我真的很想知道为什么第二种方法(注释部分)没有交换值......

标签: cpointerspass-by-referenceswapfunction-definition

解决方案


如果要更改函数中的原始对象,则必须通过引用将它们传递给函数。

在 C 中,通过引用传递对象意味着通过指向原始对象的指针间接传递它们。

否则,如果您将原始对象本身传递给函数,该函数将处理对象的副本。很明显,更改副本不会影响原始对象。

这正是这个函数中发生的事情

void swap(int *a,int *b){
    int *p=b;
    b=a;
    a=p;
}

该函数处理作为此调用中的参数传递给函数的指针的副本

swap(&a,&b);

那就是函数确实交换了声明为其参数的两个指针的值。但它们不是传递给函数的原始指针。它们是指针的副本。所以原始指针的值没有改变

函数swap一般可以如下所示

void swap( T *a, T *b )
{
    T tmp = *a;
    *a = *b;
    *b = tmp;
}  

其中T是相同的类型说明符。

所以如果你想交换类型的对象,int那么在上面的函数Tint,函数看起来像

void swap( int *a, int *b )
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}  

如果您想交换该类型指针的值,int *那么T将是int *并且函数看起来像

void swap( int **a, int **b )
{
    int *tmp = *a;
    *a = *b;
    *b = tmp;
}  

这是一个演示程序。

#include <stdio.h>

void swap1( int *pa, int *pb )
{
    int tmp = *pa;
    *pa = *pb;
    *pb = tmp;
}

void swap2( int **ppa, int **ppb )
{
    int *tmp = *ppa;
    *ppa = *ppb;
    *ppb = tmp;
}

int main(void) 
{
    int a = 3, b = 5;

    swap1( &a, &b );

    printf( "a = %d b = %d\n", a, b );

    //  reset again the values of the variables
    a = 3; b = 5;

    int *pa = &a, *pb = &b;

    swap2( &pa, &pb );

    printf( "*pa = %d *pb = %d\n", *pa, *pb );

    return 0;
}

它的输出是

a = 5 b = 3
*pa = 5 *pb = 3

那是首先在程序int中交换类型的两个对象,所以想象的类型说明符Tint

然后两个指向对象的指针ab交换。所以想象的类型说明符T int *

交换指针后,指针pa现在指向对象b,指针pb现在指向对象a


推荐阅读