C语言笔面题--高级

c高级常见笔试题

  1. 枚举与# define宏的区别有哪些?

枚举与宏的概述
(1) 枚举:是指将变量的值一一列举出来,变量的值只限于列举出来的值的范围内
(2) # define宏定义是用一个指定的标识符来代表一个字符串

枚举与# define宏的区别
(1) 在编译器中可以调试枚举变量,不能调试宏常量
(2) # define宏常量是在预编译阶段进行简单替换。枚举常量则是在编译的时候才确定其值
(3) 枚举可以一次定义大量相关的常量,而# define宏一次只能定义一个

  1. 空结构体所占的内存是多少?

结构体所占内存大小是其成员所占内存之和
一个空结构体所占的内存是1字节
因为编译器认为任何一种数据都有自己的大小,这样用这样这个类型定义一个变量才能
分配正确的内存空间大小,在所有的数据类型中char占内存最小,为1字节。

  1. 枚举类型的优点

(1) 枚举常量相当于一个符号常量,因此具有见名知意的好处,可以增加程序的可读性
(2) 枚举类型的变量取值范围仅限于列出的枚举常量范围,若取值不在列出的范围内,系统会视为出错,这样可以帮助系统检查错误,降低程序的理解难度
(3) 枚举类型还便于系统对枚举变量进行类型检查,从而增强可安全性

  1. typedef与#define宏的相似之处与不同之处是什么?

(1) 相似之处
通常都可以理解为为一个字符起别名,在程序中用一个新的字符代替原有的字符
(2) 区别
a. 实质含义不同,# define是字符串替换,typedef是为类型起了一个别名
b. 宏定义的句尾没有分号作为结束标志,其本身并不在编译过程中进行,而是在预处理过程中就已经完成了很难发现潜在的错误

#define INT int* 
typedef int* my_intp;

INT i, i_p;  ==>    int* i, i_p; 
my_intp a, ap;
  1. 大小端模式对union类型数据有什么影响

    大小端模式
    (1) 大端模式存储:高位数据存放在低地址中
    (2) 小端模式存储:高位数据存放在高地址中
    大小端模式对共用体类型数据的影响
    Union型数据所占的内存等于其最大的成员所占的内存,对union型的成员的存取都是相对于该联合体基地址的偏移量为0处开始,也就是说联合体的访问无论对哪个变量的存取都是从union的首地址位置开始,因此大小端模式的存储将会直接影响union成员的值。

  2. 如何证明联合体变量的所有成员是共享一个内存单元的?

声明一个联合体类型有两个成员变量,一个是int型的数组,另一个是char型的数组,先按照其中一个int型数组成员赋值,然后按照另一个char型数组成员输出。若整型数组与字符数组是共享一个内存的,那么输出的内容与写入的内容应该是一致的,否则结果不一致。

  1. 字节对齐的问题

什么是字节对齐?

计算机中内存大小的基本单位是字节(byte),理论上来讲,可以从任意地址访问某种基本数据类型,但是实际上,计算机并非逐字节大小读写内存,而是以2,4,或8的倍数的字节块来读写内存,如此一来就会对基本数据类型的合法地址作出一些限制,即它的地址必须是2,4或8的倍数。那么就要求各种数据类型按照一定的规则在空间上排列,这就是对齐。===》通常32位的系统或者mcu是4字节对齐。

对齐准则是什么?

  • 结构体变量的首地址能够被其对齐字节数大小所整除。
  • 结构体每个成员相对结构体首地址的偏移都是成员大小的整数倍,如不满足,对前一个成员填充字节以满足。
  • 结构体的总大小为结构体对齐字节数大小的整数倍,如不满足,最后填充字节以满足。
#include<stdio.h>
#include<stdint.h>
struct test
{
    int a;
    char b;
    int c;
    short d;
};
int main(int argc,char *argv)
{
    printf("the size of struct test is %d\n",sizeof(struct test));
    return 0;
}

运行结果:

the size of struct test is 16

换一种定义方法

#include<stdio.h>
#include<stdint.h>
struct test
{
    int a;
    int c;
    char b;
    short d;
};
int main(int argc,char *argv)
{
    printf("the size of struct test is %d\n",sizeof(struct test));
    return 0;
}

运行结果:

the size of struct test is 12

结论:在设计结构的时候,合理调整成员的位置,可以大大节省存储空间

为什么要字节对齐?

​ 提高内存系统性能

跨平台编程

​ 可以使用#pragma pack(n),使得结构间一字节对齐

#pragma pack(1) /*1字节对齐*/
struct test
{
    int a;
    char b;
    int c;
    short d;
};

总结:

  • 结构体成员合理安排位置,以节省空间
  • 跨平台数据结构可考虑1字节对齐,节省空间但影响访问效率
  • 跨平台数据结构人为进行字节填充,提高访问效率但不节省空间
  • 本地数据采用默认对齐,以提高访问效率
  1. 如下的makefile中,执行make后终端的打印结果是什么
all:cd ef
	@echo 123
cd:
	@echo 456
ef:
	@echo 789

​ 答案:

456
789
123
  1. 如下的makefile中,执行make后终端的打印结果是什么

Makefile

x := foo
y := $(x)b
x := new  

.PHONY : test

test :
	@echo "x => $(x)"
	@echo "y => $(y)"

结果:

x => new
y => foob

Makefile

x = foo
y = $(x)b
x = new

a = $(b)
b = $(c)
c = hello-makefile  

.PHONY : test

test :
	@echo "x => $(x)"
	@echo "y => $(y)"
	@echo "a => $(a)"
	@echo "b => $(b)"
	@echo "c => $(c)"

结果:

x => new
y => newb
a => hello-makefile
b => hello-makefile
c => hello-makefile

Makefile

x := foo
y := $(x)b
x ?= new   

.PHONY : test

test :
	@echo "x => $(x)"
	@echo "y => $(y)"


结果:

x => foo
y => foob

Makefile

x := foo
y := $(x)b
x += new  

.PHONY : test

test :
	@echo "x => $(x)"
	@echo "y => $(y)"

结果:

x => foo new
y => foob

总结:

​ 简单赋值 (:=)

​ 递归赋值 ( = )

​ 条件赋值( ?= )

​ 追加赋值( += )

  1. 如下的Makefile中,执行make后终端的显示结果是
Makefile

```makefile
.PHONY : all first second third 
  
all : first second third
	@echo "\$$@ => $@"
	@echo "$$^ => $^"
	@echo "$$< => $<"

```

结果:

```
$@ => all
$^ => first second third
$< => first

```

总结:

​	&@ 当前规则中触发命令被执行的目标

​	&^   当前规则中所有的依赖

​	&<  当前规则中第一个依赖

应用:

```makefile
CC := gcc
TARGET := hello-world.out

$(TARGET) : func.o main.o
	$(CC) -o $@ $^

func.o : func.c
	$(CC) -o $@ -c $^

main.o : main.c
	$(CC) -o $@ -c $^

.PHONY : rebuild clean all

rebuild : clean all


all : $(TARGET)

clean :
	rm *.o $(TARGET)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值