《拉依达的嵌入式\驱动面试宝典》—C/CPP基础篇(一)

news2024/12/17 19:58:59

《拉依达的嵌入式\驱动面试宝典》—C/CPP基础篇(一)

在这里插入图片描述

你好,我是拉依达。
感谢所有阅读关注我的同学支持,目前博客累计阅读 27w,关注1.5w人。其中博客《最全Linux驱动开发全流程详细解析(持续更新)-CSDN博客》已经是 Linux驱动 相关内容搜索的推荐首位,感谢大家支持。

《拉依达的嵌入式\驱动面试宝典》 最开始我个人的面试学习笔记,里面整合了所有我认为可能遇到的技术面试问题。随着我个人的学习以及参与面试,对内容不断完善。现在我已经步入工作阶段,空闲时间将之前的学习内容进行重新编排整理,并且加入了工作后更新系统的理解。是所有博客中投入最大的一个系列。包含我个人学习中所有的精华内容,希望可以最大限度的帮助到你。

所有问题及其答案均是我个人学习后查阅资料总结,每个回答都做了仔细的分析,在嵌入式及其驱动面试相关问题解析做到独一无二。

其中包含嵌入式软件开发、嵌入式驱动开发、linux驱动开发等职位遇到的所有技术方向问题。尤其是对驱动等底层问题的解析,适合准备相关工作或者学习提升的同学

————————————————————————————————————

第1章 C/CPP基础

1.1 编译

头文件的两种包含方式的区别

  • #include <> 的查找位置是系统目录,是标准库头文件所在目录;
  • #include “” 的查找位置是当前源文件所在目录 , 找不到再去系统目录;

动态库(.so/.dll)与静态库(.a/.lib)的区别

文件后缀不同

  • 静态库,linux系统下:xxx.a;window系统下:xxx.lib
  • 动态库,linux系统下:xxx.so;window系统下:xxx.dll

链接时期不同

  • 静态库是在链接阶段与其它.o文件链接成可执行程序,所以可执行程序体积相对较大
  • 动态库是在可执行文件运行时再加载到内存中

占用磁盘大小不同

  • 有n个可执行文件引用了同一个静态库,那么该静态库在磁盘中就有n个拷贝
  • 有n个可执行文件引用了同一个动态库,那么该动态库在磁盘中只有1个拷贝

库的发布方式不同

  • 修改静态库,除了重新编译静态库之外,还需要重新编译程序,再将程序发布出去
  • 修改动态库,只需要重新编译动态库,只发布动态库即可

程序启动速度不同

  • 使用静态库的程序启动速度较快,因为不需要花时间加载库
  • 使用动态库的程序启动速度较慢,因为需要花时间将动态库加载到内存

简述gcc编译过程

预编译、编译、汇编和链接

  1. 预编译阶段:hello.c–>hello.i , 加入头文件,替换宏,用于处理#开头的指令
  2. 编译阶段:hello.i–>hello.s , c/cpp程序转换成汇编程序
  3. 汇编阶段:hello.s–>hello.o , 将汇编程序转换成可链接的二进制程序
  4. 链接阶段:hello.o–>hello , 可链接的二进制程序和其它别的库链接在一起,形成可执行的程序文件。

静态链接和动态链接

  • 静态链接:链接过程把需要内容已经链接到了生成的可执行文件中,删除静态库程序运行不影响
  • 动态链接:链接过程没有把内容链接进去,而是在执行的过程中,再去找要链接的内容,删除动态库程序不能运行

静态链接优缺点:(动态链接相反)

  • 优点:运行不需要库
  • 缺点:编译出程序大,更新模块要全部重新编译

动态库内的内存分配

  • 动态库和主调程序分别编译的,使用2个不同的堆。
  • 堆各自管理各自的,谁负责分配,谁就负责释放(一个模块分配的内存要在同一个模块中释放!)
  • 将动态库中申请到的堆内存的指针交给主调程序去释放时,主调程序的堆管理部分就会发现这个指针不合法,就失败了。

C提高编程技巧

  1. 空间换时间

    • 使用宏函数而不是函数,宏函数占用了大量的空间,而函数占用了时间。函数调用时保存和恢复当前的现场,进行压栈和弹栈操作。宏函数仅仅作为预先写好的代码嵌入到当前程序,不会产生函数调用,所以仅仅是占用了空间
  2. 使用位操作:减少除法和取模的运算

  3. 使用嵌入式汇编:提高效率,限制可移植性

