嵌入式C语言——常见面试题

1、描述一下gcc编译过程?

gcc编译过程分为4步骤:预处理、编译、汇编、链接。

  • 预处理:头文件包含、宏替换、条件编译、删除注释。
  • 编译:主要进行词法、语法、语义分析等等,检查无误后把预处理好的文件编译成汇编文件。
  • 汇编:汇编文件转换为二进制目标文件。
  • 链接:把项目中的各个二进制文件 + 所需的库 + 启动代码链接为可执行文件。

2、内存最小存储单位以及内存的最小计量单位分别是?

内存的最小存储单位是二进制位,内存的最小计量单位:字节

3、#include<> 和#include""差异?

include<>到系统指定目录寻找头文件,#include ""先到项目所在目录寻找头文件,如果没有找再到系 统指定的目录下寻找。

4、描述一下变量的命名规则?

变量名可以由字母、数值、下划线构成,但不能直接以数值开头。

5、变量的声明和定义?

声明变量不需要建立存储空间,变量的定义需要建立一个存储空间。

6、谈谈C语言的有符号和无符号的差异?

  • 有符号:数据的最高位表示符号位,0代表正数,1代表着负数。
  • 无符号:数据的最高位不是符号位,而是数据整体的一部分。

7、谈谈计算机补码意义?

  • 统一了0的编码。
  • 把符号位和其他位统一处理。
  • 把减法运算转换为加法运算

8、谈谈数组特征?

同一个数组的成员都是相同的数据类型,同时所有的成员在内存中的地址也都是连续的。

注意:数组是存放在连续内存空间上的相同类型数据的集合。

  • 数组下标都是从0开始。
  • 数组内存空间地址都是连续。

在这里插入图片描述

9、数组分类

  • 静态数组:类似int arr[5];在程序运行就确定了数组的大小,运行过程无法改变数组的大小。
  • 动态数组:主要是在堆区申请的内存空间,数组的大小还是在程序运行中确定的,可以更改数组的大小。

10、描述一维数组的不初始化、部分初始化、完全初始化的不同特点?

  • 不初始化:若是一个局部数组,则数组元素内容随机,若是全局数组,则数组元素内容为0.
  • 部分初始化:没有初始化的部分自动补零。
  • 完全初始化:若一个数组全部初始化,则省略元素个数的数组大小由初始化的个数确定。

11、谈谈数组名作为类型、作为地址、对数组名取地址的区别?

  • 数组名作为类型:代表着整个数组的大小。
  • 数组名作为地址:代表着数组首元素的地址。
  • 数组名取地址:代表数组的首地址。

12、谈谈你对二维数组在物理上以及逻辑上的数组维度理解?

二维数组逻辑上是二维的,物理上是一维的。

13、描述一下函数定义和函数声明的差异?

  • 函数定义:对函数功能确定、指定函数名称,函数类型,形参及其类型,函数体等等,都是一个完整的,独立的函数单位。
  • 函数声明:函数名字、函数类型和形参个数、类型和顺序告知编译器,便于在包含函数调用的语句进行编译时,据此对其进行对照验证检查。

14、描述一下指针和指针变量的差异?

指针:内存中的每一个字节都会分配一个32位或者64位的编号,这个编号就是地址,而指针就是内存单元的编号。
指针变量:本质就是变量,只是该变量存放的是空间的地址编号。

15、描述一下32位或者64位平台下的指针大小

  • 32位平台:任意类型的指针大小是4字节。
  • 64位平台:任意类型的指针大小都是8字节。

16、描述一下指针数组概念?

指针数组本质就是数组,只不过数组的每一个元素存储的都是一个指针(地址)

17、描述一下普通局部变量、普通全局变量、静态局部变量、静态全局变量的差异?

  • 普通局部变量:存放在栈区,若不初始化内容则随机值,只会在定义的语句块内有效,语句块结束之后变量空间就会被释放掉弹出。
  • 普通全局变量:存放在内存全局区,若不初始化内容则默认0,进程结束空间才会被释放,能够被当前源文件或者其他文件使用;

