2017-11-24 嵌入式笔记
struct结构体
1、第一个数据成员放在offset为0的地方,之后每个成员从该成员大小的 整数倍 开始;
2、结构体作为成员时,从其内 最大元素大小的整数倍地址开始存储;
3、sizeof:在对齐基础上,必须还是其内部最大成员的整数倍,不足的要补齐。
堆、栈区别
栈:由编译器在需要的时候分配,不需要时自动清除变量的存储区,变量通常是局部变量、函数参数等;
堆:由new分配的内存块,由应用程序控制释放,一般一个new就要对应一个delete,
1、管理方式
(a)栈:由编译器自动管理,无需手工管理;
(b)堆:由程序员控制,容易产生memory leak,内存泄漏;
2、空间大小
(a)栈:有限制
(b)堆:几乎没限制
3、碎片问题
(a)栈:先进后出,不产生碎片
(b)堆:频繁的new/delete造成空间不连续,产生大量碎片,使程序效率降低;
4、生长方式
(a)栈:向下,向内存地址减小的方向增长;
(b)堆:向上,向内存地址增大的方向增长;
5、分配方式
(a)栈:有静态和动态两种方式,静态分配是编译器完成,比如局部变量的分配;动态分配有alloca函数进行分配;
(b)堆:都是动态分配;
const用途
1、定义const常量,具有不可变性,在定义该const变量时,通常需要进行初始化,因为后面再没机会改变它了;
2、const可以修饰函数的参数、返回值,及函数的定义体。强制保护,防止意外变动,提高程序健壮性;
3、对指针来说,可以指定指针本身为const--int * const p,也可以指定指针所指向数据为const-- const int *p ,
实现strcpy函数
char *strcpy(char *strDest, char *strSrc) //strDest目的字符串,strSrc源字符串
{
assert((strDest!=NULL) && (strSrc!=NULL));
char *addr = strDest;
while((*strDest++ = *strSrc++) !='\0') ;
return addr;
}
函数与宏
函数 | 宏 |
---|---|
函数调用时,先求出实参表达式,然后代入形参 | 含含的宏只进行简单的字符替换 |
函数调用在程序运行时处理,分配临时内存单元 | 宏展开是在编译时进行,展开时不分配内存单元,不进行值传递处理,也没有返回值 |
函数:实参、形参类型一致,若不一致,应进行类型转换 | 宏不存在类型问题,只是一个符号代表 |
函数只可返回一个返回值 | 宏可以设法得到几个结果 |
函数调用占用运行时间(分配单元,保存现场,值传递返回等) | 宏替换不占用运行时间 |
const 指针
int b;
1、const int *a= &b; //*a是const,但指针a可变,指向的内容不可以变
2、const *int a= &b; //a是cosnt,指向的地址可以改变,但*a可变
3、const int *const a= &b; //*a和a都是const,常量和指针的值都不能改变
4、int const *const a= &b; //等同于3
// =>
C++中包含extern C
- 在C++程序中调用被C编译器编译后的函数,为什么要加“extern C”声明???
- ——函数和变量被C++编译后在符号库中的名字与C语言不同,被extern C修饰的变量和函数是按照C语言方式编译和链接的。由于编译后的名字不同,C++程序不能直接调用C函数。C++提供了一个C连接交换指定符号extern C解决这个问题。
TCP/IP三次握手
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。
- 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
- 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个ACK包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
- 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
static关键字作用
- 函数体内的static变量作用范围为该函数体,该变量的内存只被分配一次,该值在下次调用时仍保留上一次的值;
- 在模块内的static全局变量可以被模块内的所有函数访问,但不能被模块外的其他函数访问;
- 模块内的static函数只可被这一模块内的其他函数调用,这个函数的使用范围被限制在声明它的模块内;
- 类中的static成员变量属于整个类拥有,对类的所有对象只有一份拷贝;
- 类中的static成员函数属于整个类拥有,这个函数不接受this指针,因而只能访问类的static成员变量。
little_endian / big_endian
- little_endian:CPU对操作数的存放字节方式是从低到高,低位数据存放低地址,高位数据存放高地址;eg.数据0x1234,0x34->0x4000;0x12->0x4001;
- big_endian:CPU对操作数的存放字节方式是从高到低,低位数据存放高地址,高位数据存放低地址;eg.数据0x1234,0x34->0x4001;0x12->0x4000;
- 联合体union的存放顺序是所有成员都从低地址开始存放,利用这一特性,判断大小端
/* 判断处理器大小端,大端返回0,小端返回1 */
int checkCPU()
{
union w{
int a;
char b;
}c;
c.a=1;
return (c.b==1);
}