C语言学习记录—进阶作业7(预处理操作+链接)

发布时间:2024年01月10日

1.?下面哪个不是预处理指令:( ? )

A.#define
B.#if
C.#undef
D.#end
答案:D - 正确为#endif

2.?下面哪个不是预定义符号?( )

A.__FILE__
B.__TIME__
C.__DATE__
D.__MAIN__
答案:D
?

3. () 的作用是将源程序文件进行处理,生成一个中间文件,编译系统将对此中间文件进行编译并生成目标代码。

A.预处理
B.汇编
C.生成安装文件
D.编译
答案:A
?

4.?由多个源文件组成的C程序,经过编辑、预处理、编译、链接等阶段会生成最终的可执行程序。下面哪个阶段可以发现被调用的函数未定义?()

A.预处理
B.编译
C.链接
D.执行
答案:C
?

5. 文件中定义的四个变量,哪个不是指针类型()

//test.c文件中包括如下语句
#define INT_PTR int*
typedef int* int_ptr;
INT_PTR a,b;//int* a,b;  a的类型是int* b的类型是int
int_ptr c,d;//typedef对int*重命名,int_ptr是一个独立可用的类型
//A.a
//B.b
//C.c
//D.d
//答案:B

6.?C语言头文件中的 ifndef / define / endif 的作用?()

A.防止头文件重复引用
B.规范化代码
C.标志被引用文件内容中可以被共享的代码
D.以上都不正确
答案:A
?

7.?执行语句:z = 2 * (N + Y(5 + 1)); 后,z的值为( ? )

//设有以下宏定义:
#define N 4
#define Y(n) ((N+2)*n) /*这种定义在编程规范中是严格禁止的*/
//A.出错
//B.60
//C.48
//D.70
//答案:D

//替换
//#define N 4
//#define Y(n) ((N+2)*n)
//z = 2 * (N + Y(5 + 1));
//z = 2 * (4 + ((4+2)*5 + 1));


8.?下面代码执行的结果是:( ? )

#define A 2+2
#define B 3+3
#define C A*B
int main()
{
	printf("%d\n", C);
	return 0;
}
//A.24
//B.11
//C.10
//D.23
//答案:B

//替换
//#define A 2+2
//#define B 3+3
//#define C 2+2*3+3

9.?下面哪个不是宏和函数的区别?( ? )

A.函数可以递归,宏不能递归
B.函数参数有类型检查,宏参数无类型检查
C.函数的执行速度更快,宏的执行速度慢
D.由于宏是通过替换完成的,所以操作符的优先级会影响宏的求值,应该尽量使用括号明确优先级
答案:C
?

10.?下面哪个是条件编译指令( )

A.#define
B.#ifdef
C.#pragma
D.#error
答案:B
?

11.?以下关于头文件,说法正确的是( )

A.#include<filename.h>,编译器寻找头文件时,会从当前编译的源文件所在的目录去找
B.#include"filename.h",编译器寻找头文件时,会从通过编译选项指定的库目录去找
C.多个源文件同时用到的全局整数变量,它的声明和定义都放在头文件中,是好的编程习惯
D.在大型项目开发中,把所有自定义的数据类型、函数声明都放在一个头文件中,各个源文件都只需要包含这个头文件即可,省去了要写很多#include语句的麻烦,是好的编程习惯。
答案:D ??
C选项这种做法会导致包含头文件就出现,那么可能在多个源文件中出现导致重定义
?

12.?写一个宏,计算结构体中某变量相对于首地址的偏移,并给出说明

#include <stddef.h>
#define OFFSETOF(type, m_name) ((size_t)&(((type*)0)->m_name))
//假设0地址处放一个结构体对象的地址(也可以理解为使用一个空指针类型强制转换为结构体类型指针),
//通过结构体指针找到成员再取出成员的地址,把地址强制转换成size_t得到偏移量
struct S
{
	char c1;
	int i;
	char c2;
};
int main()
{
	struct S s = { 0 };
	printf("%d\n", OFFSETOF(struct S, c1));//0
	printf("%d\n", OFFSETOF(struct S, i));//4
	printf("%d\n", OFFSETOF(struct S, c2));//8
	//printf("%d\n", offsetof(struct S, c1));//0
	//printf("%d\n", offsetof(struct S, i));//4
	//printf("%d\n", offsetof(struct S, c2));//8
	return 0;
}

13.?交换奇偶位

写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换。

//思路:
//假设右边第一位是第0位,即偶数位
//把所有的偶数位提出来,向左移动一位;把所有的奇数位提出来,向右移动一位
//提出偶数位的方法,将该数的二进制序列与 一个所有偶数位都是1,所有奇数位都是0的二进制序列按位与
//即保留偶数位,让奇数位都改为0
//10100101110011110011010110101111 - 假设一个数的二进制
//01010101010101010101010101010101 - 【偶数位都是1,奇数位都是0】二进制序列的十六进制为0x55555555
//00000101010001010001010100000101 - n&0x55555555

//提出奇数位的方法相同,将该数的二进制序列与 一个所有偶数位都是0,所有奇数位都是1的二进制序列按位与
//10100101110011110011010110101111 - 假设一个数的二进制
//10101010101010101010101010101010 - 【偶数位都是0,奇数位都是1】二进制序列的十六进制为0xaaaaaaaa
//10100000100010100010000010101010 - n&0xaaaaaaaa
//最后将所有偶数位向左移动一位((n&0x55555555)<<1)结果 + 所有奇数位向右移动一位((0xaaaaaaaa)>>1)的结果
#include <stdio.h>
#define SWAP_BIT(n) n=(((n&0x55555555)<<1)+((n&0xaaaaaaaa)>>1))
int main()
{
	int n = 0;
	scanf("%d", &n);
	//假设n=10
	//1010 - 10
	//0101 - 5
	SWAP_BIT(n);
	printf("%d\n", n);
	return 0;
}

文章来源:https://blog.csdn.net/Awkwardx/article/details/135490388
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。