我刚开始学习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);
}
答案 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()
和其他东西的所有谬误,打算(但不会,因为它处理使用局部变量)通过使用传递整数变量a
和b
的副本的函数来交换值。这是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;
}
因为i
和j
是按值传递的。这意味着它与局部变量tmp
相同。因此,修改i
和j
实际上并不会修改您传递的变量,因为i
和j
的本地副本不存在于函数{{1}之外}}
因此,如果您需要修改swap()
中的i
和j
,则必须转到main()
和{swap()
地址1 {} i
。
这就是为什么以下版本实际上有效。
j
编辑:为了更好地了解这些内容,我们建议您使用YouTube上提供的斯坦福讲座main()
。