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

本文详细解释了C语言中的预处理指令、预定义符号的作用,编译流程中的预处理阶段,以及头文件的使用、条件编译、结构体偏移量计算和奇偶位交换宏的编写。
摘要由CSDN通过智能技术生成

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;
}

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值