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程序至关重要。