c语言基础部分终于结束了。可以上数据结构了。但是目前感觉对指针这一块儿还需要加深理解!!!(指的我头皮发麻)- 有关于指针参数传递非常重要的一点:- 如果int n = 5. n的类型是int,&n的类型是*int,那么*(&n)的类型是等价于n的类型,也就是int- 动态内存分配。1. 为什么需要动态内存分配?2. 栈空间的局限性:1栈帧的大小,需要在编译时确定。栈空间不能存放动态大小的数据 、2栈空间大小是受限的:在典型的linux系统中主线程8MB,其他线程2MB。如果存放太多数据会栈溢出,程序崩溃。因此栈空间不能存放太大的数据。3每个线程都有自己的栈空间,栈空间不适合存放多线程共享的数据。3. 他作用于:堆(heap)[图片]4. sp寄存器;bp寄存器(Stack pointer; base pointer)它的作用[图片]5. 如何进行动态内存分配?malloc(内存分配) , calloc(清0分配), relloc(调整之前分配出来的内存大小) 他们返回的类型都是void*(通用指针类型:我不知道他的基类型int or double?)6. 通过在main函数里面定义指针指向(无名字)的预先分配的内存空间里面。但是由于无名字特性。我们该怎么操作呢:通过栈上的指针变量访问堆上的数据。- 动态数组(当数组空间不够的时候,他可以自动扩容)1. 我们通过写Vector.h的头文件以及他的实现来创建动态数组。(我感觉类似于java里面的getter setter?)[图片]2. vector.h ; main.c ; vector.c 的三方关系:[图片]3. 利用realloc函数进行扩容 realloc(void* ptr, size_t size): void* ptr-> 指向旧的内存块儿 size_t size:新内存的大小。- 如果返回值为NULL:重新分配的内存失败,旧的内存块不会被释放。- 不为NULL:重新分配成功。- realloc既可以扩容,也可以缩容。- 缩容:把多余的释放掉。- 扩容:第一步尽量原地扩容。第二步:如果不能原地扩容,那么就复制到大的内存空间的位置,然后吧旧空间释放掉。- 释放内存:(free)1. 注意事项:2. 严禁 double free3. free之后对野指针进行解引用会产生未定义行为。- 内存泄漏:程序中存在垃圾的现象。(这就会导致OOM现象。out of memory)[图片]- 动态分配的结构体:(链表)[图片]- 如果定义的链表类型是void的话就会发生head下一个节点是空值的现象。(怎么解决?二级指针**phead)- 二级指针:Node** pp -> Node*p -> Node node !!![图片]- 问题:传递参数的时候到底传一级指针还是二级指针。- 解决:想修改哪个变量的值,就穿哪个变量的地址!!!- 如果是想修改指针变量的指向(值),传二级指针- 如果是想修改指针变量指向的对象,传一级指针- 函数指针:- 他是什么?指向一个函数的首入口(首字节),那么这个指针就是函数指针。- 函数指针你只要知道他的入口他就会一直往下执行。1. 怎么操作?他只支持两个操作:解引用,函数调用。2. 编程范式:面向过程,面向对象,函数式编程(一等公民)<包含复制,作为参数,作为返回值>,逻辑式编程。3. 在c语言中,函数不是一等公民,函数指针是一等公民4. 在c语言中,可以通过函函数指针,进行函数式编程(有利于解耦合,易组合)。[图片]- qshort()函数就是典型利用了函数指针。它的功能:可以对任意一个数组排序。- 解耦合的形象图例:compare是钩子函数[图片]