C程序设计 第9章 指针_第1页
C程序设计 第9章 指针_第2页
C程序设计 第9章 指针_第3页
C程序设计 第9章 指针_第4页
C程序设计 第9章 指针_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第九章指 针1内存(Random Access Memory)计算机内的存储部件,所有指令和数据都保存在内存。地址(Address) 一个无符号整数。内存中的每个字节都有唯一的一个地址。地址按字节编号,按类型分配空间。9.1 引言2如何读写内存中的数据?通过变量的地址访问变量所在的存储单元。两种寻址方式直接(寻址)访问直接按变量地址来存取变量内容的访问方式。间接(寻址)访问通过指针变量来间接存取它所指向的变量的访问方式。两种访问方式的比较 一种情况是,甲知道乙在何处,直接去找就是(即直接访问)。另一种情况是,甲不知道乙在哪,但丙(指针变量)知道,此时甲可以这么做:先找丙,从丙处获得乙的去向,然

2、后再找乙(即间接访问)。3使用原则永远要清楚每个指针指向了哪里(位置)永远要清楚指针指向的位置是什么(内容)49.2 指针变量的定义、引用和初始化指针 是一种数据类型;指针类型的数据 就是内存的地址;指针常量 内存地址;指针变量 具有指针类型的变量,专门存放地址 ;变量的指针 变量的地址20003 p i2000p是指针变量p是i的指针p指向了i59.2 指针变量的定义、引用和初始化指针变量的定义基类型 *变量名;基类型 *变量1, *变量2, 变量3, 变量4;int *p1, *p2, a1, a2;指针变量初始化p1 = &a1; p2 = &a2;指针变量可以动态地保存不同内存的地址,

3、从而使指针变量指向不同的变量;但是,某种类型的指针,只能保存其基类型变量的地址。6&与*运算符int i,*p,a10;p = &i;p = a;p = &a0;p = &a5; int i, *p, a10;p = &i;*p = 0;p = a;*p = 0;p = &a0;*p = 0;p = &a5;*p = 0;* 取得指针指向地址的内存& 取变量的地址对 *p 操作就是对p所指向的变量操作;对 *p 操作就是对p所指向的内存内容操作;7p = &a;*p就像普通的变量一样使用,其值是p指向的内存的内容(在上例和a等价,但寻址方式不同)p可以动态(任意)地指向不同内存,从而使*p代表

4、不同的变量89.2 指针变量的定义、引用和初始化指针的指向指针指向非其定义时指明的数据类型,将引起warning;void*类型的指针可以指向任意类型的变量指针在初始化时一般为int *p=NULL;NULL表示空指针,即无效指针如果指针指向一个非你控制的内存空间,并对该空间进行访问(特别是写入操作),将可能造成危险(如何测试? ) 【exp9_danger.c】99.2 指针变量的声明、引用和初始化指针变量与其它类型变量的对比共性在内存中占据一定大小的存储单元先定义,后使用特殊性它的内容只能是地址,而不能是数据必须初始化后才能使用,否则指向不确定的存储单元只能指向同一基类型的变量可参与的运算

5、:加、减一个整数,自增、自减、关系、赋值109.3 指针的运算赋值运算指针在使用前一定要赋值为指针变量赋的值必须是一个地址(初始化、变量的地址、指针变量的值 等)void main() int *p; scanf(%d,p); void main() int a,*p=&a; scanf(%d,p); 错?111)一般并不直接把一个数赋予指针变量,故一般不使用下面的赋值:int *p;p=1000;2)被赋值的指针变量前不能再加“*”说明符,如写为*p=&a 也是错误的。 请严格区分指针变量的定义和引用的不同形式。定义: int a,*p=&a;引用: p=&a;129.3 指针的运算【例9-

6、1】利用指针求三个数中的最大值最小值。#include void main()int a, b, c, *pmax, *pmin;printf(“input three numbers:n”);scanf(“%d%d%d”, &a, &b, &c);if(ab)pmax = &a;pmin = &b;elsepmax = &b;pmin = &a;if(c*pmax) pmax = &c;if(c q p q p = q指针不与非指针量进行比较,但可与NULL进行等或不等的关系运算判断p是否为空指针if(p = NULL)if(p != NULL)【例9-2】16main() int a, b

7、; a = 15; b = 8; Swap(&a, &b); printf(a=%d,b=%d,a,b);void Swap(int *x, int *y) int temp; temp = *x; *x = *y; *y = temp;main() int a, b; a = 15; b = 8; Swap(a, b); printf(a:%d,b:%d,a,b);void Swap(int x, int y) int temp; temp = x; x = y; y = temp;【ex9_9.c】【ex9_611.c】例:编写函数实现两数的互换结果有何不同?17swap函数编写中容易出现

8、的问题(1/3)参数单向传递void Swap(int x, int y) int temp; temp = x; /*x,y为内部变量*/ x = y; y = temp;18swap函数编写中容易出现的问题(2/3)参数单向传递void Swap(int *p1, int *p2) int *p; p = p1; /* p1,p2为内部变量 */ p1 = p2; p2 = p; 19swap函数编写中容易出现的问题(3/3)指针p没有确切地址void Swap(int *p1, int *p2) int *p; /*指针p未初始化*/ *p = *p1; *p1 = *p2; *p2 =

9、 *p; 209.4 指针与数组作为函数的参数指针既然是数据类型,自然可以做函数的参数和返回值的类型指针做参数的经典例子,包括:两数的互换,使用函数来实现交换的过程数组名是所分配内存单元的首地址,可以作为函数的实参 。219.4.1 指针与一维数组 数组名是数组的首地址;(指针)它的值不能再被改变; (常量) 指针也可当作数组名使用 前提:int *p, a10; p = a;数组元素的几种等价引用形式ai*(a+i)pi*(p+i)229.4.1 指针与一维数组void main() int a10; int i; for (i=0; i10; i+) scanf(%d, &ai); for

