STM32C语言基础

1、预编译的工作?
编译“#”号开头的代码。例如#include拷贝头文件代码;#define宏定义替换,#ifndef条件编译

2、什么时候需要预编译?
不常改动但又常使用的代码;
多模块都使用一组标准的包含文件和相同的编译选项,将所有包含文件预编译成一个预编译头

3、#与##的区别?
#的作用是将宏参数转成一个字符串
##的作用是连接两个宏参数
在这里插入图片描述
在这里插入图片描述

4、如何避免头文件被重复包含?
使用#ifndef
#define
。。。。
#endif

5、static关键字的作用?
隐藏作用:可以在不同的文件中定义同名变量和同名函数
持久性:对于变量来说,保持变量的持久,静态数据区的变量会在程序刚刚运行时就完成初始化,也是唯一一次的初始化;静态储存区只有两种变量—全局变量与static静态变量。
默认值为0:默认初始化为0x00,和全局变量一样的属性,减少程序员的工作量

6、const关键字的作用?
限制作用,对变量加以限定,不能被修改。
const int *p1; //指针所指向的数据是只读,p1的值可以修改,但指向的数据不能被修改;
int const *p1; //指针所指向的数据是只读,p1的值可以修改,但指向的数据不能被修改;
int *const p3;//指针是只读的,p3本身的值不能被修改;

7、volatile关键字的作用?
首先引入编译器优化的概念,内存访问速度远远比不上CPU出力速度,为了提高性能,从硬件上引入了高速缓存,加速对内存的访问。
编译优化的方法有,将内存变量缓存到寄存器;调整指令顺序充分利用CPU指令流水线;
因为访问寄存器要比访问内存单元要快得多,编译器会做减少存取得优化,当使用volatile声明函数变量时,系统总是重新从它所在得内存读取数据,遇到这个关键字声明的变量,编译器对访问该变量的代码不再进行优化,从而提供对特殊地址的稳定访问,如果不使用volatile,编译器将对所有声明的语句进行优化,以免出错。

8、sizeof 与 strlen 的区别?
sizeof是操纵符,strlen是函数;

9、什么是结构体位域?
位域类型:char,short,int
例如
struct weiyu
{
unsinged char a:7//字段a占用一个字节的7bit
unsinged char b:2//字段b占用一个字节的2bit
}s1;
位域的好处:并不需要完整的字节,节省存储空间,处理简单;方便利用位域把一个变量按位域分解,当是不利于程序的移植

10、计算结构体的大小?
首先学习一下基础:
①结构体偏移量:结构体中的偏移量指的是一个成员的实际地址和结构体首地址之间的距离;注意是首地址;
②结构体大小的计算方法:结构体涉及到字节对齐,目的是为了计算机快速读取,用空间交换速度。公式是最后一个成员的大小+最后一个成员的偏移量+末尾的填充节数;
③结构体内偏移规则:每个成员的偏移量都必须是当前成员所占内存大小的整数倍,如果不是 整数倍,编译器会在前填充字节。当所有成员大小计算完毕后,编译器会对当前结构体大小是否是最宽的 结构体成员的大小的整数倍,如果不是整数倍,编译器会填充字节。
Struct s1{ 成员的大小 成员的偏移量
int a; 4 0
char b; 1 4
int c; 4 5 // b的4 + c的1 = 5 5不是4的倍数,所以是5+3
long d; 8 13+3
char h; 1 17++7=24
}
Sizeof(s1)=24+1+7(填充字节) //25,因为最宽是8,25不是8的整数倍,所加7

11、引用和指针的区别?
引用需要初始化,而指针不需要;
引用初始化后不能改变,而指针可以改变所指对象;
不存在空值的引用,而指针可以的空指针;

12、include<stdio.h>与include"stdio.h"有什么区别?
前者从编译器自带的库函数中寻找文件,从标准库路径开始搜做文件
后者是从自定义的文件中寻找,寻找不到再到库函数中寻找文件

13、全局变量与局部变量的区别?
全局变量:存储在静态数据区,占用静态的存储单元
局部变量:存储在栈中,只有在函数被调用过程中才开始分配存储单元

14、堆栈溢出的原因有哪些?
函数调用层次太深,函数递归调用时,系统要在栈中不断的保存函数调用时的线程和产生的变量,递归太深,会造成栈溢出,这时递归无法返回。
动态申请空间使用后没有释放,因为C语言没有垃圾资源自动回收机制,所以需要程序员主动释放已经不再使用的动态地址空间
数组访问越界,C语言没有提供数组下标越界检查,如果在程序中出现数组下标访问超出数据范围,运行过程中可能会存在内存访问错误
指针非法访问,指针保存了一个非法地址,通过非法地址访问时会产生内存访问错误

