为什么我不能传入变量来实现交换功能?

时间:2013-04-23 05:18:48

标签: c function pointers

我刚开始学习C而且我对为什么必须使用指针实现交换功能感到困惑?

交换不起作用的版本:

#include <stdio.h>

void swap(int i, int j) {
   int t = i;
   i = j;
   j = t;
}

int main() {
   int a = 23, b = 47;
   printf("Before. a: %d, b: %d\n", a, b);
   swap(a,b);
   printf("After.  a: %d, b: %d\n", a, b);
   return 0;
}

交换工作的版本:

#include <stdio.h>

void swap(int *i, int *j) {
   int t = *i;
   *i = *j;
   *j = t;
}

void main() {
   int a = 23, b = 47;
   printf("Before. a: %d, b: %d\n", a, b);
   swap(&a, &b);
   printf("After . a: %d, b: %d\n", a, b);
}

4 个答案:

答案 0 :(得分:3)

默认情况下,函数参数在C和C ++中按值传递。这基本上意味着在函数中接收传递的参数的副本。此副本与传递的变量不同,此副本上的任何更改都不会反映回传递的参数。

因此,您的第一个片段实际上会交换传递的参数的副本,而不是参数本身。

要将交换反射回传递的参数,您需要通过引用传递,在C中,这是通过使用指针实现的。将参数的地址传递给函数并且函数实际操作传递给它的内存地址,即:传递值的原始变量。

答案 1 :(得分:1)

swap(a,b);

void swap(int i, int j) {
   int t = i;
   i = j;
   j = t;
}

上面的代码失败了,因为变量i和j是 local 到函数swap,这意味着变量的范围仅限于函数swap,并且一旦功能终止,他们的生命就会丧失。

一种解决方法是使用传递地址,如下面的代码所示......

swap(&a,&b);

void swap(int* i, int* j) {
   int t = *i;
   i* = *j;
   j* = t;
}

现在变量i和j是指向原始变量a和b的指针,这意味着它们代表a和b,因此即使指针在函数内具有有限的范围,它们也能够间接修改变量a和b。

答案 2 :(得分:0)

你为什么要背靠背地提出两个程序?这是两个独立的程序。第一个,尽管有关于void main()和其他东西的所有谬误,打算(但不会,因为它处理使用局部变量)通过使用传递整数变量ab的副本的函数来交换值。这是pass-by-value。实际上,C只有{{} 1}},尽管你的书是由Yeshwant Kanetkar所说的。但是,为了使第一个程序工作,使用pass-by-value来显示printf()函数本身内的交换值,作为局部变量的变化值不会显示在swap()

main()

他可能声称使用void swap(int i, int j) { int t = i; i = j; j = t; printf("After. a:%d,b:%d",i,j); } 的第二个程序基本上是pass-by-reference,其中传递变量地址的副本,而不是实际地址本身。而且,尽管它是不可移植的像pass-by-value这样的怪癖,它会交换void main()a的值。

b

输出之前。 a:23 b:47            后。 a:47 b:23

我在void swap(int *i, int *j) { int t = *i; *i = *j; *j = t; } 上运行了。但是你的作者CodeBlocks一定建议你使用16位Turbo C eh?

答案 3 :(得分:0)

你无法以这种方式交换:

void swap(int i, int j) {
   int t = i;
   i = j;
   j = t;
}

因为ij是按值传递的。这意味着它与局部变量tmp相同。因此,修改ij实际上并不会修改您传递的变量,因为ij的本地副本不存在于函数{{1}之外}}

因此,如果您需要修改swap()中的ij,则必须转到main()和{swap()地址1 {} i。 这就是为什么以下版本实际上有效。

j

编辑:为了更好地了解这些内容,我们建议您使用YouTube上提供的斯坦福讲座main()