数据结构复习总结

来源:互联网 发布:e网是什么网络 编辑:程序博客网 时间:2024/06/08 19:03

首先还是复习,二维数组和指针:

Int  a[2][3];  int (*p)[3] = a;

这里输出p和*p是一样的,p ==a整个数组的首地址,*p == a[0]是这个一维数组的首地址,p++就是移动int[3]个字节,(*p)++移动了4字节,但是这样是错的,相当于a[0]++。

    注:如果希望通过形参修改实参的值,传递的必须是指针,函数内部一定使用的是指针指向的内存,而不是直接使用指针。如果是希望改变指针指向的值,那么形参得是二维指针。二维数组作为参数的时候,被解析为指向数组的指针。

内存管理:

auto(自动变量,C语言默认,处于栈中)

   register(寄存器变量不能取地址)

    静态变量(程序执行期间一直存在,而且内存地址不会改变,不能在代码块外面访问它;只初始化一次,第二次的时候不会再赋值;和全局变量相比,static只能在定义变量的文件内部使用,文件外部不可以使用,但是可以通过函数来间接访问static变量)能用局部变量解决的,就不要使用全局变量。

   extern(外部变量,extern int i引用一个外部变量,和int i一样)

内存四区:是独立的区域

代码区:变量的定义不是代码,代码区不可读写,只能执行;常量字符串;假如给main函数的地址赋个其他值,会出现错误,是CPU读写的。编译完之后是固定不变的。

静态区:全部静态变量和全局变量都在这儿存放

栈区:  所有的局部自动变量,先进后出,当一个变量超出作用域的时候,自动弹出,系统自动管理,但是空间比较小;char a[n],C语言是不允许在栈里面定义动态大小的数组,在编译时必须确定栈的大小。递归层数不能过多,否则会出现栈溢出。函数参数从右到左入栈。栈顶从高地址向低地址增长

堆区: 远远大于栈,但是内存需要自己处理。

int *p = malloc(4*sizeof(int));//单位是字节,32位系统默认是3G,要及时释放内存,清空memset(p,0,10*sizeof(int))。可以根据用户的输入来决定堆里面动态数组的大小。

Calloc(10,sizeof(int))//分配10个int,同时初始化为0.

Realloc(src,10) //重新分配10个空间,原来的内容还在

如果堆没有可分配的内存,malloc返回null,在有些linux嵌入式系统下,继续调用realloc分配内存,操作系统重新启动

注:在一个函数里面,如果函数的返回值是一个指针,就不能返回局部变量,就是不可以使用栈分配的地址,因为函数结束的时候,指针就收回了,这样得到的是一个失效地址。通过函数的参数为指针分配内存,得使用二级指针。

注:对于字符串常量和静态变量,是在静态区存放的,所以返回的地址是有效的,在程序运行期间是一直有效的。

在linux下,查看栈和堆的内存使用,在proc下面可以看到进程的PID号,然后进去之后,可以看到好多信息,栈的大小事88KB,

每个线程都有自己专属的栈。

内存的最小单位是字节,在malloc的时候,不是按你自己的意愿来分配的,这个时候操作系统是根据内存页的方式来管理内存,分配内存的时候,除非一个页的单位已满,就会开辟一个新的页。

硬盘的存储也是字节为最小单位,但是有很多个扇区,每个扇区包含很多字节。数组在内存中的存放是下标从小到达,内存也是从小到大存放,不管在堆、栈和全局变量中都是这样。和栈的变量不同,先声明的地址大,符合栈的概念。

将dest的值追加到src后面,这时候最容易造成数组的溢出,所以这时候适合使用动态数组,在函数中申请一个新的内存。使用堆动态的来分配内存。

   void mystrcat(char **src,char *dest)

   {

     Int src_len = strlen(*src);

     Int dest_len = strlen(dest);

Char *p = malloc(src_len + dest_len +1); //效率不高

Memset(p,0,src_len + dest_len +1);

Strcpy(p,*src);

/*

Char *p = realloc(*src,src_len + dest_len +1);

*/

Int i;

For(i=0;i<dest_len;i++)

   *src[src_len + i] = dest[i]

Free(*src);

*src = p;

   }

0 0
原创粉丝点击