当前位置: 首页 > news >正文

嵌入式面试八股文(七)·#ifndef#define#endif的作用、以及内存分区(全局区、堆区、栈区、代码区)

目录

1.  头文件中的#ifndef / #define / #endif的作用是什么?

2.  内存分区:全局区、堆区、栈区、代码区简单描述?

2.1  代码区(Text Segment):

2.2  全局区(Data Segment):

2.3  堆区(Heap):

2.4  栈区(Stack):

3.  C语言各数据类型的取值范围?


1.  头文件中的#ifndef / #define / #endif的作用是什么?

#ifndef:用于判断指定的标识符是否已经被定义。如果该标识符未定义,则执行下面的代码块,否则跳过。

#ifndef MACRO_NAME// 如果没有定义 MACRO_NAME,则编译以下内容
#endif

#define:用于定义指定的标识符,通常用于定义宏。在条件编译中,一般用来定义一个标识符,以便在后面的代码中进行条件判断,通常用于定义一个标识符,用来标记某些代码块已经被处理过。通过定义宏来确保头文件只被包含一次。

#define MACRO_NAME

#endif:用于结束条件编译的代码块。

        三者常用写法:

#ifndef MY_HEADER_H  // 如果没有定义 MY_HEADER_H
#define MY_HEADER_H  // 定义 MY_HEADER_H,表示头文件已经包含// 头文件内容,如结构体、函数声明等#endif  // 结束条件编译块

工作原理:

第一次包含:

  •         当编译器处理一个头文件时,它遇到 #ifndef MY_HEADER_H。
  •         如果 MY_HEADER_H 没有被定义,则会进入条件编译块,并定义 MY_HEADER_H(通过 #define MY_HEADER_H)。
  •         然后,编译器继续编译头文件的内容。

第二次及之后的包含:

  •         如果该头文件在其他地方被再次包含,编译器会再次遇到 #ifndef MY_HEADER_H。
  •         由于宏 MY_HEADER_H 已经被定义,条件 #ifndef MY_HEADER_H 会失败,编译器跳过头文件的内容,不会重复定义和包含相同的内容。

2.  内存分区:全局区、堆区、栈区、代码区简单描述?

2.1  代码区(Text Segment)

作用:存放程序的机器指令,也就是程序的执行代码。

特点:是只读的,防止程序在运行时修改自己的指令。

           通常由操作系统在程序加载时分配,加载到内存中。

           大小固定,一般在程序编译时就确定。

2.2  全局区(Data Segment)

作用:存放程序中的全局变量、静态变量和常量。

特点已初始化的全局变量:如在程序中显式赋初值的全局变量,会存放在该区域。

           未初始化的全局变量:存放在一个叫做BSS(Block Started by Symbol)区的区域,程序启动时会自动初始化为零。

           全局变量在整个程序的生命周期内存在,直到程序结束。

           全局区在程序运行期间不会被改变大小。

2.3  堆区(Heap)

作用:用于动态分配内存。程序运行时可以向堆区申请内存空间(例如,通过 malloc、new 等动态内存分配函数)。

特点:内存的分配和释放由程序员管理(或者通过垃圾回收机制,如在某些高级语言中)。

           堆区内存大小可以动态变化,根据程序的需要增加或减少。

           如果没有及时释放堆区内存,可能导致内存泄漏

           堆区通常位于全局区和栈区之间。

2.4  栈区(Stack)

作用:存放局部变量、函数参数和函数调用时的返回地址等。

特点自动管理:栈的内存分配和释放由操作系统自动完成。函数调用时会自动分配栈空间,函数执行完后会自动释放。

           栈内存的分配遵循“后进先出”的原则(LIFO),即最后被压入栈的变量最先被弹出。

           栈区的大小通常有限,过多的函数调用可能会导致栈溢出

           栈区的内存是临时的,函数返回后,栈中的局部变量会被销毁。

简单来说:

  • 代码区:存储程序的代码,通常是只读的。
  • 全局区:存储全局变量和静态变量。
  • 堆区:用于动态分配内存,由程序员手动管理。
  • 栈区:存储局部变量和函数调用的相关信息,由操作系统自动管理。

3.  C语言各数据类型的取值范围?

关键字位数表示范围stdint关键字ST关键字
char8-128 ~ 127int8_ts8
unsigned char80 ~ 255uint8_tu8
short16-32768 ~ 32767int16_ts16
unsigned short160 ~ 65535uint16_tu16
int32-2147483648 ~ 2147483647int32_ts32
unsigned int320 ~ 4294967295uint32_tu32
long32-2147483648 ~ 2147483647
unsigned long320 ~ 4294967295
long long64-(2^64)/2 ~ (2^64)/2-1int64_t
unsigned long long640 ~ (2^64)-1uint64_t
float32-3.4e38 ~ 3.4e38
double64-1.7e308 ~ 1.7e308

千题千解·嵌入式工程师八股文详解_时光の尘的博客-CSDN博客

http://www.lryc.cn/news/484259.html

相关文章:

  • 【弱监督视频异常检测】2024-ESWA-基于扩散的弱监督视频异常检测常态预训练
  • Android 13 实现屏幕熄屏一段时候后关闭 Wi-Fi 和清空多任务列表
  • Elasticsearch磁盘占用大于95%时将所有索引置为只读
  • 删除 git config 保存的密码
  • Springboot环境搭建详解
  • SpringCloud框架学习(第三部分:Resilience4j 与 Micrometer)
  • Scala的Map集合(不可变)
  • 深入剖析:Spring MVC与Struts的较量
  • 4.Mybatis中,在Mapper的SQL映射文件中,使用<choose><when>无法识别参数的情况
  • antd proFromSelect 懒加载+模糊查询
  • Spring Boot 牛刀小试 org.springframework.boot:spring-boot-maven-plugin:找不到类错误
  • qt中ctrl+鼠标左键无法进入
  • 丹摩征文活动 | 丹摩智算平台:服务器虚拟化的璀璨明珠与实战秘籍
  • 本机ip地址和网络ip地址一样吗
  • websocket身份验证
  • 案例解读 | 某三甲医院IT监控体系升级实例
  • Ubuntu20.04 为脚本文件创建桌面快捷方式 ubuntu
  • LeetCode297.二叉树的序列化和反序列化
  • 应用程序部署(IIS的相关使用,sql server的相关使用)
  • 小程序源码-模版 100多套小程序(附源码)
  • UE5运行时创建slate窗口
  • 浅谈C#之单线程流式适配器
  • 【更新中】《硬件架构的艺术》笔记(三):处理多个时钟
  • 【matlab】数据类型01-数值型变量(整数、浮点数、复数、二进制和十六进制)
  • 引入第三方jar包部署服务器后找不到jar处理方法
  • neo4j desktop基本入门
  • 前端系统设计面试题(二)Javascript\Vue
  • 军工行业运维:监控易引领自主可控新潮流
  • unity3d————接口基础知识点
  • 蓝队基础5 -- 安全策略与防护技术