-2
#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 是局部变量吗?

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

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

4

4 回答 4

1

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

在 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

于 2020-04-03T14:50:46.027 回答
0

在第二种方法中,您使用受限于函数范围的局部变量swap。因此,主函数中的变量a或变量与函数中定义为参数的变量或变量不同。babswap

当你使用指针时,swap函数会改变指针所指向的值(这意味着函数改变了函数中声明的a和地址处的值)。bmain

于 2020-04-03T14:12:32.710 回答
0

假设你的意思

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

该代码只是交换函数中指针的值swap()。这不会交换地址,main()因为正如您所说,“参数 int *a,int *b 是局部变量”。

当你swap()像这样调用函数时

swap(&a,&b);

和的地址被传递并成为函数中的局部变量。您不能更改或的地址- 它们在内存中有一个位置。abswap()ab

在有效的代码中

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

您不会更改指针的值,而是更改指针指向的内存中的值,这就是它起作用的原因。

虽然 C 是按值传递的,但如果您将某物的地址作为值传递,则函数可以在其范围之外修改某些东西,因为您告诉函数该变量在哪里。

于 2020-04-03T14:13:31.040 回答
0

在 C 中,函数中声明的所有变量都是该特定函数的局部变量。所以,你在函数交换中写了一些东西

诠释*p=b;

上面的代码会做的是,它将 b 的复制到 p 中。因此,当函数 swap 返回时,局部变量 p、b 和 a 将消失。

于 2020-04-03T14:15:39.860 回答