C模块划分

  1. 模块即是一个.c 文件和一个.h 文件的结合,头文件(.h)中是对于该模块接口的声明;
  2. 某模块提供给其它模块调用的外部函数及数据需在.h 中文件中冠以 extern 关键字声明;
  3. 模块内的函数和全局变量需在.c 文件开头冠以 static 关键字声明;
  4. 永远不要在.h 文件中定义变量!定义变量和声明变量的区别在于定义会产生内存分配的操作,是汇编阶段的概
    念;而声明则只是告诉包含该声明的模块在连接阶段从其它模块寻找外部函数和变量。

统计数值中1的个数

int nums( int date)
{
    int num = 0;
    for(int i=0 ; i<32 ; i++)
    {
        num += (date>>i)&0x01;
    }
    return num;
}
//更快速的方法是直接建立一个表,然后查表

对某一位置1或置0

//对一个char的第三位置0或置1
unsigned char c = 0x07;
c |= (0x01<<2); //置1
c &= ~(0x01<<2); //置0

对指定地址存储数据

int *p = (int *)0x12345678;
*p = 10;

c语言运算符优先级

优先级运算符类型运算符结合性
1后缀() [] -> . ++ –左到右
2一元++ – + - ! ~ (type)* & sizeof右到左
3乘法* / %左到右
4加法+ -左到右
5移位<< >>左到右
6关系< <= > >=左到右
7相等== !=左到右
8位与&左到右
9位异或^左到右
10位或|左到右
11逻辑与&&左到右
12逻辑或||左到右
13条件? :右到左
14赋值= += -= *= /= %= <<= >>= &= ^= |=右到左
15逗号,左到右

C语言面向对象实现多态

#include "stdio.h"
 
typedef struct Person{
    char *name;
    void (*eat)();
}Person;

void fun1(){
	printf("student eat!\r\n");
}
void fun2(){
	printf("teacher eat!\r\n");
}

int main()
{
    Person student={"student",fun1};
    Person teacher={"teacher",fun2};
    student.eat();
    teacher.eat();
}

C++代码优化?

  1. 循环外移。
  2. 减少函数调用。(inline)
  3. 右值引用。

1.2 内存

堆和栈的区别?

  • 分配和回收机制不同——堆由程序员手动开辟与回收,栈由系统自动分配和回收
  • 存放内容不同——堆存你想存的数据,栈存放函数的相关参数,返回值,局变量,寄存器内容等
  • 地址增长方式不同——堆向地址增大方向增长,栈反过来
  • 大小不同——堆可开辟,理论课开辟整个虚拟内存,栈有上限
  • 效率——堆开辟慢,栈系统开辟快

哈希冲突?

​ 主要是通过哈希函数产生的哈希值是有限的,当数据比较多的时候,不同的元素经过相同的哈希函数产生了相同的值,这就是哈希冲突。

解决办法:

  1. 线性探测法
  2. 链式地址法
  3. 再散列法(哈希冲突的时候,再用不同哈希函数产生不同的值)
  4. 公共溢出区:一旦哈希函数计算的结构相同就放入公共溢出区

1.3 基础

main函数的返回值

  • main函数的返回值是返回给主调进程,让主调进程得知被调用程序的运行结果。
  • 标准规范中main函数返回int类型,返回0无错误。
  • 检查不严格编译器返回类型也可以是void(如vs),检查严格必须是int(如g++)

main函数执行前后

  1. 执行前

    • 设置栈指针
    • 初始化 .date段内容(静态static变量和 赋值全局变量)
    • 初始化 .bss段内容(未初始化全局变量 赋0)
    • 全局对象初始化,调用全局对象的构造函数
    • 将参数argc、argv 传递给main函数,运行main函数。argc 类型为int型 ,argv类型为字符串数组
  2. 执行后

    • atexit() 函数,在main函数结束后调用
    • atexit() 函数注册的顺序和调用的顺序相反

“\n” 和 endl 的区别

  • “\n” 输出换行
  • endl 输出换行还会刷新缓冲区 , endl = “\n” + flush()
  • 没有必要刷新输出流的时候应尽量使用 “\n”

命名空间std

名称空间:将库函数封装起来的方法。可以避免和应用程序发生命名冲突的问题。

  • 使用 cin,cout 这两个 iostream 对象,要包含 头文件,还得让命名空间 std 内的名称曝光,即 using namespace std;
  • 开发过程中,避免使用直接引入整个命名空间,否则会因为命名空间污染导致很多不必要的问题(自己写的函数名称相同)。建议使用由命名空间组合起来的全称:std::cout

初始化和赋值

  • 初始化:创建变量时赋予其一个初始值
  • 赋值:把对象的当前值擦除,再用一个新值来替代。

局部变量和全局变量

  • 局部变量:也称为内部变量,它是在函数内定义的,作用域仅限于函数内
  • 全局变量:也称为外部变量,它是在函数外部定义的变量。其作用域是整个程序。在函数内部,局部变量可以屏蔽全局变量。
  • 如果一个全局变量用 static 修饰,它就是静态全局变量,它的作用域是该文件范围(称为文件作用域,即其它文件不能使用它)

