sizeof 在宏和函数中的区别
Difference between sizeof in macro and in function
我在 Whosebug 的 answer 中找到了通用交换函数的以下声明。
#define swap(x,y) do \
{ unsigned char swap_temp[sizeof(x) == sizeof(y) ? (signed)sizeof(x) : -1]; \
memcpy(swap_temp,&y,sizeof(x)); \
memcpy(&y,&x, sizeof(x)); \
memcpy(&x,swap_temp,sizeof(x)); \
} while(0)
但是,如果我们用 C 编写类似的函数,它就无法工作,我们需要显式传入 void* 类型的大小才能使其工作。我知道这会发生,因为宏会在调用它的函数内扩展,并且 sizeof 会起作用,因为它与变量 x 或 y 在同一范围内。我说得对吗?
如果我是。考虑以下情况。
void someComplexFunction(void* a, void* b){
swap(a,b);
}
这样对吗?我试过了,它奏效了。为什么这有效?
您交换的是指针的地址,而不是实际内容。
这段代码显示了它
char *foo = "foo";
char *bar = "bar";
printf("before swap\n");
printf("foo address '%08x', foo content '%s'\n", foo, foo);
printf("foo address '%08x', foo content '%s'\n", bar, bar);
swap(foo, bar);
printf("after swap\n");
printf("foo address '%08x', foo content '%s'\n", foo, foo);
printf("foo address '%08x', foo content '%s'\n", bar, bar);
输出类似于此
before swap
foo address '010e58a8', foo content 'foo'
foo address '010e58ac', foo content 'bar'
after swap
foo address '010e58ac', foo content 'bar'
foo address '010e58a8', foo content 'foo'
我在 Whosebug 的 answer 中找到了通用交换函数的以下声明。
#define swap(x,y) do \
{ unsigned char swap_temp[sizeof(x) == sizeof(y) ? (signed)sizeof(x) : -1]; \
memcpy(swap_temp,&y,sizeof(x)); \
memcpy(&y,&x, sizeof(x)); \
memcpy(&x,swap_temp,sizeof(x)); \
} while(0)
但是,如果我们用 C 编写类似的函数,它就无法工作,我们需要显式传入 void* 类型的大小才能使其工作。我知道这会发生,因为宏会在调用它的函数内扩展,并且 sizeof 会起作用,因为它与变量 x 或 y 在同一范围内。我说得对吗?
如果我是。考虑以下情况。
void someComplexFunction(void* a, void* b){
swap(a,b);
}
这样对吗?我试过了,它奏效了。为什么这有效?
您交换的是指针的地址,而不是实际内容。
这段代码显示了它
char *foo = "foo";
char *bar = "bar";
printf("before swap\n");
printf("foo address '%08x', foo content '%s'\n", foo, foo);
printf("foo address '%08x', foo content '%s'\n", bar, bar);
swap(foo, bar);
printf("after swap\n");
printf("foo address '%08x', foo content '%s'\n", foo, foo);
printf("foo address '%08x', foo content '%s'\n", bar, bar);
输出类似于此
before swap
foo address '010e58a8', foo content 'foo'
foo address '010e58ac', foo content 'bar'
after swap
foo address '010e58ac', foo content 'bar'
foo address '010e58a8', foo content 'foo'