- 第11次直播 指针数组与malloc
- 易错三大例子
- 指针与一维数组
- 指针与动态内存申请
- 栈空间与堆空间的差异
- 第12次直播 函数与指针
- 字符指针与字符数组的初始化(了解)
- 第12次直播 二级指针 结构体
- 关于全局变量与局部变量
- 结构体
- 结构体指针(重要)
例子一:
上述正确的输出为: 2 2 7
例子二:
上述正确的输出为: 3 2 3
例子三:
上述正确的输出为:2 7 8
例子一:
输出结果为: Hello
- 数组名作为实参传递给子函数时,是弱化为指针的
例子二:
-
很多读者在学习C语言的数组后都会觉得数组长度固定很不方便,其实C语言的数组长度固定是因为其定义的整型、浮点型、字符型变量、数组变量都在栈空间中,而栈空间的大小在编译时是确定的。如果使用的空间大小不确定,那么就要使用堆空间。
-
既然都是内存空间,为什么还要分栈空间和堆空间呢?栈是计算机系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈操作、出栈操作都有专门的旨令执行,这就决定了栈的效率比较高;堆则是CC艹函数库提供的数据结构,它的机制很复杂,例如为了分配一块内存,库函数会按照一定的算法(具体的算法请参考关于数据结构、操作系统的书籍)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能由于内存碎片太多),那么就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后返回。显然,堆的效率要比栈低得多栈空间由系统自动管理,而堆空间的申请和释放需要自行管理,所以在具体例子中需要通过free函数释放堆空间。free函数的头文件及格式为
进程地址空间如下
- 首先进行解析 malloc 在 # include< stdlib. h> 头文件中, 函数的定义为void* malloc(size_ t size) void * 表示定义的为无类型指针,因为是无类型所以才使用强制类型转换,在前面加上 (char *) , malloc 申请空间的单位是字节
易错点: 指针在释放的时候发生偏移
- 释放空间,p的值必须和最初 malloc 返回的值一致,如果发生偏移则会有下下图的报错
报错如下:
free(p) ; p=NULL ; 释放操作
问题引入:
#includechar* print_stack() { char c[17] = "i am ok"; puts(c); return c; } int main() { char* p; p = print_stack(); puts(p); return 0; }
- 原因在在于函数是栈空间,栈空间会随着函数结束而释放。
- 不能使指针变量指向栈空间,进行操作,因为栈空间会在之后进行释放
解决方法
- 堆空间不会随子函数的结束而释放,必须自己free
- 字符指针可以初始化赋值一个字符串,字符数组初始化也可以赋值一个字符串。 char *p="hello"和 char c[10]="hello"有什么区别呢?
易错分析一:
错误分析:
- 对 p[0] 进行修改,会报如下错误,然而 c[0] 对数组进行修改可以,因为char c [10] = "hello"实际等价于 strcpy(c,"hello") ; 操作的是堆区(可读可写),p[0] 实际操作的是字符串常量区(数据区),该区域只读不能写
原因在于:不能对常量区数据进行修改
易错分析二:
第12次直播 二级指针 结构体-
二级指针只服务于一级指针的传递与偏移
-
要想在子函数中改变一个变量的值,必须把该变量的地址传进去
-
要想在子函数中改变一个指针变量的值,必须把该指针变量的地址传进去
#include#include void change(int** p, int* pj) { int i = 5; *p = pj; } int main() { int i = 10; int j = 5; int* pi; int* pj; pi = &i; pj = &j; printf("i=%d,*pi=%d,*pj=%dn", i, *pi, *pj); change(&pi, pj); printf("after change i=%d,*pi=%d,*pj=%dn", i, *pi, *pj); system("pause"); return 0; }
微软的C动态库 后缀为 dll
注意区分函数的声明与函数的定义:
链接错误 main.obj
关于全局变量与局部变量
输出结果为: 10 5
#include// 定义全局变量 int i = 10; void print(int a) { printf("print i =%dn", i); } int main() { printf("main i =%dn", i); i = 5; //局部变量 print(i); return 0; }
输出结果为 10 10
- 这是因为全局变量存储于数据段中(全局变量定义存储于数据段)
- 结构体所占的空间,并不是简单的里面所包含的数据类型容量简单相加,因为存在对齐策略,会比预期要大
易错分析一:
-
正确写法为: (*p).num ,(*p).name,(*p).sex
-
. 的优先级比 * 高
-
优化写法: p->num p->name p->sex
关于结构体的偏移:



