10 第6章 数组与指针— 指针
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
3、数组与地址
例如:有一条定义语句“int a[3]={1,2,3};”,分配的内存单元 如图3所示,而记录下来的数组与地址对照表如图4所示。
地址 内存单元 3000 3001 3002 3003 3004 3005 1 2 3 图3 数组名 a 整型数组元素a[0] 整型数组元素a[1] 整型数组元素a[2] 数组与地址对照表 数据类型 整型 图4 长 度 3 首地址 3000
C语言规定:
① 变量地址只能利用“取地址”运算符“&”通过运算获得 运算对象:变量或数组元素名 运算结果:对应变量或数组元素的地址 例如:变量i的地址应写成表达式“&i” 数组元素a[1]的地址 “&a[1]” ② 数组的首地址就是数组名,不必利用取地址运算符通过 运算获得 例如定义了数组a,这个a在程序中可以直接使用,代 表该数组的首地址,也是数组元素a[0]的地址。 所以“a”和“&a[0]”的作用是相同的。
1、内存单元和地址
内部存储器是由多个内存单元组成的,每个内存单元 有自己独有的地址,称为内存单元地址
2、变量与地址
程序中可以用变量来存放各种数据,因此每个变量都 需要分配连续的内存单元
由于数据类型的不同,每个变量需要分配的内存单元 数目也不同
2、变量与地址
当一个变量只占用一个内存单元时,内存单元的地址 就是变量的地址
(三)
指针运算符(*)
运算对象:已赋值的指针变量,不能是普通变量 变量的地址 数组元素的地址
运算结果:指针所指向的内存单元的内容
(三)
例如
指针运算符(*)
定义:变量a、数组b[10]、指针变量p 执行:“p=&a”,即p已指向了a,则*p代表变量a 执行:“p=&b[3]”,即p已指向了数组元素b[3],则*p就 代表数组元素b[3] 注意:当指针变量的值为数组的首地址,“* 指针变量” 也是正确的,它代表数组的第一个元素。例如,执行了 “p=b”,即 p已指向了数组b,则*p就代表数组元素b[0]
说
明
(5)其中的“初值”通常是“&普通变量名”、“&数组元素名” 或“数组名”,这个普通变量或数组必须在前面已定义。 这个普通变量或数组可以是在本语句的前面出现的定义 语句中定义的,也可以是在本定义语句中出现的,但必须是 对应指针变量前出现
说
明
(6)一个定义语句中,可以只给部分指针变量赋初值
例:指针变量的定义和初始化 int a; int *p=&a,*p3; float f1, f[10], *p1=&f1, *p2=f;
例:用指针方法按从小到大的顺序输出三个整数
main( ) { int a,b,c; int *pa=&a,*pb=&b,*pc=&c,*p; scanf (“%d,%d,%d”,pa,pb,pc); if (*pa>*pb) { p = pa; pa = pb; pb = p; } if (*pa>*pc) { p = pa; pa = pc; pc = p; } if (*pb>*pc) { p = pb; pb = pc; pc = p; } printf (“%d<=%d<=%d\n”,*pa,*pb,*pc); }
(二)
指针变量的引用方式
3、通过指针变量引用所指向的变量 格式:* 指针变量名 “* 指针变量名”代表它所指向的变量
例如:int i = 1, j = 2, k, *p = &i ; k = *p + j ;
(三)
取地址运算符与指针运算符
对象数 单目 前缀
名称 取地址
运算符 &
运算规 则 取运算 对象的 地址 取所指 向的变 量或数 组元素 的值
(1)指针变量和整数的算术运算 ++指针变量 “指针变量中的地址+指针变量类型占用单元 数”对应的地址,此后,指针变量将指向下一 个数组元素 注意:指针变量本身的值已经发生了变化 --指针变量 “指针变量中的地址-指针变量类型占用单元 数”对应的地址,此后,指针变量将指向上一 个数组元素 注意:指针变量本身的值已经发生了变化
(1)指针变量和整数的算术运算
上述运算规则组成的式子称为表达式,这种表达式的类 型是“地址型”,所以上述规则组成的表达式常称为“地址型表 达式”或“指针型表达式”,简称为“指针表达式”
(1)指针变量和整数的算术运算 例如:定义整型数组a[10],整型指针变量pa 执行pa=a 假定数组a的首地址为2000 则,下列表达式的运算结果: 执行pa=pa+5后 pa指向数组元素a[5],pa的地址值将为 2000+5*2=2010,其中的“2”是整型数 占用的单元数 再执行pa--后 pa将指向数组元素a[4],pa的地址值将为 2010-1*2=2008
(二)
指针变量的引用方式
1、给指针变量赋值
格式:指针变量=表达式 该表达式必须是地址型表达式
例如:int
i, *p_i;
p_i=&i;
(二)
指针变量的引用方式
2、直接引用指针变量
需要用到地址时,可以直接引用指针变量 例如:int i, j, *p=&i, *q; q=p; scanf (“%d, %d”, q, &j);
1、用指向一维数组的指针变量处理数组元素
引用方式一:当指针变量指向数组首地址
引用“数组元素[0]” 引用“数组元素[i]”
* (指针变量+0) 或 * 指针变量 * (指针变量+i)
1、用指向一维数组的指针变量处理数组元素
引用方式二:当指针变量指向下标为i的数组元素
引用“数组元素[i]” 引用“数组元素[i-k]” 引用“数组元素[i+k]”
变量与地址对照表
变量名 i j f 数据类型 整型 整型 单精度 地址 2001 2003 2005
单精度变量f
图1
图
2、变量与地址
通过变量名查取变量的地址,再从变量对应地址的内 单元中取得值或将某值存入变量对应地址的内存单元中称 直接寻址(访问)方式
3、数组与地址
对一个数组来说,所分配的内存单元必须是连续的,并 且按顺序与数组元素对应 每个数组元素也要占用连续的内存单元。数组类型不 同,每个数组元素占用的内存单元数也不同 数组占用的总单元数 = 数组长度×每个数组元素占用 的内存单元数
1、用指向一维数组的指针变量处理数组元素
注意: 指针变量是存放地址这种数据类型的变量,可以按照 变量的处理方式对其进行运算 而数组名仅仅是一个地址常量,只能按照常量的方式 进行处理
2、指向一维数组的指针变量的运算
(1)指针变量和整数的算术运算
指针变量+整数 “指针变量中的地址+整数*指针变量类型 占用单元数”对应的地址 注意:指针变量本身的值并没有变化 指针变量-整数 “指针变量中的地址-整数*指针变量类型 占用单元数”对应的地址 注意:指针变量本身的值并没有变化
6.2.2 指针变量的定义、初始化和引用
(一) 指针变量的定义和初始化
1、指针变量的定义和初始化格式 数据类型 *指针变量名 [=初值] ; 例如: int *p = &i ;
2、功能:定义指向特定数据类型的变量或数组的若干 个指针变量,同时给这些指针变量赋初值。
说
明
(1)指针变量名的命名原则同标识符,前面必须有“*”号 (2)在一个定义语句中,可以同时定义普通变量、数组、 指针变量 (3)定义指针变量时的“数据类型”可以选取任何基本数据类 型,也可以选取以后介绍的其它数据类型。 这个数据类型不是指针变量中存放的数据类型,而是它将 要指向的变量或数组的数据类型
* (指针变量+0) 或 * 指针变量 * (指针变量-k) * (指针变量+k)
1、用指向一维数组的指针变量处理数组元素
● 当指针变量指向首地址后,对下标为i的数组元素引用 有下列四种方法:* (指针变量+i) * (数组名+i) 指针变量[i] 数组名[i] 前两种引用数组元素的方法采用“指针运算符”,称为 “指针法” 后两种引用数组元素的方法采用“下标运算符([])” 称为“下标法”
(1)指针变量和整数的算术运算 指针变量++ “指针变量中的地址”对应的地址(因为是后 增1运算符),此后,指针变量将指向下一个 数组元素 注意:指针变量本身的值已经发生了变化 指针变量-- “指针变量中的地址”对应的地址(因为是后 减1运算符),此后,指针变量将指向上一 数组元素 注意:指针变量本身的值已经发生了变化
运算对象 (1)变量 (2)数组元素 (1)指针变量 (2)变量的地址 (3)数组元素的 地址
运算结果 对象的地址 指针变量所 指向的变量 或数组元素 的值
结合性 自右向左
单目 前缀
指针 (间接 访问)
*
自右向左
(三) 取地址运算符(&)
运算对象:已定义过的变量或数组的元素 不能是数组名、常量 运算结果:运算对象的地址 例如: 定义:变量a、数组b[10],则&a、&b[0]、&b[9]均合法 代表:变量a的地址 数组元素b[0]的地址、数组元素b[9]的地址 而&b则是非法的
(三)&和*的运算优先级
· &、*和自增、自减等单目运算符是同级别的
· 所有单目运算符的结合性均为自右向左
(三)&和*的运算优先级
在混合使用运算符时,要注意分清它们的运算对象和运 时的结合性。 例如,设有变量a、指针变量pa,且pa已经指向a,则
*&a 正确的 相当于“*(&a)”,&a是变量a的地址,*(a地址)代表变量a &* a 错误的 相当于“&(*a) ”,因为a不是合法运算对象,所以* a不正确 *&pa 正确的 相当于“*(&pa)”, &pa是pa的地址,*(pa地址) 代表指针变量 &*pa 正确的 相当于“&(*pa)”,*pa代表变量a,&(变量a)代表a的地址
4、指针和变量 —— 指针变量
地址也是一种值,也可以存储在一个变量中 由于地址是一种特殊的数据类型,所以存放地址的变量与存放字符型、 整型、实型数据的变量不同,是特定类型的变量 存放地址的变量像一个指针,指向要存取值的变量,所以将这种变量 称为“指针变量” 先通过指针变量获得变量的地址,再到相应地址中访问变量的方式, 称为“间接寻址(访问)方式”
3、数组与地址
当一个数组元素只占用一个内存单元时,内存单元的地 址就是该数组元素的地址 当数组元素占用若干个连续的内存单元时,最前面一个 单元的地址就是该数组元素的地址 当一个数组占用连续的若干个内存单元时,最前面的单 元地址称为数组的首地址,也是第一个数组元素的地址
3、数组与地址
每个数组元素的地址可以通过下列公式求得: 数组元素a[i]的地址=数组首地址+i×数组元素的数据类 所占用单元数 对源程序进行编译时,每遇到一个数组,按其类型和 度分配内存单元,同时记录数组名、数据类型、数组长度、 数组首地址。
指
6.2 指针的概念 6.3 指针与数组 6.4 字符串的指针
针
*6.5 指针数组和指向指针的指针
6.2 指针的概念
6.2.1 地址与指针的概念 6.2.2 指针的定义、初始化与引用
6.2.1 指 针 概 述
指针是一种数据类型 所谓指针,就是存放数据的内存地址 指针变量是一种变量,该变量中存放的数据就是指针类型 的数据 对一个变量或数组元素来说,可以通过变量名或数组名 标]来引用,也可以通过指针变量来引用,但需要事先将指 针变量“指向”变量或数组,所谓“指向”就是将变量或数组 地址存放到指针变量中
6.3 指针与数组
6.3.1 指向一维数组的指针 6.3.2 指向多维数组的指针
6.3.1
指向一维数组的指针
1、用指向一维数组的指针变量处理数组元素
2、指向一维数组的指针变量的运算
1、用指向一维数组的指针变量处理数组元素
当指针变量已指向数组后,就可以用指针变量处理 数组中的每个元素。
处理数组元素的关键是引用数组元素,引用数组元 素的方法与指针指向数组的方式有关:
பைடு நூலகம்
当变量占用连续的若干个内存单元时,最前面一个单 元的地址就是该变量的地址
2、变量与地址
例如,int i=3, j=5 ; float f ; 分配的内存单元如图1所示 记录下来的变量与地址对照表如图2所
2001 2002 2003 2004 2005 2006 2007 2008
3 5
整型变量i 整型变量j
4、指针和变量 ——指针变量
举例:如何使用指针变量,通过间接寻址方式完成赋值语句“a[1]=i*j;”
操作 (1)事先将变量i、j和数组元素a[1]的地址分别存入指针变量pi、pj、p (2)操作过程: 首先从指针变量pi中取出i的地址,再从该地址所对应的内存空间中 取出变量i的值; 按同样方法取出j的值,进行相乘; 最后从指针变量p中取出数组元素a[1]的地址,将运算结果存入该 址所对应的内存空间中。