1:define定义语句块
首先,我们来看一个最简单的问题:花括号后面有分号和没有分号有什么区别.这个问题的答案要从两个方面来回答.
第一,类型定义中的花括号必须要跟分号.比如结构体struct A{}; ,类class A{}; 等自定义类型,花括号后面必须要跟花括号.
第二,语句块后面跟花括号.这个时候的形式为”{语句块}; ” ,后面的分号就是一个空语句.
总的来说,有花括号后面有和没有分号是有很区别的.
现在转入正题,讨论define定义语句块方面的细节.
先看一个可以正确的代码:
#include <stdio.h>
#define change(str) {str[0]=’a’; printf(“%s”,str);}
int main()
{
char str1[10] = “true!n”;
if (1) change(str1); //这里的宏展开后是两个语句.一个是if语句,一个是空语句
getchar();
return 0;
}
int main()
{
char str1[10] = “true!n”;
if (1) change(str1); //这里的宏展开后是两个语句.一个是if语句,一个是空语句
getchar();
return 0;
}
一个空语句,看起来无关大碍,可有可无,无关紧要.
但是,现实中,我们的if语句后面都经常跟有else语句,于是可能会有下面形式的代码出现
#include <stdio.h>
#define change(str) {str[0]=’a’; printf(“%s”,str);}
int main()
{
char str1[10] = “true!n”;
char str2[10] = “false!n”;
if (1) change(str1);
else change(str2);
getchar();
return 0;
}
#define change(str) {str[0]=’a’; printf(“%s”,str);}
int main()
{
char str1[10] = “true!n”;
char str2[10] = “false!n”;
if (1) change(str1);
else change(str2);
getchar();
return 0;
}
修改完成后,编译一下,编译器出现如下错误提示:
D:ctsmain.cpp In function `int main()‘:
8 D:ctsmain.cpp expected primary–expression before “else“
8 D:ctsmain.cpp expected `;‘ before “else”
8 D:ctsmain.cpp expected primary–expression before “else“
8 D:ctsmain.cpp expected `;‘ before “else”
原因很明显,if语句后面跟有一个空语句,导致了else没有了if语句与之匹配,于是编译出错.就是说,下面形式的代码中
//这里的空导致了后面的else没有匹配
if (表达式) {语句块} ;
else {语句块};
if (表达式) {语句块} ;
else {语句块};
else没有if相匹配.
对于上面的问题,我们怎么解决呢.我们平时在语句中调用宏的一般形式是: 宏名(参数列表); ,在表达式中调用宏名的形式是宏名(参数列表) (这里不讨论表达式的情况).我们不可能老是自己去判断是否宏后面是否必须要加一个分号,如果是那样,那实在是一件很痛苦的事情.
那有什么办法,宏在语句中总是通过 宏名(参数列表); 的形式调用,而又不会产生上面的错误呢?有,那就是使用do{}whil()语句,示例如下
#include <stdlib.h>
#define change(str) do{str[0]=’a’; printf(“%s”,str);}while(0)
int main()
{
char str1[10] = “true!n“;
char str2[10] = “false!n“;
if (1) change(str1);
else change(str2);
getch();
return 0;
}
#define change(str) do{str[0]=’a’; printf(“%s”,str);}while(0)
int main()
{
char str1[10] = “true!n“;
char str2[10] = “false!n“;
if (1) change(str1);
else change(str2);
getch();
return 0;
}
这样,我们通过do while语句,就解决了上面的问题