该博客属于随堂笔记,省略了基础知识,不足的地方请指正。
1. 数组的3种形式
数组在程序执行完成后自动释放内存。
malloc动态申请的内存需要手动释放。
int a[2] = {1,2}; // 静态数组在栈区,自动释放
int *p = malloc(sizeof(int)*100); //动态数组在堆区,手动释放,否则一直占用
int *pc99= (int []){[3]=10}; // 静态数组在栈区,vc99新语法,(int [])代表数组,不可缺省
pc99 = (int [30]){0};// 这是可以编译的,pc99作为变量,可以指向另外的内存
a = 1; //错误的做法,是常量。不能赋值也不能指向另外的内存。
静态数组编译时必须确定大小。free(vc99),将在dbgheap.c出现程序异常。数组没有副本机制,传递数组名将退化为一个指针。
栈上的动态分配:在GCC编译器下,可以使用
int num=30;
int a[num];//GCC编译器下,可编程数组。
int *pc99= (int [num]){[3]=10}; //错误
在栈上动态分配,很容易栈溢出。
2. 数组与指针的区别
//1-D 数组,动态
// 列必须是确定的,行可以动态分配
int (*p)[5]=malloc(sizeof(int)*30)
for(int i=0;i<30;i++ ){
printf("%4d\n",p[i]=i)
}
//2-D 数组,动态
int (*p)[5]=malloc(sizeof(int)*30);
for(int i=0,num=0;i<30;i++,num++ ){
printf("%4d",p[i/5][i%5]=num);
if((i+1)%5==0)
printf("\n");
}
指针数组的数组名是二级指针:
二级指针是指针的指针,形式int **p。
int **p,int *p1;
p = p1;
对于多级指针,需要动态申请内存, malloc(sizeof(int)*length)
数组:查找方便,删除、插入太麻烦—数据位置需要移动,即改变数据所在位置的下标。
链表:查询慢,找到n,必须依赖于n-1,删除容易–修改n-1位置的内存地址
插入容易–malloc插入地址,修改插入位置之前地址,链接插入位置地址
3. 分块数组
采用综合性能最高的方法——分块数组(多级指针)
内存消耗大,查找性能跟数组一样,但删除、插入快很多,可以等长也可以不等长。
int ********pppppppp = malloc(sizeof(int *******)*length);
//8级指针动态内存申请,其他N级指针类似
QQ账号: 采用十级指针,每一个节点有10个分支,相当于一个树的root节点有10棵子树。
N 级指针可以存储N-1级指针的地址与指针。数据可以看做0级指针。多级指针也可以看做一个树形结构
指针中括号优先级问题:
中括号的优先级大于*运算符
* (a+1)[1] = a[1][1]
* ((a+1)[1]) = *(a+1 +1) = *a[2]