注意:其他文件调用该全局变量,需要使用extern修饰。

  • 静态局部变量:存放在全局区,不被初始化内容则默认0,整个进程结束空间才会被释放,只能够在定义的语句块内有效。
  • 静态全局变量:存放在内存全局区,不初始化则默认0,整个进程结束空间会被释放,只能够被当前源文件使用。

18、描述一下内存分区?

  • 程序运行之前:分为代码区、BSS段(未初始化数据区)、data段(初始化数据区)。
  • 程序运行之后:栈、堆、全局区(静态区)、文字常量区、代码区。
    在这里插入图片描述

19、使用realloc给已分配的堆区空间追加空间时需要注意什么?

注意:需要使用指针变量保存realloc的返回值。

20、谈谈文件的分类?

  • 二进制文件基于数值编码,需要根据具体应用解析。
  • 文本文件基于字符集编码,一个字节一个意思,可以直接通过记事本打开。

21、文件缓冲区刷新有几种刷新模式?

行刷新、满刷新、强制刷新、关闭刷新。

22、如何理解结构体的深拷贝和浅拷贝?

若结构体有指针成员的时候容易出现该问题。

浅拷贝:两个结构体变量的指针成员指向了同一个堆区空间,在各个结构体变量释放的时候会出现多次释放同一段堆区空间的情况。

深拷贝:让两个结构体变量的指针成员分别指向了不同的堆区空间,只是空间内容拷贝一份,这样在各个结构体变量释放的时候就不会出现多次释放同一段堆区空间的问题。

23、描述一下结构体对齐规则?

  1. 结构体成员对齐规则。第一个结构体成员应该放在offffset(偏移量)为0的地方,以后每个数组成员应该放在offffset 为min(当前成员的大小,#pargama pack(n))整数倍的地方开始(比如int在32位机器为4字节,#pargama pack(2),那么从2的倍数地方开始存储)。

  2. 结构体总的大小,也就是sizeof的结果,必须是min(结构体内部最大成员,#pargama pack(n))的整数倍,不足要补⻬。

  3. 结构体做为成员的对齐规则。如果一个结构体B里嵌套另⼀个结构体A,还是以最大成员类型的大小对齐,但是结构体A的起点为A内部最大成员的整数倍的地方。(struct B里存有struct A,A里有char,int,double等成员,那A应该从8的整数倍开始存储。),结构体A中的成员的对齐规则仍满足原则1、原则2。

  • 7
    点赞
  • 122
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
sscanf函数是C语言中一个非常常用的函数,它可以将一个字符串按照指定的格式转换成相应的数据类型。在嵌入式开发中,sscanf函数也是非常常见的,因为很多时候需要从串口或者其他外部设备中读取数据,并将其转换成相应的数据类型进行处理。下面是一些sscanf函数的使用技巧: 1. 使用sscanf函数时一定要注意格式字符串的正确性。格式字符串中的占位符必须与待转换的数据类型相对应,否则会发生未知错误。 2. 如果待转换的字符串中包含多个数据,可以使用多个占位符进行转换。例如,如果待转换的字符串为"1,2,3",可以使用" %d,%d,%d"的格式字符串进行转换。 3. 可以使用sscanf函数的返回值来判断转换是否成功。如果返回值等于待转换字符串的长度,则说明转换成功,否则转换失败。 4. 如果待转换的字符串中包含浮点数,可以使用"%f"或者"%lf"的格式字符串进行转换。 5. 如果待转换的字符串中包含十六进制数,可以使用"%x"的格式字符串进行转换。 6. 如果待转换的字符串中包含字符或字符串,可以使用"%c"或者"%s"的格式字符串进行转换。 7. 如果待转换的字符串中包含指针类型的数据,可以使用"%p"的格式字符串进行转换。 总之,在使用sscanf函数时一定要注意格式字符串的正确性,否则很容易出现转换错误的情况。同时,还应该注意sscanf函数返回值的判断,以确保转换的正确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值