操作系统和编译器是怎么知道变量是全局还是局部?

  • 操作系统和编译器,可能是通过内存分配的位置来知道的
  • 全局变量分配在全局数据段
  • 局部变量则分配在栈里面

变量的静态存储和动态存储

变量的生存周期只与变量的存储位置(存储类别)有关

  • 静态存储(在程序运行期间,系统对变量分配固定的存储空间)
  • 动态存储(在程序运行期间,系统对变量动态(不固定)的分配存储空间)
  • auto 自动变量(动态存储方式)
    static 静态变量(静态存储方式)
    register 寄存器变量(动态存储方式)
    extern 外部变量(静态存储方式)

函数返回引用

  • 可以节省构造函数创建临时副本
  • 可以节省析构函数删除临时副本的时间
  • 但是不能返回临时对象的引用

this指针

  • 一个类的成员函数只有一份,为了分开不同对象的数据,执行类成员函数时,会把当前的this指针(对象的首地址)传入成员函数。函数体内的数据成员都会转化为this->数据成员的方式。
  • 非静态成员函数(包括构造函数和析构函数)有自己的this指针,指向当前调用的对象。
  • 静态成员函数和友元函数没有this指针

为什么静态成员函数不用this指针?

  • 静态成员函数属于整个类,所有对象共有,独立于对象之外的。
  • this指针是类的实例指针,操作对象实例内容的,所以静态不用this指针
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2261228.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IntelliJ IDEA(2024版) 的安装、配置与使用教程:常用配置、创建工程等操作(很详细,你想要的都在这里)

IDEA的安装、配置与使用&#xff1a; Ⅰ、IDEA 的安装&#xff1a;1、IDEA 的下载地址(官网)&#xff1a;2、IDEA 分为两个版本&#xff1a;旗舰版 (Ultimate) 和 社区版 (Community)其一、两个不同版本的安装文件&#xff1a;其二、两个不同版本的详细对比&#xff1a; 3、IDE…

MybatisPlus-配置加密

配置加密 目前配置文件中的很多参数都是明文&#xff0c;如果开发人员发生流动&#xff0c;很容易导致敏感信息的泄露。所以MybatisPlus支持配置文件的加密和解密功能。 我们以数据库的用户名和密码为例。 生成秘钥 首先&#xff0c;我们利用AES工具生成一个随机秘钥&#…

深度学习基础--将yolov5的backbone模块用于目标识别会出现怎么效果呢??

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 yolov5网络结构比较复杂&#xff0c;上次我们简要介绍了yolov5网络模块&#xff0c;并且复现了C3模块&#xff0c;深度学习基础–yolov5网络结构简介&a…

数据结构---图(Graph)

图&#xff08;Graph&#xff09;是一种非常灵活且强大的数据结构&#xff0c;用于表示实体之间的复杂关系。在图结构中&#xff0c;数据由一组节点&#xff08;或称为顶点&#xff09;和连接这些节点的边组成。图可以用于表示社交网络、交通网络、网络路由等场景。 1. 基本概…

人工智能技术的深度解析与推广【人工智能的应用场景】

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c; 忍不住分享一下给大家。点击跳转到网站 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把…

软件开发中 Bug 为什么不能彻底消除

在软件开发中&#xff0c;Bug无法彻底消除的原因主要包括&#xff1a;软件复杂度高、人员认知与沟通受限、需求和环境不断变化、工具与测试覆盖不足、经济与时间成本制约。其中“需求和环境不断变化”尤为关键&#xff0c;因为在实际开发中&#xff0c;业务逻辑随着市场与用户反…

【嵌入式软件】跑开发板的前置服务配置

在嵌入式开发中,通常需要在 开发板和主机之间共享、传输和挂载文件。 这篇文章是关于如何在 Ubuntu 中配置 Samba、TFTP 和 NFS 协议的详细步骤。这些协议分别用于远程文件共享、文件传输和内核挂载文件系统。 如何安装协议: 参考:ubuntu18配置:详细的内容我手写了一份文档。…

CTF 攻防世界 Web: FlatScience write-up

题目名称-FlatScience 网址 index 目录中没有发现提示信息&#xff0c;链接会跳转到论文。 目前没有发现有用信息&#xff0c;尝试目录扫描。 目录扫描 注意到存在 robots.txt 和 login.php。 访问 robots.txt 这里表明还存在 admin.php admin.php 分析 在这里尝试一些 sql…

从YOLOv5到训练实战:易用性和扩展性的加强