10、 (i=0; i10; i+) printf(%d , ai); void main() int a10; int *p, i; for (p=a; p(a+10); p+) scanf(%d, p); for (p=a; p(a+10); p+) printf(%d , *p); 方法1:下标法方法2:指针法例:输入输出数组的全部元素239.4.2 指针与二维数组C语言将二维数组看作一维数组,其每个元素又是一个一维数组 a00 a0a01a02a10 a1 a11a12 a int a23;a &a0a+1 &a1a0 &a00a0+1 &a01a0+2 &a02a1 &a10a1+1 &a

11、11a1+2 &a12249.4.2 指针与二维数组int a34; a00 a01 a02 a03 a0 a0+1 a0+2 a0+3a0a0a1a2a+0 &a0a+1 &a1a+2 &a2a a10 a11 a12 a13 a1 a1+1 a1+2 a1+3a1 a20 a21 a22 a23 a2 a2+1 a2+2 a2+3a2259.4.2 指针与二维数组a&a0 代表二维数组的首地址,第0行的地址a+i&ai 代表第i行的地址*(a+i)ai &ai0 代表第i行第0列的地址*(a+i)+jai+j &aij &(*(a+i)j代表第i行第j列的地址*(*(a+i)+j)aij

12、*(ai + j) (*(a+i)j代表第i行第j列的元素269.4.2 指针与二维数组元素aij的地址的几种等价的引用方式&aij ai+j *(a+i)+j &(*(a+i)j元素aij的几种等价的引用方式aij *(ai+j) *(*(a+i)+j) (*(a+i)j279.4.2 指针与二维数组二维数组的列指针:每个二维元素的地址。int a34;int *p;p = &a00;相对于数组起始地址的偏移量i*m+jfor (i=0; in; i+)for (j=0; jm; j+) printf(%d,*(p+i*m+j);二维数组的行指针:每个一维元素的地址。(&a0 &a1 &a2

13、)int a34;int (*q)4;q = &a0;for (i=0; in; i+)for (j=0; jm; j+) printf(%d,*(*(p+i)+j);a00a01a02a03a10a11a12a13a20a21a22a23pp+1p=a0; p=*a;q = a;qq+1q+2数组的指针加一,越过一个数组。*(*(q+i) + j)*(p+i*m + j)aij289.6.1 指针数组元素均为指针类型数据的数组,称为指针数组 。定义形式为: 类型关键字 *数组名数组长度;例如: int a, b, c, d, e; int *p5; p0=&a; p1=&b; p2=&c;

14、p3=&d; p4=&e; 【例9-17】299.6.2 指向指针的指针 如果指针变量中保存的是另一个指针变量的地址,这样的指针变量就称为指向指针的指针定义形式: 类型关键字 *变量名; int i;int *p=&i;int *q=&p; *p i*q p *q *(*q) *p i 【例9-18】2008q200030002008p53000i309.4.2 指针与二维数组#define CLASS 3#define STUD 4void main() int scoreCLASSSTUD, i, j, maxScore, row, col;for(i = 0; iCLASS; i+) p

15、rintf(Please enter scores of class %d:n, i+1); for(j = 0; jSTUD; j+) scanf(%d, &scoreij); /*输入成绩*/maxScore = FindMax(*score, CLASS, STUD, &row, &col); printf(maxScore = %d, class = %d, number = %dn, maxScore, row+1, col+1); 例 :求最高分及其所在班级和学号319.4.2 指针与二维数组int FindMax(int *p, int m, int n, int *pRow,

16、int *pCol) int i, j, max;max = p0; *pRow = 0; *pCol = 0; for (i=0; im; i+)for (j = 0; j max) max = pi*n+j; *pRow = i; *pCol = j; return (max); 例 :求最高分及其所在班级和学号329.4.3 指针作为函数的参数任意给定某年某月某日,打印出它是这一年的第几天 已知某一年的第几天,计算它是该年的第几月第几日 int dayTab213 = 0,31,28,31,30,31,30,31,31,30,31,30,31, 0,31,29,31,30,31,30,3

17、1,31,30,31,30,31; 例:日期转换问题 33计算某年某月某日是这一年的第几天int DayofYear(int year, int month, int day) int i, leap; leap = (year % 4 = 0) & (year % 100 != 0) | (year % 400 = 0); for (i=1; idayTableapi; i+) yearDay = yearDay - dayTableapi; *pMonth = i; *pDay = yearDay; 35本章小结 指针的概念指针是一种特殊的数据类型永远要清楚每个指针指向了什么位置 永远要清

18、楚每个指针指向的位置中的内容是什么 指针与数组之间的关系掌握二维数组在内存中的存放方式,是理解二维数组的行指针和列指针的关键指针的应用做函数参数,传地址调用排序算法36作业1、输入3个数,用指针编程实现按从大到小输出。2、用指针和数组编程实现对一个4*3的矩阵实现转置操作。3、从键盘输入10个整数,用指针和函数编程实现计算最大值和最小值,并返回其在数组中的位置。4、用指向指针的指针的方法实现对10个数排序并输出。要求将排序功能用一个单独的函数来实现。37用起泡法对10个数排序【ex9_9.c】第1次, a1和a2比较9 8 5 4 2 0 6 1 3 7 8 9 5 4 2 0 6 1 3 7 8 5 9 4 2 0 6 1 3 7 8

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论