C语言预处理器专项练习题
说明: 本练习包含16道题目,涵盖宏定义、条件编译和文件包含等C语言预处理器知识点。前13题为程序阅读题,后3题为综合应用题。
第一部分:程序阅读题(1-13题)
题目1:基本宏定义 简单
#include <stdio.h>
#define PI 3.14
#define R 5
int main() {
double area = PI * R * R;
printf("面积 = %.2f\n", area);
return 0;
}
问题: 程序输出结果是什么?
题目2:带参数宏定义 简单
#include <stdio.h>
#define SQUARE(x) x * x
int main() {
int a = 5;
printf("%d\n", SQUARE(a));
printf("%d\n", SQUARE(a+1));
return 0;
}
问题: 程序输出结果是什么?为什么第二个结果?
题目3:带括号的宏定义 中等
#include <stdio.h>
#define SQUARE(x) (x) * (x)
int main() {
int a = 5;
printf("%d\n", SQUARE(a+1));
return 0;
}
问题: 程序输出结果是什么?与上一题有何不同?
答案:
与上一题的区别在于添加了括号,确保了正确的运算顺序。
题目4:宏定义中的三目运算符 中等
#include <stdio.h>
#define MAX(a, b) ((a) > (b) ? (a) : (b))
int main() {
int x = 5, y = 8;
printf("%d\n", MAX(x, y));
return 0;
}
问题: 程序输出结果是什么?
题目5:宏参数副作用 困难
#include <stdio.h>
#define MAX(a, b) ((a) > (b) ? (a) : (b))
int main() {
int x = 5, y = 8;
printf("%d\n", MAX(++x, ++y));
printf("x = %d, y = %d\n", x, y);
return 0;
}
问题: 程序输出结果是什么?x和y的最终值是多少?
题目6:字符串化运算符# 中等
#include <stdio.h>
#define STR(s) #s
int main() {
printf("%s\n", STR(Hello World));
printf("%s\n", STR(123));
return 0;
}
问题: 程序输出结果是什么?
题目7:连接运算符## 中等
#include <stdio.h>
#define CONCAT(a, b) a##b
int main() {
int xy = 100;
printf("%d\n", CONCAT(x, y));
return 0;
}
问题: 程序输出结果是什么?
##运算符将两个标记连接成一个。
题目8:#ifdef和#ifndef条件编译 简单
#include <stdio.h>
#define DEBUG
int main() {
#ifdef DEBUG
printf("调试模式\n");
#endif
#ifndef RELEASE
printf("非发布模式\n");
#endif
return 0;
}
问题: 程序输出结果是什么?
#ifdef判断标识符是否已定义,#ifndef判断是否未定义。
题目9:#if条件编译 中等
#include <stdio.h>
#define VERSION 2
int main() {
#if VERSION == 1
printf("版本1\n");
#elif VERSION == 2
printf("版本2\n");
#else
printf("未知版本\n");
#endif
return 0;
}
问题: 程序输出结果是什么?
答案:
#if根据常量表达式结果决定编译哪部分代码。
题目10:条件编译嵌套 困难
#include <stdio.h>
#define OS 1
#define DEBUG 1
int main() {
#if OS == 1
#if DEBUG
printf("Windows调试版\n");
#else
printf("Windows发布版\n");
#endif
#elif OS == 2
printf("Linux版\n");
#endif
return 0;
}
问题: 程序输出结果是什么?
答案:
条件编译可以嵌套使用。
题目11:#include的使用 简单
// math_utils.h 文件内容:
// #define PI 3.14159
// double circle_area(double r) { return PI * r * r; }
#include <stdio.h>
#include "math_utils.h"
int main() {
double r = 3.0;
printf("半径%.1f的圆面积: %.2f\n", r, circle_area(r));
return 0;
}
问题: 假设math_utils.h文件存在且内容如上,程序输出结果是什么?
答案:
#include用于包含头文件,双引号表示先从当前目录查找。
题目12:宏定义与优先级 困难
#include <stdio.h>
#define MUL(a, b) a * b
int main() {
int result = MUL(2+3, 4+5);
printf("%d\n", result);
return 0;
}
问题: 程序输出结果是什么?如何修正?
答案:
修正方法:#define MUL(a, b) ((a) * (b))
题目13:综合宏应用 困难
#include <stdio.h>
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define SQUARE(x) ((x) * (x))
#define PRINT_INT(x) printf(#x " = %d\n", x)
int main() {
int a = 3, b = 4;
PRINT_INT(MAX(SQUARE(a), b));
return 0;
}
问题: 程序输出结果是什么?
答案:
宏展开过程:MAX(SQUARE(3), 4) → MAX(9, 4) → 9。
第二部分:综合应用题(14-16题)
题目14:设计调试宏 中等
#include <stdio.h>
// 请补充以下宏定义,实现调试输出功能
// 当定义了DEBUG宏时,DEBUG_PRINT输出调试信息
// 否则DEBUG_PRINT不执行任何操作
__________ DEBUG_PRINT(msg) __________
int main() {
int x = 5, y = 10;
__________
DEBUG_PRINT("开始计算");
__________
int sum = x + y;
__________
DEBUG_PRINT("计算结果");
printf("sum = %d\n", sum);
__________
return 0;
}
此题考查条件编译与宏定义的结合使用,实现调试信息的条件输出。
题目15:安全交换宏 困难
#include <stdio.h>
// 请设计一个安全的交换宏,能够交换两个同类型变量的值
// 要求:避免参数副作用,支持多种数据类型
#define SWAP(type, a, b) _______________________________
int main() {
int x = 5, y = 10;
printf("交换前: x=%d, y=%d\n", x, y);
SWAP(int, x, y);
printf("交换后: x=%d, y=%d\n", x, y);
double d1 = 3.14, d2 = 2.71;
printf("交换前: d1=%.2f, d2=%.2f\n", d1, d2);
SWAP(double, d1, d2);
printf("交换后: d1=%.2f, d2=%.2f\n", d1, d2);
return 0;
}
总结: 本练习涵盖了C语言预处理器的核心知识点。宏定义要注意括号使用和参数副作用,条件编译可实现跨平台和调试功能,文件包含是模块化编程的基础。掌握这些知识点对编写高质量C程序至关重要。