文章目录 前言一、模型介绍二、YOLOv5网络结构1.Input&#xff08;输入端&#xff09;&#xff1a;智能预处理与优化策略2.Backbone&#xff08;骨干网络&#xff09;&#xff1a;高效特征提取3.NECK&#xff08;颈部&#xff09;&#xff1a;特征增强与多尺度融合4.Prediction…

Ilya Sutskever发表了对AI未来发展的颠覆性看法

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Crawl4AI:一个为大型语言模型(LLM)和AI应用设计的网页爬虫和数据提取工具实战

这里写目录标题 一、crawl4AI功能及简介1、简介2、特性 二、项目地址三、环境安装四、大模型申请五、代码示例1.生成markdown2.结构化数据 一、crawl4AI功能及简介 1、简介 Crawl4AI 是一个开源的网页爬虫和数据抓取工具&#xff0c;一个python项目&#xff0c;主要为大型语言…

HuLa——一款基于 Tauri+Vue3 构建的桌面即时通讯应用

文章目录 一、HuLa简介二、技术栈介绍三、安装运行四、界面体验五、开源地址 一、HuLa简介 HuLa 是一个基于 Tauri、Vite 5、Vue 3 和 TypeScript 构建的即时通讯系统。它利用了 Tauri 的跨平台能力和 Vue 3 的响应式设计&#xff0c;结合了 TypeScript 的类型安全特性和 Vite…

websocket_asyncio

WebSocket 和 asyncio 指南 简介 本指南涵盖了使用 Python 中的 websockets 库进行 WebSocket 编程的基础知识&#xff0c;以及 asyncio 在异步非阻塞 I/O 中的作用。它提供了构建高效 WebSocket 服务端和客户端的知识&#xff0c;以及 asyncio 的特性和优势。 1. 什么是 WebS…

《Java核心技术I》Swing用户界面组件

Swing和模型-视图-控制器设计模式 用户界面组件各个组成部分&#xff0c;如按钮&#xff0c;复选框&#xff0c;文本框或复杂的树控件&#xff0c;每个组件都有三个特征&#xff1a; 内容&#xff0c;如按钮的状态&#xff0c;文本域中的文本。外观&#xff0c;颜色&#xff0c…

如何通过递延型指标预测项目的长期成果?

递延型指标&#xff08;Deferred Metrics&#xff09;是指那些并不立即反映或直接影响当前操作、决策或行为的指标&#xff0c;而是随着时间的推移&#xff0c;才逐渐显现出影响效果的指标。这类指标通常会在一段时间后反映出来&#xff0c;或者需要一定的周期才能展现其成果或…

uni-app开发AI康复锻炼小程序,帮助肢体受伤患者康复!

**提要&#xff1a;**近段时间我们收到多个康复机构用户&#xff0c;咨询AI运动识别插件是否可以应用于肢力运动受限患者的康复锻炼中来&#xff0c;插件是可以应用到AI康复锻炼中的&#xff0c;今天小编就为您介绍一下AI运动识别插件在康腹锻炼中的应用场景。 一、康复机构的应…

C++(十八)

前言&#xff1a; 本文依据上一篇&#xff0c;继续对C中的函数进行学习。 一&#xff0c;内联函数。 再执行函数代码时&#xff0c;比不使用函数花费了更多时间&#xff0c;因为总结步骤&#xff0c;传递参数和返回值都很花费时间。 因此&#xff0c;在调试小型函数时&…

如何在 Ubuntu 上安装 NodeBB 并使用 Nginx 反向代理

简介 NodeBB 是一款基于 Node.js 的开源论坛软件&#xff0c;为在线社区提供了现代化和响应式的解决方案。在 Ubuntu Linux 上运行的 NodeBB 利用了操作系统的强大性和灵活性&#xff0c;以提供高性能和可扩展性。它结合了 MongoDB 或 Redis 进行数据库管理&#xff0c;使其能…

【UE5 C++课程系列笔记】09——多播委托的基本使用

目录 多播委托——申明委托 一、DECLARE_MULTICAST_DELEGATE 二、DECLARE_DYNAMIC_MULTICAST_DELEGATE 多播委托——绑定委托 一、Add 二、AddStatic 三、AddRaw 四、AddSP 五、AddUObject 六、Remove 七、RemoveAll 多播委托——执行 上一篇&#xff1a;【UE5 C课程…

车牌识别OCR授权:助力国产化升级,全面提升道路监控效率

政策背景&#xff1a;国产化升级&#xff0c;推动道路监控产业转型 随着国家对信息安全的重视&#xff0c;国内各大公安、政企机构已进入全面升级国产化平台的实施阶段。根据最新的政策要求&#xff0c;公安和政府部门必须在未来三年内完成平台的国产化替换工作。这一举措不仅…