C语言学习第十九弹

宏定义
被定义为 的标识符称为 宏名 。在编译预处理时 , 对程序中所有出现的 宏名 ”, 都用宏定义中的字
符串去代换 , 这称为 宏代换 宏展开
宏定义是由源程序中的宏定义命令完成的。宏代换是由预处理程序自动完成的。在 C 语言中 ,“
为有参数和无参数两种。
## 不带参数的宏定义
格式 : #define 标识符 字符串
其中的 “#” 表示这是一条预处理命令。凡是以 “#” 开头的均为预处理命令。 “define” 为宏定义命令。
标识符 为所定义的宏名。 字符串 可以是常数、表达式、格式串等。
注意点 :
1) 宏名一般用大写字母,以便与变量名区别开来,但用小写也没有语法错误
2) 对程序中用双引号扩起来的字符串内的字符,不进行宏的替换操作
3) 在编译预处理用字符串替换宏名时,不作语法检查,只是简单的字符串替换。只有在编译的时候
才对已经展开宏名的源程序进行语法检查
#include <stdio.h>
// 源程序中所有的宏名 PI 在编译预处理的时候都会被 3.14 所代替
#define PI 3.14
// 根据圆的半径计 radius 算周长
float girth ( float radius ) {
return 2 * PI * radius ;
}
int main ()
{
float g = girth ( 2 );
printf ( " 周长为: %f" , g );
return 0 ;
}
#define R 10
int main ()
{
char * s = "Radio" ; // 在第 1 行定义了一个叫 R 的宏,但是第 4 行中 "Radio" 里面的 'R' 并不会被
替换成 10
return 0 ;
}
代码情缘 4) 宏名的有效范围是从定义位置到文件结束。如果需要终止宏定义的作用域,可以用 #undef 命令
5) 定义一个宏时可以引用已经定义的宏名
6) 可用宏定义表示数据类型 , 使书写方便
带参数的宏定义
C 语言允许宏带有参数。在宏定义中的参数称为形式参数 , 在宏调用中的参数称为实际参数。对带参
数的宏 , 在调用中 , 不仅要宏展开 , 而且要用实参去代换形参
格式 : #define 宏名 ( 形参表 ) 字符串
#define I 100
int main ()
{
int i [ 3 ] = I ;
return 0 ;
}
#define PI 3.14
int main ()
{
printf ( "%f" , PI );
return 0 ;
}
#undef PI
void test ()
{
printf ( "%f" , PI ); // 不能使用
}
#define R 3.0
#define PI 3.14
#define L 2*PI*R
#define S PI*R*R
#define String char *
int main ( int argc , const char * argv [])
{
String str = "This is a string!" ;
return 0 ;
}
代码情缘 // 1 行中定义了一个带有 2 个参数的宏 average
#define average(a, b) (a+b)/2
int main ()
{
// 4 行其实会被替换成: int a = (10 + 4)/2;
int a = average ( 10 , 4 );
// 输出结果为: 7 是不是感觉这个宏有点像函数呢?
printf ( " 平均值: %d" , a );
return 0 ;
}
注意点 :
1) 宏名和参数列表之间不能有空格,否则空格后面的所有字符串都作为替换的字符串 .
#define average (a, b) (a+b)/2
int main ()
{
int a = average ( 10 , 4 );
return 0 ;
}
注意第 1 行的宏定义,宏名 average ( a , b ) 之间是有空格的,于是,第 5 行就变成了这样:
int a = ( a , b ) ( a + b ) / 2 ( 10 , 4 );
这个肯定是编译不通过的
2) 带参数的宏在展开时,只作简单的字符和参数的替换,不进行任何计算操作。所以在定义宏时,
一般用一个小括号括住字符串的参数。
#include <stdio.h>
// 下面定义一个宏 D(a) ,作用是返回 a 2 倍数值:
#define D(a) 2*a
// 如果定义宏的时候不用小括号括住参数
int main ()
{
// 将被替换成 int b = 2*3+4; ,输出结果 10 ,如果定义宏的时候用小括号括住参数,把上面的第 3 行改
成: #define D(a) 2*(a) ,注意右边的 a 是有括号的,第 7 行将被替换成 int b = 2*(3+4); ,输出结果
14
int b = D ( 3 + 4 );
printf ( "%d" , b );
return 0 ;
}
3) 计算结果最好也用括号括起来
代码情缘 条件编译
在很多情况下,我们希望程序的其中一部分代码只有在满足一定条件时才进行编译,否则不参与编
( 只有参与编译的代码最终才能被执行 ) ,这就是条件编译。
为什么要使用条件编译
1) 按不同的条件去编译不同的程序部分 , 因而产生不同的目标代码文件。有利于程序的移植和
调试。
2) 条件编译当然也可以用条件语句来实现。 但是用条件语句将会对整个源程序进行编译 , 生成
的目标代码程序很长 , 而采用条件编译 , 则根据条件只编译其中的程序段 1 或程序段 2, 生成的目
标程序较短。
##if-#else 条件编译指令
第一种格式 :
它的功能是 , 如常量表达式的值为真 ( 0), 则将 code1 编译到程序中 , 否则对 code2 编译到程序
中。
注意 :
是将代码编译进可执行程序 , 而不是执行代码
条件编译后面的条件表达式中不能识别变量 , 它里面只能识别常量和宏定义
#include <stdio.h>
// 下面定义一个宏 P(a) ,作用是返回 a 的平方
#define Pow(a) (a) * (a) // 如果不用小括号括住计算结果
int main ( int argc , const char * argv []) {
// 代码被替换为 :int b = (10) * (10) / (2) * (2);
// 简化之后: int b = 10 * (10 / 2) * 2; ,最后变量 b :100
int b = Pow ( 10 ) / Pow ( 2 );
printf ( "%d" , b );
return 0 ;
}
#include <stdio.h>
// 计算结果用括号括起来
#define Pow(a) ( (a) * (a) )
int main ( int argc , const char * argv []) {
// 代码被替换为 :int b = ( (10) * (10) ) / ( (2) * (2) );
// 简化之后: int b = (10 * 10) / (2 *2); ,最后输出结果: 25
int b = Pow ( 10 ) / Pow ( 2 );
printf ( "%d" , b );
return 0 ;
}
#if 常量表达式
.. code1 ...
#else
.. code2 ...
#endif
代码情缘 第二种格式 :
typedef 关键字
C 语言不仅
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值