文章目录
第11次直播 指针数组与malloc
易错三大例子
例子一:
上述正确的输出为: 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 ;
释放操作
栈空间与堆空间的差异
问题引入:
#include <stdio.h>
char* print_stack() {
char c[17] = "i am ok";
puts(c);
return c;
}
int main() {
char* p;
p = print_stack();
puts(p);
return 0;
}
- 原因在在于函数是栈空间,栈空间会随着函数结束而释放。
- 不能使指针变量指向栈空间,进行操作,因为栈空间会在之后进行释放
解决方法
- 堆空间不会随子函数的结束而释放,必须自己free
第12次直播 函数与指针
字符指针与字符数组的初始化(了解)
- 字符指针可以初始化赋值一个字符串,字符数组初始化也可以赋值一个字符串。
char *p="hello"
和char c[10]="hello"
有什么区别呢?
易错分析一:
错误分析:
- 对
p[0]
进行修改,会报如下错误,然而c[0]
对数组进行修改可以,因为char c [10] = "hello"
实际等价于strcpy(c,"hello") ;
操作的是堆区(可读可写),p[0]
实际操作的是字符串常量区(数据区),该区域只读不能写
原因在于:不能对常量区数据进行修改
易错分析二:
第12次直播 二级指针 结构体
-
二级指针只服务于一级指针的传递与偏移
-
要想在子函数中改变一个变量的值,必须把该变量的地址传进去
-
要想在子函数中改变一个指针变量的值,必须把该指针变量的地址传进去
#include <stdio.h>
#include <stdlib.h>
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=%d\n", i, *pi, *pj);
change(&pi, pj);
printf("after change i=%d,*pi=%d,*pj=%d\n", i, *pi, *pj);
system("pause");
return 0;
}
微软的C动态库 后缀为 dll
注意区分函数的声明与函数的定义:
链接错误 main.obj
关于全局变量与局部变量
输出结果为: 10 5
#include <stdio.h>
// 定义全局变量
int i = 10;
void print(int a) {
printf("print i =%d\n", i);
}
int main() {
printf("main i =%d\n", i);
i = 5; //局部变量
print(i);
return 0;
}
输出结果为 10 10
- 这是因为全局变量存储于数据段中(全局变量定义存储于数据段)
结构体
- 结构体所占的空间,并不是简单的里面所包含的数据类型容量简单相加,因为存在对齐策略,会比预期要大
结构体指针(重要)
易错分析一:
-
正确写法为:
(*p).num ,(*p).name,(*p).sex
-
.
的优先级比*
高 -
优化写法:
p->num p->name p->sex
关于结构体的偏移: