1.结构体占用内存
(1)内存对齐问题(变量字节最长的大小用来对齐)
a.原则一:数据成员对齐规则:结构的数据成员,第一个数据成员放在offset()为0的地方,
以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储)
b.原则二:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a 里有struct b里有char int double 等元素那b应该从8的整数倍开始存储)
c.原则3,收尾工作,结构体的总大小,也就是sizeof的结果,必须是内部最大成员的整数倍,不足的要不起
(2)指针类型都占4个字节
2.内存分配的三种方式
(1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。
3.数组和vector
(1)数组初始化固定大小;vector动态扩容
(2)vector:新数组的容量总是取原数组的两倍
4.数组和链表
(1)数组:连续存储(随机访问,占用资源少);插入删除O(N)
(2)链表:不连续存储(不可随机访问,占用资源多);插入删除O(1)
5.static
(1)用static定义的全局和局部静态变量的都是在全局区分配内存;区别是,全局的静态变量的作用域和可见域都是从文件的定义开始到整个文件结束;而局部的静态变量可见域是从文件的定义开始到整个文件结束,作用域是从该语句块的定义开始到该语句块结束
(2)定义静态函数:在函数返回类型前加上static关键字,函数即被定义为静态函数,其特点如下:
a.静态函数只能在本源文件中使用
b.在文件作用域中声明的inline函数默认为static类型
6.const char*(char const*=const char*):指针指向内容不可以修改;指针可以修改
char* const:指针不可以修改;指针指向内容可以修改
7.volatile
读取volatile类型的变量时总会返回最新写入的值;轻量级的同步机制
8.大端和小端的含义及判断代码
大端和小端的含义及判断代码_YoungYangD的博客-CSDN博客_判断大端小端代码
9.实现string memcpy
int memcpy_mk(char *dst, char *src, int n)
{
if (src == NULL || dst == NULL)
return -1;
for (int i = 0; i < n; i++)
{
*dst = *src;
src++;
dst++;
}
return 0;
}
int memcpy_string(char *dst, char *src)
{
if (src == NULL || dst == NULL)
return -1;
int n_src = strlen(src)+1;
// int n_dst = strlen(dst)+1; // 目标内存没有结束符\0
memcpy_mk(dst, src, n_src);
return 0;
}
10.n--和--n
n--,先取n的值进行运算,运算结束后再n自减;
--n:先n自n自减,再取n的值进行运算;