半个月的学习总结(面试知识点)

一、什么是嵌入式?

在已有硬件的基础上移植操作系统解决软硬件耦合度过高的导致的问题。

 

二、单片机开发(裸机开发)与嵌入式开发的区别?

是否移植操作系统

 

三、嵌入式软件与非嵌入软件的区别?

传统开发缺点:软硬件耦合度高,导致软件移植性较差;软件开发人员必须要懂硬件;软件的功能较差

传统开发优点:方便简单

嵌入式开发缺点:成本较高

嵌入式开发优点:解决了传统开发的耦合度高导致的问题;多任务机制;提供了丰富的网络协议;提供了丰富的开源软件和工具。

 

四、应用软件开发VS系统软件开发

应用软件:

精通一门语言;

熟悉一款操作系统;

数据结构和算法。

系统软件开发:

精通C语言;

熟悉汇编;

理解操作系统的实现;

熟悉硬件工作原理。

 

五、Linux文件

普通文件(-)、目录文件(d)、链接文件(l)、设备文件(c/b)、共享文件(s/套接字)、管道文件(p)、堆栈文件(f)

 

六、Linux一点哲学:一切皆为文件

 

七、#include "stdio.h" VS#include <stdio.h>

文件搜索路径不同

#include "stdio.h":先在当前目录查找,再到系统目录查找

#include <stdio.h>:系统头文件目录。

 

八、汇编特点

能够访问硬件

每个CPU有自己的汇编语言

 

九、预处理的步骤

将头文件展开

宏替换

条件编译

 

十、C语言源文件到可执行文件经历的过程

预处理(-E)———编译(c)————汇编(-s)————链接

 

十一、-o1、-o2、-o3编译器优化选项

-O1:这是最基本的优化等级。编译器会在不花费太多编译时间的同时试图生成更快更小的代码。这些优化是非常基础的,但一般这些任务肯定能顺利完成。
-O2:-O1的进阶。这是推荐的优化等级,除非你有特殊的需求。-O2会比-O1启用多一些标记。设置了-O2后,编译器会试图提高代码性能而不会增大体积和大量占用的编译时间。
-O3:这是最高最危险的优化等级。用这个选项会延长编译代码的时间,并且在使用gcc4.x的系统里不应全局启用。自从3.x版本以来gcc的行为已经有了极大地改变。在3.x,-O3生成的代码也只是比-O2快一点点而已,而gcc4.x中还未必更快。用-O3来编译所有的软件包将产生更大体积更耗内存的二进制文件,大大增加编译失败的机会或不可预知的程序行为(包括错误)。这样做将得不偿失,记住过犹不及。在gcc 4.x.中使用-O3是不推荐的。


十二、makefile三种形式

makfile有三种形式:每个函数下有个makefile
:脚本文件下需要一个makefile
:根目录下的makefil


十三、Makefile结构

TARGET:prerequisites 
TAB command

 

十四、使用动态库与静态库的区别

1.使用静态库编译的程序易于升级,动态库难于升级

2.使用动态库生成的可执行文件大,占用内存大

  使用静态库生产可执行文件小,占用内存小

3.使用动态库编译块,时间段,程序运行时间慢

4.动态库难以部署。

 

十五、C语言的数据类型

 

十六、static关键字

1.修饰局部变量时(在函数体内):一个被声明为静态的变量在函数过程中值保持不变,使得声明周期延长至程序结束,此时的变量存放区域为数据段上。(从而可以少使用全局变量)
2.修饰全局变量:使得全局变量的作用域在本文件中,不能被其他文件使用
3.修饰函数:使得函数的作用域只在本文件中。(由于在大型项目中,可能有相同的函数名,在函数加上static可以防止函数重名带来不必要的麻烦。如linux内核的函数都是static修饰的)

 

十七、const关键字

const:修饰一个变量让其成为只读变量。但是不会使其地址成为只读数据。
const使用判断用就近原则。
其好处:在函数传参时,修饰函数形参,防止实参在函数调用时被意外修改。

 

