当前课程知识点:C语言程序设计 > 第9章 指针 > 9.2 指针变量的概念(下) > 指针变量的概念(下)
在这节当中
我们将和大家一起探讨指针变量如何定义
以及指针变量指向一个变量时
对应的一些表达式的含义
我们还会研究指针变量的初始化
野指针
以及指针做函数形参 首先我们看一下指针变量如何定义
指针变量 定义指针变量的一般形式为
存储类型 数据类型 *指针名
例如int *p1 *,p2 float *q
对指针变量的定义包括三个内容
1 指针类型说明
即定义变量为一个指针变量
2 指针变量名
3 变量值(指针)所指向的变量的数据类型
注意 指针变量只能指向定义时所规定类型的变量
指针变量定义后变量值不确定
使用前必须先赋值
如果将变量或数组函数等
的首地址赋值给指针变量
则称该指针指向该变量或数组 函数等
指针变量的基类型用来指定此指针变量可以指向的变量的类型
下面我们来研究一下指针变量的初始化
一般形式
[存储类型] 数据类型 *指针名=初始地址值
初始地址值要赋给指针变量
不能赋给目标变量
变量必须已说明过
类型应一致
如果在赋值之后在定义目标变量是错误的
用已初始化指针变量作初值
表示两个指针变量p
q指向同一变量a
需要注意的是不能用auto变量的地址去初始化static型指针
指针变量必须先赋值 再使用
当我们定义了指针变量p
没有对它进行初始化指向
那么使用赋值表达式*p=a时
由于p的指向是随机的*p
取p所指向的对象值就是危险的
他不像我们想象中的指向应该是零
在这种情况之下会产生使用风险
我们把这种未进行初始化指向而使用的指针称之为野指针
最为稳妥的办法是
定义指针变量之后
首先定义一个变量
让指针变量初始化指向这个变量
然后进行使用指针变量做间接访问内存的操作
我们在这个例题当中可以看到
我们先让指针变量p指向变量K
然后用A的值对p所指向的变量K进行赋值操作
下面我们来探讨指针变量作为函数参数——地址传递
首先我们先复习一下值传递
值传递的特征是实参传递给形参的是值
在发生值传递时
将实参的值拷贝一份放到形参里面
对形参的改变无法影响实参
比如这个例题
我们使用实参a b
分别传递5 9给形参X Y
函数swap做了对Xy的一个交换
但是XY的改变无法传递回给实参ab
函数调用结束后ab的值不变
无法达到从大到小输出的这个效果
下面我们来看
使用指针变量做函数参数
实现地址传递时能否改变实参a b的值
首先我们定义变量a b
在定义指针变量point1 point2
让他们分别指向ab
然后我们调用函数
让指针变量point1
point2做函数实参
在函数调用时形参P1
P2做地址传递
分别指向point1
point2指向的变量ab
函数swap完成的是p1所指向的内容a和P2
所指向的内容b之间的一个交换
大家由图可以看出
我们通过函数可以达到对a
b的值一个交换
这样子 我们使用指针变量做函数参数
可以做到共享内存的目的
并能实现对形参所指向值的改变
可以共享实参所指向的内存单元
改变实参所指向的存储单元的值
下面我们对这个例题做一个非常小的改变
在函数swap中
我们使用第三变量整型变量p来达到交换的目的
下面我们把变量p改成指针变量p
大家看一下能否达到交换的目的
首先 大家看一下的指针变量的使用是否规范
我们说定义一个指针变量我们首先要做指针变量初始化指向
防止它成为野指针
请大家观察这道题对指针变量p是否做了初始化指向
因为没有p赋值为某变量地址的表达式
所以p未做初始化指向就对其做了一个*p=*p1的赋值
该表达式的含义是取p所指向的内存单元的值
将它赋值为p1所指向的变量的内存单元的值
大家可以看一下
在这里p是一个野指针
那么我们说也许它可以达到一个交换的目的
但是野指针P的使用是非常危险的
因为你无法获知
它当中的随机数指向谁
也许指向系统核心也未可知
所以要请大家警惕
并进行指针变量初始化指向后在使用
今天的内容就讲到这里
在这一节中我们主要学习了探讨指针变量如何定义
以及指针变量指向一个变量时
对应的一些表达式的含义
我们研究了指针变量的初始化野指针
以及指针做函数形参的情况
同学们 今天的课就到这里 我们下次课再见
-计算思维与计算机
--计算思维与计算机
--计算思维与计算机
--计算思维和计算机
-2.1 程序设计语言的发展及其特点和应用
--程序设计语言的特点及发展
- 2.2 C语言程序的基本结构及编制C语言程序的基本步骤
--C语言程序的结构和编制步骤
-3.1 C语言的数据类型
--C语言的数据类型
--C语言的数据类型
-3.2 常量
--常量
--常量
-3.3 什么是变量
--什么是变量
--什么是变量
-3.4 如何进行算术运算
--如何进行算术运算
--如何进行算术运算
-3.5 赋值运算符和逗号运算符
--赋值运算符和逗号运算符
-3.6 数据类型转换
--数据类型转换
--数据类型转换
-4.1 格式化输出printf
--格式化输出
-4.2 格式化输入scanf及字符数据的非格式化输入输出
--格式化输入
-5.1 关系运算符和关系表达式
--关系运算符和关系表达式
-5.2 逻辑运算符和逻辑表达式
--逻辑运算符和逻辑表达式
-5.3 条件运算符和条件表达式
--条件运算符和条件表达式
-5.4 if语句
--if语句
--if语句
-5.5 switch语句
--switch语句
--switch语句
-6.1 while语句
--while语句
--while语句
--do-while语句
-6.2 for语句
--for语句
--for语句
-6.3 循环的嵌套
--循环的嵌套
--循环的嵌套
-6.4 break语句和continue语句
--break和continue语句
-7.1 一维数组的定义和引用
--一维数组的定义和引用
-7.2 一维数组的赋值
--一维数组的赋值
--一维数组的赋值
-7.3 二维数组的定义和引用
--二维数组的定义和引用
-7.4 二维数组的赋值
--二维数组的赋值
--二维数组的赋值
-7.5 字符串的本质
--字符串的本质
--字符串的本质
-7.6 字符串操作的常用函数
--字符串常用函数
-7.7 字符串数组
--字符串数组
--字符串数组
-8.1 函数概述
--函数概述
--函数概述
-8.2 有参函数
--有参函数
--有参函数
-8.3 函数参数的传递方式
--函数参数的传递方式
-8.4 变量的作用域和生存期
--变量的作用域和生存期
-8.5 变量的存储类型
--变量的存储类型
--变量的存储类型
-8.6 函数的嵌套和递归调用
--函数的嵌套和递归调用
-8.7 函数的作用域与封装
--函数的作用域与封装
-9.1 指针变量的概念(上)
--指针变量的概念(上)
-9.2 指针变量的概念(下)
--指针变量的概念(下)
-9.3 指向一维数组的指针变量
--指向一维数组的指针变量
-9.4 指向二维数组的指针变量(上)
--指向二维数组的指针变量(上)
-9.5 指向二维数组的指针变量(下)
--指向二维数组的指针变量(下)
-9.6 动态内存分配
--动态内存分配
--动态内存分配
-10.1 编译预处理
--编译预处理
-11.1 用户自己建立数据类型
--用户自己建立数据类型
-11.2 定义结构体类型变量
--定义结构体类型变量
-11.3 结构体变量的引用与初始化
-11.4 结构体数组
--结构体数组
--结构体数组
-11.5 指向结构体类型数据的指针
--指向结构体类型数据的指针
-12.1 文件的基本概念和文件指针
--文件的基本概念和文件指针
-12,2 文件的打开和关闭
--文件的打开和关闭
--文件的打开和关闭
-12.3 文本文件读写
--文本文件读写
--文本文件读写
-12.4 二进制文件读写
--二进制文件读写
--二进制文件读写