当前课程知识点:C语言程序设计 > 第22讲 编程训练 > 编程训练 > 指针变量(下)
数组与指针有直接关系
C语言中数组的名字有特殊含义
它表示该数组的首地址
可以直接赋值给指针变量
我们看
比如说程序当中你写的这条语句
int a[4]={1,2,3,4},
int *pa,这是一个指针变量
然后把这个数组名赋值给pa
刚才讲C语言当中数组名相当于是数组的首地址
那我们从这个图上看
这写了这个以后系统分配4个整型元素的空间
然后它们的值是1,2,3,4填在这
那么假如系统在给这个数组分配的时候
它的首地址是这样一个地址
那么你这么写了以后这个pa的值也是这个地址
我们有时候把这个指针形象化的写成一个箭头的形式
就是好像它指向到某个位置
那么因为数组它表示的是一个地址
所以数组元素使用的时候有如下的等价形式
最常见的就是通过数组它的下标来引用
那么这种形式等价于*(a+i)
就是起始地址加上偏移的地址
然后从那个位置出去等同于上面
因为这个地方a和pa是指向同一个位置
所以pa那个指针
它也可以用这种类似数组下标的形式来访问
也可以用指针的形式来访问
当数组作为函数的参数时
实参和形参有四种组合形式
这些组合我们都应该知道
虽然这里实参和形参的形式很多
但万变不离其宗
这个宗就是地址
那么实参和形参在进行配合的时候
它可能有这么几种组合
一种实参是数组名
形参也是数组名
第二种实参是数组名
形参是指针变量
第三种实参是指针变量
形参也是指针变量
第四种实参是指针变量
形参是数组名
我们以前面讲过的计算平均分为例
演示这四种组合形式
这是第一种情况
实参是数组名
形参也是数组名
我们看在main函数当中
定义了这样一个score这个成绩数组
然后我们在调用这个average函数的时候
那么我们传递的是这个数组的数组名
就是这个地方实参是数组名
就说的是这个
那么在这个函数中这个地方是形参
形参也写成数组名的形式
那具体这个里面的内容在前面讲过了
所以这个地方不多讲
唯一注意的就是这儿呢
你可以写成这个下标的形式访问
你也可以用这样的形式来访问
第二种情况
实参是数组名
而形参写成指针变量的形式
那我们看
main函数当中这个地方实参还是这个数组名
而这个形参呢
这个地方写成了指针的形式
虽然写是这样写
但其实里面使用的时候
你可以用数组的形式
也可以用这个指针变量的形式
第三种情况就是实参写成指针变量的形式
形参也是指针变量的形式
那我们看这儿跟前面相比多定义了一个指针变量ps
把这个数组的数组名赋值给这个ps
就是数组的首地址赋值给它
然后实参在调用的时候用这个指针变量ps
这儿是实参
这是一种指针变量的形式
而我们的形参呢
这儿也是用指针变量的形式
第四种形式是实参是指针变量ps是指针变量
形参可以用数组名的形式
那么下面这个地方都是一样的
形式看起来好像有点乱
但是当你理解了它不管是指针变量还是数组名
它其实指示的都是一个地址
所以它万变不离其宗
就是这个地址
内存分配有两种方式
分别是静态分配和动态分配
我们前面程序用到的都是静态内存分配
动态内存分配是一种更灵活的内存分配方式
有些情况下
使用这种方式更合理
静态分配
系统自动为你分配空间
而动态分配呢
是使用动态分配内存函数
申请内存空间
静态分配的例子包括这定义了两个整型变量a和b
那么系统会为你分配这个空间
如果你定义了这是一个整型的数组
那么系统会给你分配有100个元素的整数的这样的空间
静态分配可能存在两个问题
第一个分配的空间太小了不够
太大了浪费
比如我们前面我们在计算学生成绩的时候
那么一个合理的能够应用的系统当中
那个数组的大小你应该给它分配多大呢
这个就不太好讲
那么你分配的小了可能就不够用
分配的大了就有浪费这种情况
第二个问题是当要求的系统分配很大的空间的时候
系统没有这么多空闲空间
那这会出现什么情况呢
比如说你在这个地方定义一个数组
这儿要求它分配的空间可能有几千或者上万这么大
那么这种程序有些时候
程序编译没有错误
但是一运行就直接退出了
你可能觉得莫名其妙
到底怎么回事呢
那有一种可能就是你在这个地方定义数组的时候
它的那个元素太多
就说系统它没有那么多空闲空间
它也不提示你
然后呢它又分配不了
然后程序就自动退出了
有时候这种错误还比较隐蔽难以发现
我们看一下内存的动态分配
我们常用的分配函数是这个malloc
那么它的功能是向系统申请大小为size的内存块
系统如果找到了一块未占用的内存
就将这块地址的首地址返回
若申请不成功
就返回NULL
就是你申请的这个size不能满足这么大
那么就返回NULL,如果成功的话
返回的是那块地址的首地址
例如你要申请一块可存放10个整型变量的内存
那么就是定义这样一个指针变量
然后使用malloc这个函数
注意malloc函数使用的时候
这个前面的有一个强制类型转换
因为你这儿定义的是一个整型的指针变量
所以这就强制转换成int*
就强制把它转换成整型指针
这儿分配的因为是10个整型变量内存
我们用10乘以sizeof(int)
sizeof(int)的意思是一个整型变量它占多大空间
这个可能它会由于系统的不同会有所差异
那么这儿这么写是比较好的一种写法
C语言当中动态申请的内存如果不主动释放的话
那么系统是不会帮你释放的
那么这样呢如果你一直不释放
就是说就好比像一个公共的空间里面
你老是拿公共的用品
完了以后你不还回去
那么用品就会越来越少
到最后就没得用了
这个内存也是这样
所以一个好的习惯就是申请了内存以后
在程序退出之前应该给它释放掉
释放内存的函数叫free
那么这个使用非常简单
比如说你上面这样申请到的内存空间
就直接用这个free(p)
这个变量名写在这
这样它就释放了
我们下面看一个内存动态分配的例子
前面在计算学生平均成绩时
用的是数组
就相当于是静态分配
我们下面这个例子展示了类似的功能
但使用的是内存动态分配
大家可以来回看看
比较一下两者的区别
我们先看一下这个main函数
在这儿它先定义了一个指针变量p
完了以后这个地方
就是你要申请的这个空间大小
你可以从键盘上输入
那么输入了这个n的大小以后这就进行了分配
这是想分配float类型的元素
所以malloc前面强制类型转换成float*
申请的大小就是n个float类型的数据
通常在这个malloc函数写完以后
这应该写一个就是看一下是否这个p等于NULL
前面已经解释过了
如果这个申请不成功
那么它会返回一个NULL空值
就是如果p等于空的话
就输出没有足够的内存
然后程序退出
这样呢你运行的时候就知道
如果出现这种情况的话是什么状况
下面这个就是申请成功的情况
申请成功了
然后从键盘上读入n个值
读到p的空间里面
这个地方
因为我们前面解释过
这个指针变量它和数组其实有非常类似的关系
所以你这个地方输入的时候可以采用数组的形式
然后这调用求平均分的这样一个函数
我们看这个函数
前面已经解释过了
这就不多说了
这儿调用完了以后计算得到的平均分赋值给aver
然后输出这个平均分
-作业
-作业
-作业
-作业
-作业
-作业
-作业
-作业
-循环类型
-作业
-程序结构
-函数基础
-作业
-数组基础
-作业
-作业
-作业
-作业
-程序调试
- 文件(上)
- 编程训练