资源预览内容
第1页 / 共70页
第2页 / 共70页
第3页 / 共70页
第4页 / 共70页
第5页 / 共70页
第6页 / 共70页
第7页 / 共70页
第8页 / 共70页
第9页 / 共70页
第10页 / 共70页
亲,该文档总共70页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
1,第6章 指针和引用,6.1 指针基本概念 6.2 指向数组元素的指针 6.3 指针形参 6.4 数组形参,6.5 指向二维数组一整行的指针 6.6 指针数组 6.7 多级指针 6.8 函数指针 6.9 返回指针值的函数,2,6.1 指针基础概念,指针是C语言的一个重要概念。指针在程序中有以下多方面的作用: (1) 利用指针能间接引用指针所指的对象。 (2) 指针能用来描述数据之间的关系,以便构造复杂数据结构和处理动态数据结构问题。 (3) 利用指针形参,能使函数间接引用调用环境中的变量。 (4) 指针与数组结合,使访问数组元素的方式更加多样、手段更加灵活。 (5) 熟练正确应用指针,能写出紧凑高效的程序。,3,1. 变量、变量的地址及变量的值,程序在计算机上运行时,程序中的变量会在内存中占据由若干字节组成的一个内存储块,用于存放变量的值。存储块的开始地址称为变量的地址。 程序用变量的名引用变量的值或变量的地址。 例如: int x = 1; x = x + 2; 在代码“x = x+2;”中,赋值号左边的 x 表示将存入变量 x,赋值号右边的 x 表示引用变量 x 的值。该代码的意义是“完成取x的值,加上 2 的计算,并将计算结果存入变量 x 中。”,4,2. 指针变量和它所指向的变量,取变量地址运算符: & 例: &x 表示取变量x的地址 说明: 变量的地址也可作为一种值被存储和运算。 除能按名引用变量外,也可利用变量的地址引用变量。按变量名引用变量习惯称为直接引用,而将变量A的地址存于另一变量B中,借助于变量B引用变量A称为对A的间接引用。,5,指针变量的定义,指针变量:专门用于存放某个变量地址。 一般形式为: 类型 *标识符; 其中, 标识符:指针变量的名,标识符之前的*符号表示该变量是指针变量。 类型: 表示该指针变量能指向的数据类型。 例如, int *ip; float *fp; 说明: 定义指针变量ip和fp,ip能取int类型变量的地址,fp能取float类型变量的地址。,6,指针变量的定义,例如: int *ip, i = 2; ip = 表示:将整型变量i的地址(而非内容)赋给指针变量ip。 使指针变量ip与变量i之间建立如下图所示的关系 (假设分配给变量 i 的内存地址为1000)。 当指针变量 ip 的值为变量 i 的地址时,就说指针变量 ip 指向变量 i 。,7,指针变量定义时指定初值,例如: int j; int *intpt = &j; 表示:在定义 int * 类型指针变量 intpt 时,给它初始化为 int 类型变量 j 的地址,使它指向 j。,8,指针变量定义说明,(1) 当定义局部指针变量时,如果未给它指定初值,则它的值是不确定的。 (2) C语言规定 0 地址记为 NULL,即表示空地址。 例如: ip = NULL; 表示:指针变量 ip 为空指针,不指向任何变量。 (3) 指针变量只能取程序对象的地址值,不能将任何其他非地址值赋给指针变量。 (4) 一个指针变量只能指向同一个类型的变量,不能一会儿指向整型变量,一会儿指向实型变量。,9,指针变量定义说明,例如:int i = 100, j, *ip, *intpt; float f, *fp; 以下都是不正确的赋值: ip = 100; /* 指针变量不能赋整数值 */ intpt = j; /* 指针变量不能赋整型变量的值 */ fp = /* 使 ip 不再指向任何变量 */,10,3. 引用指针变量所指的变量,引用指针变量所指向的对象:* 指针变量 例如:int i=3, j, *ip, *intpt; ip = 使两个指针变量intpt与ip指向同一个对象,或都不指向任何对象(如果ip的值为NULL)。,11,#include void main() int k; /* 定义整型变量 */ int *kPtr; /* 定义整型指针变量 */ k = 7; kPtr = ,【例6.1】说明指针变量与它所指变量之间关系的示意程序,k的地址是 12ff7c kPtr的值是 12ff7c k的值是 7 *kPtr的值是 7,运行结果,以下表明运算符 * 和 & 是互逆的: &*kPtr = 12ff7c *&kPtr = 12ff7c,12,已知:int i=100, j=200, *ip=,引用指针变量所指的变量,语句:intpt = ip; 的作用如右图所示,13,已知:int i=100, j=200, *ip= */,引用指针变量所指的变量,14,指针变量说明,(1) 定义指针变量与间接引用指针变量所指对象采用相似的标记形式(* 指针变量名),但它们的作用与意义是完全不同的。 例如:int i,*ip = 说明:凡变量 i 能使用的地方,*ip一样能用。,15,指针变量说明例1,(3) 因单目运算符*、,16,指针变量说明例2、3,例2:int i = 5, j, *ip = ,17,将数组元素的地址赋值给指针变量,就能使指针指向数组元素。 例如:int a100, *p; p = 2. 比用下标引用数组元素更灵活和简洁, 因为指针运算能力强。,6.2 指向数组元素的指针,18,对指向数组元素的指针允许作有限的运算 例如: int *p, *q, a100; p = (1) 两个指向同一个数组元素的指针可以作关系比较 (, =, !=)。 若 p=q 表示p,q指向数组的同一个元素; pq 表示p所指向的数组元素的下标大于q所指向的数组元素的下标。,6.2 指向数组元素的指针(续),19,(2) 指向数组元素的指针可与整数进行加减运算 由于数组元素在内存中顺序连续存放,因此表达式a+1为a1的地址,a+2为a2的地址。 若指针 p = 则 *(p+i)表示ai。 *(p+i)也可写成pi。,6.2 指向数组元素的指针(续),20,用数组名与指针的区别: 指针变量的值可改变,如 p+;数组名只代表数组首元素的指针,是不可改变的(是常量),如 a+;是错误的。 例:利用指针遍历数组,输入生成一个数组并复制到另一个数组。 int a100, b100, *p, *q; for(p = a; p a + 100;) /* 利用指针,输入数组的全部元素*/ scanf(“%d“, p+); for(p = a; p = ,6.2 指向数组元素的指针(续),21,当指针变量指向字符串某字符时,习惯称这样的指针为字符串的字符指针。因为字符串存储于字符数组中,所以字符串的字符指针也是指向数组元素的指针。 为字符串常量提供存储空间有两种方法: 1. 把字符串常量存放在一个字符数组中。 例如:char s = “I am a string.“; 2. 字符串常量放在程序运行环境的常量存储区中。 例如:char *cp1, *cp2 = “I am a string“; cp1 = “Another string“; 说明:字符指针指向字符串的第一个字符,即指向A。,指向字符串的指针,22,【例6.2】将一个已知字符串复制到一个字符数组。 1. 用下标引用数组元素方法 int k = 0; char *from = “Fudan University“; char d100, *to=d; while( tok = fromk ) != 0 ) k+; puts(d); /* 或使用printf (“%sn“, d) */ 2. 采用字符指针描述方法 while(*to+ = *from+ ) != 0); 更简洁的写法是:while(*to+ = *from+);,指向字符串的指针(续),23,【例6.3】将字符串s中的某种字符去掉,假设要去掉的字符与字符变量c中的字符相同。 采用一边考察字符一边复制。引入两个字符指针p和q,p指向当前正考察的字符,q指向下一个用于存储复制字符的位置。若p所指字符与c不相同,则将它复制到新字符串。否则,该字符不被复制。每复制一个字符q才增1,p是每考察一个字符就增1。 char s = “Fudan University“, *p, *q, c = i; for(p = q = s; *p; p+) if (*p != c) *q+ = *p; /* 复制 */ *q= 0; /* 重新构成字符串 */,指向字符串的指针(续),24,在C的函数计算过程中,函数不能修改实参变量。但许多应用要求被调用函数能修改由实参指定的变量。C语言的指针形参能实现这种特殊的要求。指针形参能够指向的对象的类型在形参说明时指明。 例如,以下函数说明中 void divNum(int *intPt, int d); intPt是一个指针形参,它能指向int类型的变量。 调用有指针形参的函数时,对应指针形参的实参必须是某个变量的指针。指针形参从实参处得到某变量的指针,使指针形参指向一个变量。这样,函数就可用这个指针形参间接访问被调用函数之外的变量,或引用其值,或修改其值。因此,指针类型形参为函数改变调用环境中的变量提供了手段。,6.3 指针形参,25,#include /* 使用一般形参计算n2 */ int squreByValue(int n) return n*n; /* 以n的平方为结果返回 */ /* 使用指针形参计算n2 */ void squreByPoint(int *nPtr) *nPtr = *nPtr * *nPtr; /* 将形参所指向的变量值平方,并存于该变量中 */ ,【例6.4】 求n2,26,void main() /* 主函数 */ int m = 5; printf(“数m原来的值是 %dn“, m); /* 5 */ printf(“函数调用squreByValue(m)的返回值是 %dn“, squreByValue(m); /* 25 */ printf(“函数调用后m的值是 %dn“, m); /* 5 */ /* m值没有因调用函数而改变 */ printf(“*n“); printf(“数m原来的值是 %dn“, m); /* 5 */ squreByPoint( /* 25 */,【例6.4】 求n2,27,#include void main() int a = 1, b = 2; void swap(); printf(“调用 swap 函数之前:a = %dtb = %dn“, a, b); swap( ,【例6.5】 使用指针形参, 交换两个整型变量的值,运行结果,调用 swap 函数之前: a = 1 b = 2 调用 swap 函数之后: a = 2 b = 1,28,#include void paws(int u, int v) int t = u; u = v; v = t; printf(“在函数 paws 中:u = %dtv = %dn“, u, v); void main() int x = 1, y = 2; paws(x, y); printf(“在主函数 main 中:x = %dty = %dn“, x, y); ,【例6.6】 使用非指针形参, 不能交换两个整型变量的值,运行结果,在函数 paws 中: u = 2 v = 1 在主函数 main 中: x = 1 y = 2,29,#include void f1(int x, int y) int t=x; x=y; y=t; void f2(int *x, in
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号