以下代码如何执行(除第二行中的分号外,代码相同)
此代码可以执行,也可以执行。
#include<stdio.h>
#define SWAP(a, b) int t; t=a, a=b, b=t //note here is no semi-colon at the end
int main()
{
int a=10, b=12;
SWAP(a, b);
printf("a = %d, b = %d\n", a, b);
return 0;
}
但是预计不会运行以下内容,因为SWAP(a, b)
将被int t; t=a, a=b, b=t;;
替换。所以两个分号会产生错误!
#include<stdio.h>
#define SWAP(a, b) int t; t=a, a=b, b=t; //note the semi-colon here
int main()
{
int a=10, b=12;
SWAP(a, b);
printf("a = %d, b = %d\n", a, b);
return 0;
}
答案 0 :(得分:7)
杂散分号变为空语句,在C语言中完全合法。
您可以通过在代码中添加包含十几个分号的行来证明这一点。
另外,你的宏写得更好:
#define SWAP(a, b) do { int t = a; a = b; b = t; } while (0)
如果您尝试在单个代码块中进行两次不同的交换,这种方法会更好。
答案 1 :(得分:4)
如果在宏中使用,本地范围中的额外分号将永远不会在C(C99之后)中产生错误。他们只是简单地介绍一个空话。你在哪里知道这应该是一个错误?由于额外的分号,可以编造一个会触发“孤立的其他”错误的示例,但无论如何,您的宏在if
下都无法使用(见下文)。
在C89 / 90中,有可能在声明后通过无意中放置的额外分号触发错误,因为在C89 / 90中混合声明和语句是非法的。例如
int a, b;; /* <- A declaration followed by an empty statement */
int c; /* <- ERROR: Illegal declaration after a statement */
但是在C99中这不是问题,因为声明和陈述可以混合在一起。您的SWAP
显然已针对C99实施,因此不会立即应用此问题。
值得注意的是SWAP
的这种实现非常糟糕且非常危险。它可能会导致意外,危险和完全无意义的行为,如
if (/* whatever */)
SWAP(a, b);
更好地遵循do/while(0)
惯用语并执行类似
#define SWAP(a, b) do { int t; t=a, a=b, b=t; } while (0)
注意 - 最后没有分号。
答案 2 :(得分:2)
一个半冒号本身就是一个“空声明”,一个什么都不做的声明。
它有时很有用,但大部分时间都是错误的。例如,这个if语句没有预期的效果:
if (x == y);
{
z=1;
}
尽管如此,它仍然是C语言中非常有效的部分。
答案 3 :(得分:2)
使用后
gcc -E file_name.c
您将获得第二个代码: -
int t; t=a, a=b, b=t;;
是有效的
,相当于
int t; t=a, a=b, b=t;
; // null statement does nothing