十八、typedef关键字
typedef:给类型重命名,其中特例就是给函数指针重命名
typedef int (*p_func)(int, int)
使用它可以增加代码的可移植性,可读性,开发效率提高,以及增加代码的安全性;
1.移植性:在某些机器上,对于缺省定义符号的某种类型,有些机器上默认为有符号,有些机器默认无符号数,当我们代码移植到另外不同机器运行时候,如果使用typedef 给数据类型重命名,只需要直接修改重命名的类型为有/无符号即可。
2可读性:我们可以把一些我们长度,姓名之类的重器名字这样增加了代码的可读性,让别人知道使用变量时候更加明白开发人员的意图,如strlen函数原型返回值就是一个size_t的类型,告诉别人返回的是一个长度类型
3开发效率:对结构体重起名
4代码安全性:代码泄露时候,别人不得而知你的类型是什么,从而增加了安全性。


 十九、extern关键字
extern:做外部声明。
用extern修饰的都是声明语句。使用声明是一种良好的编码规范。可以优化编译速度
1.声明全局变量
2.声明函数


二十、register关键字

修饰变量,将一个变量尽可能的保存在寄存器里,减少CPU从内存中抓取数据的时间,从而提高代码运行效率。
注意事项:
1.用rigister修饰的变量不可使用取地址符号。(&取的是内存中的地址)
2.不可修饰全局变量,函数。只能修饰局部变量
3.修饰cpu可接受的类型(有些cpu不接受浮点型运算)

 

二十一、volatile关键字

防止编译器做默认优化
一个定义为volatile的变量是说这个变量可能会意想不到的被改变,这样,编译就不会假设个变量的值。(编译器优化:一个值多次操作都不改变,编译会进行优化,让其放入cou寄存器中)
用例:
1.并行设备的硬件寄存器(如状态寄存器)
2.一个终端服务子程序中会访问到的非自动变量
3.多线程应用被几个任务共享的变量。

 

二十二、一维数组

一维数组名:指针常量,保存数组首元素地址

&a:一维数组的地址

*(&a)=a;

对一维数组的地址取值等于数组首元素的地址;

对一维数组名取地址等于一位数组的地址;

 

二十三、二维数组

二维数组名:指针常量,保持首个一维数组的地址

*(&aa)==aa;

对二维数组的地址取值等于二维数组的首个一维数组的地址

*aa=&aa[0][0];

 

*(*(aa+i)+j);

aa+i:二维数组的第i+1个一维数组的地址;

*(aa+i):二维数组的第i+1个一维数组的首元素地址;

*(aa+i)+j:二维数组的第i+1个一维数组的地址的第j+1个元素的地址;

*(*(aa+i)+j):二维数组的第i+1个一维数组的首元素地址的第j+1个元素的地址。
 

二十四、三维数组

三维数组名:指针常量,保存首个二维数组的首个一维数组的地址。

*(&aaa)==aaa;

对三维数组的地址取值等于首个二维数组的首个一维数组的地址

 

二十五、指针数组作用

1.处理不规则多维数组

 2.节省空间

 

二十六、什么是野指针

未初始化的指针,它随机指向一块内存(linux下未初始化的变量,系统随机分配),从而造成内存泄露,非法访问一块内存或者已经释放的内存。

 

二十七、如何避免野指针

首先要养成如下的编码习惯:
1.当定义一个指针时, 不确定它指向那,应该置为NULL;

int *p = NULL;
2.往指针指向的空间进行赋值,要给指针分配空间(malloc函数);

ptr = (char*) malloc (sizeof(char*) * 100);
3.判断分配好的空间是否分配成功

if(NULL == p)
4.初始化分配好的空间

memset(ptr,0,sizeof(char) * 100);
5.使用分配好的空间时不要出现越界
6.使用完应该使用释放函数释放分配好的空间
7.释放完再次置空指针。

free(ptr);

其中free函数释放空间不能超过分配的空间,否则出现堆溢出

 

二十八、malloc、realloc、calloc的区别

realloc函数 追加分配空间,会对分配的空间初始化
malloc函数分配一块空间,但是不会对空间进行初始化
calloc函数不做初始化,分配几块连续的空间

 

二十九、万能指针

万能指针void *p可以保存任何类型的指针地址。对于void *类型的指针不可作取值运算,它所占的步长为1;占位字节;其中malloc分配的地址返回值也为void *类型

 

三十、C语言实现面向对象

使用结构体加函数指针

 

三十一、函数名

是一个指针常量,保存函数的入口地址,步长为1

 

三十二、指针数组的作用

1.实现不规则多维数组

2.节省空间(传递多行数据的时候,不需要拷贝大量数据,只需要用指针,节省空间)。
 

 

 


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值