为什么宏和函数对 c 中的相同代码的工作方式不同
Why macros and functions work differently about same code in c
我是编程新手,我发现了一个有趣但很难找到原因的问题,所以我写这个post。
我正在尝试编写交换函数:
当我用传统方式写swap函数时,
void swap(int *x,int *y){int t=*x;*x=*y;*y=t;}
此功能有效,当然,
void swap(int x,int y){int t=x;x=y;x=t;}
不起作用。但是当我把交换写成宏时,
#define swap(x,y){int t=x;x=y;y=t;}
作品...
为什么宏不用指针也可以交换值?
why the macro can swap value though they don't use pointer?
因为宏和函数的工作方式不同。 C 中的函数使用“按值调用”语义:当您将变量作为参数传递给函数时,只有该变量的值被发送到函数——函数不能更改变量本身。我们通过将指针传递给要更改的变量而不是变量本身来模拟“按引用调用”语义。它仍然是按值调用,因为函数仍然不能改变传入的东西,即地址,但它可以改变存储在该地址的值,这是我们想要什么。
另一方面,宏只是一个简单的文本替换;根本没有函数调用。当您使用 swap(x,y)
宏时,预处理器会将宏的定义插入该位置。这就好像你写了 {int t=x;x=y;y=t;}
而不是 swap(x,y)
。当该代码运行时,它可以更改变量的值。
正如您已经猜到的那样,第一个有效但第二个无效,因为在第一个中,您将指针传递给要交换的变量,然后使用您想要交换的指针已经传递进来交换它们,有效地改变了存储在指针指向的位置的值。但是在第二个中,您只是传递变量的副本,因为 C 中的所有内容都是按值传递的。
然而,第三个有效,是因为宏 是简单的文本替换 通过预处理器标记替换工作(感谢 Eric Postpischil 指出宏不仅仅是简单的文本替换)。
所以考虑这段代码:
#define swap(x,y){int t=x;x=y;y=t;}
int main(void){
int a=10;
int b=20;
swap(a,b);
}
这相当于:
int main(void){
int a=10;
int b=20;
{int t=a;a=b;b=t;};
}
所以这里没有通过。 swap(a,b)
简单地替换为 {int t=a;a=b;b=t;}
。您可以通过调用 cpp <file-name>
.
来验证它
我是编程新手,我发现了一个有趣但很难找到原因的问题,所以我写这个post。
我正在尝试编写交换函数:
当我用传统方式写swap函数时,
void swap(int *x,int *y){int t=*x;*x=*y;*y=t;}
此功能有效,当然,
void swap(int x,int y){int t=x;x=y;x=t;}
不起作用。但是当我把交换写成宏时,
#define swap(x,y){int t=x;x=y;y=t;}
作品...
为什么宏不用指针也可以交换值?
why the macro can swap value though they don't use pointer?
因为宏和函数的工作方式不同。 C 中的函数使用“按值调用”语义:当您将变量作为参数传递给函数时,只有该变量的值被发送到函数——函数不能更改变量本身。我们通过将指针传递给要更改的变量而不是变量本身来模拟“按引用调用”语义。它仍然是按值调用,因为函数仍然不能改变传入的东西,即地址,但它可以改变存储在该地址的值,这是我们想要什么。
另一方面,宏只是一个简单的文本替换;根本没有函数调用。当您使用 swap(x,y)
宏时,预处理器会将宏的定义插入该位置。这就好像你写了 {int t=x;x=y;y=t;}
而不是 swap(x,y)
。当该代码运行时,它可以更改变量的值。
正如您已经猜到的那样,第一个有效但第二个无效,因为在第一个中,您将指针传递给要交换的变量,然后使用您想要交换的指针已经传递进来交换它们,有效地改变了存储在指针指向的位置的值。但是在第二个中,您只是传递变量的副本,因为 C 中的所有内容都是按值传递的。
然而,第三个有效,是因为宏 是简单的文本替换 通过预处理器标记替换工作(感谢 Eric Postpischil 指出宏不仅仅是简单的文本替换)。
所以考虑这段代码:
#define swap(x,y){int t=x;x=y;y=t;}
int main(void){
int a=10;
int b=20;
swap(a,b);
}
这相当于:
int main(void){
int a=10;
int b=20;
{int t=a;a=b;b=t;};
}
所以这里没有通过。 swap(a,b)
简单地替换为 {int t=a;a=b;b=t;}
。您可以通过调用 cpp <file-name>
.