一:define宏常量
#define PI 3.1415926 /* 无类型,纯文本替换 */
#define MSG "hello"
发生在预处理阶段,只是简单“粘贴”。
无类型检查,容易出奇葩 bug:
#define SQR(x) x*x
int a = SQR(3+2); // 展开成 3+2*3+2 = 11,非 25
解决:加括号 #define SQR(x) ((x)*(x))
- define宏常量
- const只读变量
const double pi = 3.1415926; /* 有类型,受编译器检查 */
const int days[] = {31,28,31};
const本质是“只读变量”,仍然占内存,可以取地址
const int c = 5;
int *p = (int *)&c; /* 能通过指针强行改,但属于未定义行为 */
const只读变量在作用域、链接属性与普通变量相同:
const int x = 3;
// 外部默认是 extern conststatic const int x = 3;
// 仅在当前文件可见
3:枚举常量
enum color
{
RED,
GREEN,
BLUE
}; /* RED=0, GREEN=1, BLUE=6 */
enum color
{
RED,
GREEN=5,
BLUE
}; /* RED=0, GREEN=5, BLUE=6 */
enum color c = GREEN;
只能表示整型常量。
不会分配内存,除非定义了枚举变量本身。
编译器可见值,调试友好。
组合示例:圆周长 & 面积
#include
#define PI_F 3.1415926f /* 宏常量:方便改精度 */
const double PI_D = 3.141592653589793; /* 双精度 */
int main(void)
{
float r;
printf("输入半径: ");
scanf("%f", &r);
printf("单精度周长=%f 面积=%f\n", 2*PI_F*r, PI_F*r*r);
printf("双精度周长=%lf 面积=%lf\n", 2*PI_D*r, PI_D*r*r);
return 0;
}
常见的问题排查
1:宏无括号 #define MAX a+b -> #define MAX (a+b)
2: 修改 const *((int *)&c) = 10; -> 不要改,属于 UB
3: 枚举越界 enum { A=300 }; char x=A; -> 使用足够大的整型 (char只有一个字节 256)