首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我们把地址而不是值作为参数传递给C中的交换函数?

为什么我们把地址而不是值作为参数传递给C中的交换函数?
EN

Stack Overflow用户
提问于 2022-08-09 10:06:37
回答 4查看 230关注 0票数 0

我正在解决交换两个变量的值的问题。我需要使用一个助手函数来完成它。现在我一直在研究“按值呼叫”和“按引用呼叫”的内容。

我唯一的困惑是,当我将参数传递给交换函数时,为什么要发送地址(&a,&b)?当我发送地址而不是值本身时,实际会发生什么?

这是密码

代码语言:javascript
复制
#include <stdio.h>
void swap(int a, int b) {
    int temp;
    temp = a;
    a = b;
    b = temp;
    printf("After swapping values in function(using call by value) a = %d, b = %d\n",a,b);
}
void swapref(int *a, int *b) {
    int temp2;
    temp2 = *a;
    *a=*b;
    *b=temp2;
    printf("After swapping values in function(using call by reference) a = %d, b = %d\n",*a,*b);
}
int main() {
    int a = 10, b = 20;
    printf("Before swapping the values in main a = %d, b = %d\n",a,b);

    swap(a,b);

    printf("After swapping values in main(using call by value) a = %d, b = %d\n",a,b);

    swapref(&a,&b); // <-- This is the line I'm talking about

    printf("After swapping values in main(using call by reference) a = %d, b = %d\n",a,b);
    return 0;
}

在上面的代码中,在swapref(&a,&b)行中实际发生了什么?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2022-08-09 12:58:49

你用同样的名字来做不同的事情也于事无补。为了回答这个问题,我们假设main中的变量名为xy

代码语言:javascript
复制
int main( void )
{
  int x = 10, y = 20;
  ...
  swap(x, y);
  ...
  swapref(&x, &y);
  ...
}

这将使下面的讨论更容易理解。

abswap中的形式参数是内存中与局部变量xmain中的y不同的对象。

当你打电话的时候

代码语言:javascript
复制
swap(x, y);

main中,表达式xy被完全计算,这些计算结果(分别为1020 )传递给swap并复制到其形式参数中。

由于ab是与xy不同的对象,交换ab的值对xy的值没有影响。

swap一样,swapref中的形式参数ab与局部变量xy是内存中的不同对象。当你打电话的时候

代码语言:javascript
复制
swapref(&x, &y);

表达式&x&y是完全计算的,这些计算的结果( xy的地址)传递给swapref,并复制到正式的参数ab中。

这意味着下列关系为真:

代码语言:javascript
复制
 a == &x // int * == int *
*a ==  x // int   == int
 b == &y // int * == int *
*b ==  y // int   == int

同样,由于ab在内存中是与main中的xy不同的对象,所以在swapref中更改ab的值对xy没有影响。但是,当您将新值写入*a*b表达式的swapref中时,并不是要更改ab的值,而是要更改ab所指向的值,在本例中是xy

您可以将*a*b看作是xy的别名,它们是相同对象的替代名称。写作

代码语言:javascript
复制
temp = *a;
*a = *b;
*b = temp;

等于写

代码语言:javascript
复制
temp = x;
x = y;
y = temp;
票数 0
EN

Stack Overflow用户

发布于 2022-08-09 10:13:09

传递地址与给出值是不同的,因为您通过了存储原始变量(a和b)的确切内存情况。比如:

代码语言:javascript
复制
void swapref(int *a, int *b)

因此,在函数中修改这些值时,需要更改原始值。

而传递变量的值如下:

代码语言:javascript
复制
void swap(int a, int b)

您将传递每个变量的副本,这样就不会触及原始变量。

票数 1
EN

Stack Overflow用户

发布于 2022-08-09 10:18:10

从程序的输出可以看出:

代码语言:javascript
复制
After swapping values in function(using call by value) a = 20, b = 10
After swapping values in main(using call by value) a = 10, b = 20
After swapping values in function(using call by reference) a = 20, b = 10
After swapping values in main(using call by reference) a = 20, b = 10

变量实际上并不是交换的。每当将某个东西作为参数传递时,它的值就会被复制到参数中。

代码语言:javascript
复制
void by_val(int i) {
    i = 2;
    // the variable i in main will NOT be changed,
    // because this one is a copy
}

void by_ptr(int* i) {
    // This will change the i in main, because we didn't copy its value,
    // but copied the memory address of i variable in main.
    *i = 2;

    // Now we can make i point to an other variable than the main function i.
    // This will not update i, but it will update num.
    int num = 2;
    i = &num;
    *i = 3;
    
}

int main() {
    int i = 1;
    by_val(i);
    printf("%d\n", i); // "1"
    by_ptr(&i);
    printf("%d\n", i); // "2"
}

因此,在第一个交换函数中,交换的是(main) a和b的副本的值,而不是(main) a和b的值,而是在第二个函数中交换(main) a和b的值,因为您传递了(main)的内存地址。*操作符使程序使用变量中的值,内存地址指向。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73290006

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档