15、队列和栈的区别?
相同点:栈和队列是限定插入和删除只能在表的“端点”进行的线性表
不同点:栈元素必须是“先进后出”,队列元素必须是“先进先出”

16、局部变量能否与全局变量重名?
可以,局部变量会屏蔽全局变量,使用全局变量,即在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量,当需使用”::”; 局部变量可以与全局变量同名,。

19、如何引用一个已经定义了的全局变量?
使用 extern 关键字;
引用头文件,前提是其中只能有一个 C 文件中对此变量赋初值,此时连接不会出错;

20、全局变量可不可以定义在可被多个.c 文件包含的头文件中,为什么?
可以,在不同的 C 文件中各自用 static 声明的全局变量,变量名可能相同,但是 各自 C 文件中的全局变量的作用域为该文件,所以互不干扰

21、static 关键字在全局变量、局部变量、函数的区别?
static+全局变量:改变作用域,改变(限制)其使用范围。 只初始化一次,防止在其他文件单元中被引用。全局变量的作用域是整个源程序,在各个源文件中都是有效的,而加了静态后的全局变量的作用域 仅限于一个源文件中。
static+局部变量:改变看它的存储方式,也就是改变了它的生存期。
static+普通函数:作用域不同,仅在本文件。 只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义,对于可在当前源文件以外使用的函数,应该在一个 头文件中说明,要使用这些函数的源文件要包含这个头文件。

22、程序的内存分配?
c 语言程序.c 文件经过编译、连接后形成的二进制映像文件由堆、栈、数据段(只读数据段,未初始化数据段 BSS,已初始化数据段三部分)、代码段组成。
栈区 (stack):由编译器进行管理,自动分配和释放,存放的是函数调用过 程中的各种参数,局部变量,返回值以及函数返回地址。
堆区(heap) :用于程序动态申请分配和释放空间,malloc 和 free,程序员 申请的空间在使用结束后应该释放,则程序自动收回。
全局(静态)存储区:分为 DATA(已经初始化),BSS(未初始化)段,DATA 段存放的是全局变量和静态变量; BSS(未初始化)存放未初始化的全局变量和 静态变量。 程序运行结束后自动释放,其中 BSS(全部未初始化区)会被系统自动 清零。
④文字常量区 :存放常量字符串,程序结束后由系统释放。
⑤程序代码段:存放程序的二进制代码。

23、解释”堆”和”栈”的区别?
申请方式:
Strack(栈): 由编译器自带分配释放,存放函数的参数值,局部变量等。
Heap(堆):程序员自己申请,并指名大小–>malloc 函数。
申请后的系统响应
Strack(栈):只要栈剩余空间大于所申请空间,都会提供。 Heap(堆):操作系统有记录空闲内存的链表:收到申请->遍历链表->寻找->申请空间的堆结点
申请内存的大小限制
Strack(栈):向低地址扩展的数据结果,连续内存区域,栈获得的空间较小。
Heap(堆):向高地址扩展的,不连续内存区域;链表遍历方向为(低地址->高地址)。 栈获得空间灵活,空间也大。
申请效率
Strack(栈):系统自由分配,速度快。
Heap(堆):速度慢,容易产生内存碎片。
存储内容
Strack(栈):第一进栈 :主函数中的下一条指令的地址 -->函数的各个参数,参数由右往左 进栈。–>函数的局部变量(静态变量不入栈)。调用结束后,顺序相反,局部变量先出栈。
Heap(堆): 程序员自己安排分配方式
Strack(栈):栈有两种分配方式,静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配,动态分配由 malloca 函数进行分配,但栈的动态分配和堆是不同的,栈的动态内存由编译器进行释放,无需手工实现。
Heap(堆):堆都是动态分配的,没有静态分配的堆。

24、 结构体和联合体的区别:
结构体和联合体:都是由不同的数据类型成员组成,但是在同一时刻,联合体只存放了一 个被选中的成员(所有成员公用一块地址);而结构体成员都存在(不同成员存放地址不同)。
union lianheti
{
int i;
char m;
};
在联合体 lianheti中,整形量 i 和字符 m 共用一块内存位置。
当一个联合体被说明时,编译程序自动产生一个变量,其长度为联合体中最大的变量长度
联合体不同成员赋值,会对其他成员重写,原来成员的值会不存在。 结构体的不同成员赋值是互不影响的

/********************************************************************************************************************/
以上内容是学习群一位网友分享的,我整理了出来,如有侵权,私聊我,我删除文章

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值