当前位置: 首页> 游戏> 单机 > 成都私人做网站建设的公司_郑州企业建设网站技术_免费注册二级域名的网站_互联网推广运营是干什么的

成都私人做网站建设的公司_郑州企业建设网站技术_免费注册二级域名的网站_互联网推广运营是干什么的

时间:2025/7/12 20:41:58来源:https://blog.csdn.net/qq_44814825/article/details/144485798 浏览次数:0次
成都私人做网站建设的公司_郑州企业建设网站技术_免费注册二级域名的网站_互联网推广运营是干什么的

《拉依达的嵌入式\驱动面试宝典》—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指针
    在这里插入图片描述
关键字:成都私人做网站建设的公司_郑州企业建设网站技术_免费注册二级域名的网站_互联网推广运营是干什么的

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: