第 十 章 指 针.

Slides:



Advertisements
Similar presentations
第九章 指针 西安工程大学.
Advertisements

第七章 指针 计算机公共教学部.
第六章 指针 指针的概念 指针变量 指针与数组 指针与函数 返回指针值的函数.
第十章 指针 分析C程序的变量所存放的数据:  数值型数据:整数、实数  字符型数据:字符、字符串 这些变量具有以下性质:
第7章 指针 存储地址的变量的类型就是指针类型 能直接对内存地址操作, 实现动态存储管理 容易产生副作用, 初学者常会出错
第七章 指针 教 材: C程序设计导论 主 讲: 谭 成 予 武汉大学计算机学院.
二级指针与二维数组.
C语言程序设计基础 第10章 指针进阶 刘新国.
10.1 二级指针 10.2 指针与二维数组 10.3 指针的动态存储分配 10.4 函数指针 10.5 main函数的参数
第5章 指针 5.1 指针与指针变量 5.2 指针运算符 5.3 指针与一维数组 5.4 指向指针的指针 5.5 指针与结构
第 6 章 第 6 章 指 针 指 针 1.
第8章 指针 ● 8.1 指针简介 ● 8.2 指针变量的操作 ● 8.3 数组与指针 ● 8.4 二维数组与指针 ●本章小结 ●本章练习.
C语言基础——指针的高级应用 Week 05.
第6章 指针 6.1 指针的概念 6.2 变量与指针 6.3 数组与指针 6.4 字符串与指针 6.5 函数与指针 6.6 返回指针值的函数
6.4 字符串与指针 1. 用字符数组存放一个字符串.
第六节 二维数组和指针 二维数组的地址 对于一维数组: (1)数组名array表示数组的首地址, 即array[0]的地址;
8.1 指针的概念 8.2 指针变量 8.3 指针变量的基础类型 8.4 指针的运算 8.5 指针与一维数组 8.6 指针应用实例
C++中的声音处理 在传统Turbo C环境中,如果想用C语言控制电脑发声,可以用Sound函数。在VC6.6环境中如果想控制电脑发声则采用Beep函数。原型为: Beep(频率,持续时间) , 单位毫秒 暂停程序执行使用Sleep函数 Sleep(持续时间), 单位毫秒 引用这两个函数时,必须包含头文件
第九章 指针 目录 指针与指针变量的概念 变量的指针和指向变量的指针变量 数组的指针和指向数组的指针变量
程序设计基础.
第6章 指针 学习目的与要求: 了解指针的概念和相关术语 熟练掌握指向变量、数组和字符串的指针变量的使用方法 了解指向函数的指针变量
指 针 为什么要使用指针 指针变量 指针与数组 返回指针值的函数 动态内存分配 通过指针引用字符串 指向函数的指针 小 结 习 题.
第一章 C语言概述.
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
第八章 指 针 8.1 指针的概念与定义 8.2 指针作函数参数 8.3 指针与数组 8.4 指针与函数 8.5 复杂指针.
项目六 用指针优化学生成绩排名 项目要求 项目分析
C语言高级编程(第四部分) 字符串 北京大学 信息科学技术学院.
Chap 8 指针 8.1 寻找保险箱密码 8.2 狸猫换太子 8.3 冒泡排序 8.4 加密变换问题 8.5 任意个整数求和问题*
程序设计基础 第 八 章 谌 卫 军 清华大学软件学院 2008年秋季.
第8章 善于利用指针 8.1 指针是什么 8.2 指针变量 8.3 通过指针引用数组 8.4 通过指针引用字符串 8.5 指向函数的指针
二维数组的指针表示 与复杂的指针例子 专题研讨课之三.
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
第8章 指针.
第六章 指针 指针的概念 指针的运算 指向变量的指针 指向数组的指针 指向函数的指针 二级指针 主讲:李祥 时间:2015年10月.
第八章 使用指针.
第十章 指针.
欲穷千里,更上层楼 第十章 指 针 指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构; 能很方便地使用数组和字符串; 并能象汇编语言一样处理内存地址,从而编出精练而高效的程序。指针极大地丰富了C语言的功能。 学习指针是学习C语言中最重要的一环,
第五章 习题课 电子信息与计算机科学系 曾庆尚.
C++大学基础教程 第6章 指针和引用 北京科技大学 信息基础科学系.
第五章 指针 5.1 指针的概念 5.2 指针与数组 5.3 字符串指针.
9.1 地址、指针和变量 9.2 指针运算 9.3 指针与数组 9.4 函数与指针 9.5 程序综合举例 9.6 上机实训.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
《概率论》总复习.
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
C语言复习3----指针.
C语言大学实用教程 第7章 指针 西南财经大学经济信息工程学院 刘家芬
第二章 Java基本语法 讲师:复凡.
指针 几个概念:  指针也是一种数据类型,具有指针类型的变量,称为指针变量。
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
第6讲 指针与引用 6.1 指针 6.2 引用.
C语言程序设计 第一章 数据类型, 运算符与表达式 第二章 顺序程序设计 第三章 选择结构程序设计 第四章 循环控制 第五章 数组.
第六章 指针 C++程序设计中使用指针可以: 使程序简洁、紧凑、高效 有效地表示复杂的数据结构 动态分配内存 得到多于一个的函数返回值.
第6章 指针 6.1 指针的概念 6.2 变量与指针 6.3 数组与指针 6.4 字符串与指针 6.5 函数与指针 6.6 返回指针值的函数
第十章 指针 指针是C语言的重要概念,是C语言的特色,是C语言的精华。 10.1 地址和指针的概念 内存中的每一个字节都有一个地址。
第4章 Excel电子表格制作软件 4.4 函数(一).
第九节 赋值运算符和赋值表达式.
3.16 枚举算法及其程序实现 ——数组的作用.
第8章 善于利用指针 8.1 指针是什么 8.2 指针变量 8.3 通过指针引用数组 8.4 通过指针引用字符串 8.5 指向函数的指针
第二章 基本数据类型 ——数据的表示.
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
C程序设计.
C程序设计 实验二 数据类型、运算符和表达式 第6讲
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
C语言程序设计 第8章 指针.
第七章 指针 指针与指针变量 指针与数组 指针与函数 指针与字符串.
第九章 指针 C程序设计中使用指针可以: 使程序简洁、紧凑、高效 有效地表示复杂的数据结构 动态分配内存 得到多于一个的函数返回值.
第八章 指 针 北京邮电大学出版社.
第7章 地址和指针 7.1 地址和指针的概念 7.2 指针变量的定义和指针变量的基类型 7.3 给指针变量赋值 7.4 对指针变量的操作
Presentation transcript:

第 十 章 指 针

§10.1 指针的概念 内存区域被划分成一个一个的内存单元,一个内存单元可 一、内存单元的内容和内存单元的地址: 以存放一个字节的数据,每一个内存单元都有一个编号,统称 为地址。 例:int i=3; char j=‘s’; 地址 内存单元 3 2000 2001 2002 2004 3000 变量i 变量j 编译时为变量i分配2000和2001两 个字节的内存单元,为j分配2003 一个字节的内存单元 2003 75 因为内存单元的地址就是“指向”了该内存单元,故通常把内存单元的地址称为指针。

二.内存单元的访问: j 直接访问:通过变量名访问。 char j=‘s’; printf(“%c”, j ); 间接访问:通过该变量的指针来访问。 p=&j; 称:指针变量p指向变量j,p是变量j的指针。 j 2000 75 p j 2000 75

变量的指针:是一个变量的地址, 是常量。 指针变量:是存放变量地址的变量,其 值是该变量的地址。 要引用指针,必须定义指针。 定义指针,是为了通过指针访问内存单元。 一个数组或函数占有一段连续内存单元,假如将一个数组或函数的首地址赋给指针变量,通过指针就可以找到该数组或函数。

一、指针变量的定义 §10.2 变量的指针 类型标识符 * 标识符 例如:int *p “标识符”是指针变量名。 如 p §10.2 变量的指针 一、指针变量的定义 类型标识符 * 标识符 例如:int *p “标识符”是指针变量名。 如 p “*”表示定义指针变量 “类型标识符”表示该指针变量所指向的变量类型。 指针指向一个变量的地址,用*表示指向。

二、指针变量的引用 &: 取地址运算符 *: 取内容运算符 *和 &的优先级相同。 例: int a=5,b; int *p; p=&a; 指针变量只能存放地址。 未经赋值的指针变量不能用。 C语言提供两种相关地址运算符: &: 取地址运算符 *: 取内容运算符 *和 &的优先级相同。 例: int a=5,b; int *p; p=&a; b=*p; p a , b 2000 5 2002 ... ... 3000 2000 &a 类型说明中的*表示 定义指针变量 &a 5 p a 表达式中的*是运算符 *p表示p指向地址里的值

三、指针变量的赋值: (1)、int a,*pa; pa=&a; (2)、int a=5,*p=&a; (3)、int a,*pa=&a,*pb; pb=pa; (4)、int a[5],*pa; pa=a; (5)、char *pc; pc=“c language”; /*整型变量a的地址赋给指针变量pa*/ /*指针变量p取得整型变量a的地址.*/ /*指针pa的值赋给指针pb*/ /*将数组a的首地址赋给相同类型的指针pa*/ /*将字符串的首地址赋给指针变量*/

int *pointer_1, *pointer_2; /* 定义指针变量 */ a = 100; b = 10; [例10.1] main () { int a,b; int *pointer_1, *pointer_2; /* 定义指针变量 */ a = 100; b = 10; pointer_1 = &a; pointer_2 = &b; printf("%d,%d\n", a,b ); printf("%d,%d\n", *pointer_1,*pointer_2 ); } 程序运行结果: pointer-1 a &a 100 100,10 b pointer-2 &b 10

[例10.2] 输入a和b两个整数,按先大后小的顺序输出a和b。 main () { int *p1, *p2, *p , a, b; scanf("%d,%d",&a,&b); p1 = &a; p2 = &b; if (a < b) { p = p1; p1 = p2; p2 = p; } printf("a=%d,b=%d\n",a,b); printf("max=%d,min=%d\n", *p1, *p2 ); } 运行:5,9 p1 a p &a 5 &b p2 b &b 9 &a a=5,b=9; max=9,min=5 该例不交换变量a、b的值,而是交换指针p1、p2的值。

四、指针变量作为函数的参数 if (a<b) swap(pointer_1, pointer_2) ; [例10.3] 题目要求同[例10.2],输入a和b两个整数,按先大后小的顺序输出a和b。 swap( int* p1,int *p2 ) /*交换指针p1、p2所指向的变量的值 */ { int p; p = *p1; *p1 = *p2; *p2 = p; } main () { int a, b; int *pointer_1, *pointer_2; scanf("%d,%d",&a,&b); pointer_1 = &a; pointer_2 = &b; if (a<b) swap(pointer_1, pointer_2) ; printf("\n%d,%d\n",a,b); 把变量a和b的地址传送给形参

§10.3 数组的指针 指针可以指向数组和数组元素,对数组元素的访问: 既可以使用数组下标,也可以使用指针。 一、指向数组元素的指针变量 指向数组元素的指针变量,其类型应与数组元素相 同。例1: int a[7]; int *p; p=&a[0]; 或 p=a; 例2: float b[10],*p=b ; 或 float b[10],p=&b[0]; 1 2 3 4 5 6 7 &a[0] p a[0] a[6] /*指的是把数组a的首地址赋给指针p*/

如果数组元素是整型,p+1表示p的地址加2; 如果数组元素是实型,p+1表示p的地址加4; 二、通过指针引用数组元素 设:int a[10],*p=&a[0]; (1).p+1和a+1都是指向下一个元素a[1]; 如果数组元素是整型,p+1表示p的地址加2; 如果数组元素是实型,p+1表示p的地址加4; a表示数组首地址。 p+i 和a+i 指向元素a[i]。 (2).*(p+i) 访问元素a[i]; 例: *(p+5)和*(a+5) 与a[5]等效; (3).指向数组指针可以带下标: 例: p[i]与*(p+i)等效.

[例10.5] 输出数组的全部元素。(设10个整数) 1、下标法 main () { int a[10]; int i; for(i=0;i<10;i++) scanf("%d", &a[i]); printf("\n"); printf("%d ", a[i] ); } 特点:常用、过程简单直观

2、用数组名计算数组元素的地址。 main( ) { int a[10]; int i; for(i=0;i<10;i++) scanf("%d", &a[i]); printf("\n"); printf("%d ", *(a+i) ); } 特点:不移动指针 但要计算每个元素的地址 费时间

for( p=a ; p<(a+10) ; p++ ) printf("%d ", *p ); } 3、用指针访问各元素。 main () { int a[10]; int *p , i; for(i=0;i<10;i++) scanf("%d", &a[i]); printf("\n"); for( p=a ; p<(a+10) ; p++ ) /* p++使p指向下一个元素 */ printf("%d ", *p ); } 特点:移动指针 速度快

??试问:以上程序可以输出a数组中的 例:通过以下程序输出a数组中的10个元素。 main() { int a[10],*p,i; p=a; for(i=0;i<10;i++) scanf("%d",p++); printf("\n"); for(i=0;i<10;i++,p++) printf("%d\t",*p); } ??试问:以上程序可以输出a数组中的 10个元素吗?

三、数组名作函数参数 1、形参和实参都用数组名 main() { int array[10]; … f( array ,10); } f( int arr[],int n) { … }

2、实参用数组名,形参用指针变量。 main() { int array[10]; … f(array ,10); } f( int *arr,int n) { … }

3、实参、形参都用指针变量。 main() f( int *arr,int n) { { … p=array; … } f(p,10); } int array[10],*p; p=array; … f(p,10); } f( int *arr,int n) { … }

4、实参用指针变量,形参用数组名。 main() f( int arr[ ],int n) { { … p=array; … } int array[10],*p; p=array; … f(p,10); } f( int arr[ ],int n) { … }

§10.4 字符串的指针 一、字符串的表现形式 C语言中,有两种方式可以实现字符串: 字符数组、字符指针。 [例10.16]:字符数组 main() { char string[ ] ={“How are you!”}; printf("%s\n",string); } 用字符串对字符数组赋值 string是数组名,代表字符数组的首地址。 数组可以用下标访问,也可以用指针访问

printf("%10s%10s\n",name1,name2); } [例10.17]字符指针 main() { char *name1 =”Mary"; char *name2=“Hare”;  printf("%10s%10s\n",name1,name2); } name1、name2是指针变量 name1 name2 Mary Hare char *name1 =“Mary”; 等价于: char * name1; name1 = “Mary”; 它把字符串常量的首地址赋给指针name1.

特点:不移动指针 [例10.18] 将字符串a复制到字符串b。 main () { char a[ ] = "I am a boy."; char b[20]; int i; for (i=0; *(a+i) !='\0'; i++) *(b+i) = *(a+i); *(b+i) = '\0'; printf("string a is: %s\n",a); printf("string b is:"); for (i=0; b[i] !='\0'; i++) printf("%c",b[i]); printf("\n"); } 用数组名计算数组元素的地址 I a m 数组a b o y . \0 数组b b 特点:不移动指针

特点:移动指针 [例10.19]:用指针处理字串复制. 数组a 数组b main () p1 p2 o y . \0 数组b p2 main () { char a[ ] = "I am a boy.",b[20],*p1,*p2; int i; p1=a;p2=b; for ( ; *p1 !='\0'; p1++,p2++) *p2 = *p1; *p2 = '\0'; printf("string a is: %s\n",a); printf("string b is:"); for (i=0; b[i] !='\0'; i++) printf("%c",b[i]); printf("\n"); } 特点:移动指针

(a+7)是用指针指向数组元素a[i]的第7个字符 例10.21: main() { char *a=“I love china!”; a=a+7; printf(“%s”,a); } 运行结果如下: China! (a+7)是用指针指向数组元素a[i]的第7个字符

可以看到: 1、字符数组和字符指针的概念不同。 2、字符指针指向字符串,而C语言中, 字符串按数组方式处理,因此,字符指 针和字符数组的访问方式相同。

§10.5 函数指针 一、用函数指针变量调用函数 函数指针定义的一般形式: 函数返回值类型(*指针变量名)( ) §10.5 函数指针 一、用函数指针变量调用函数 函数指针定义的一般形式: 函数返回值类型(*指针变量名)( ) 例: int (*p)( ) 说明:(*p)( ) 表示定义一个指向函数的指针变量, 它不固定指向哪一个函数,它是专门用来存放函数的入口 地址的,该函数返回一个整型值。 C规定:函数的名称就就代表函数的入口地址。

int max(int x, int y); /*原型*/ {int z; if (x>y) z = x; else z = y; [例9.23] 求a和b中的大者。 用函数名调用子函数max() int max(int x, int y); /*原型*/ {int z; if (x>y) z = x; else z = y; return z; } main () {int a,b,c; scanf("%d,%d", &a, &b); c = max(a, b); printf("a=%d,b=%d,max=%d",a,b,c);

用函数指针变量调用函数时,只须将(*p)代替函数名max,并加上实参 [例9.23] 求a和b中的大者。 用函数指针调用函数max() int max(int x, int y) /*原型*/ {int z; if (x>y) z = x; else z = y; return z;} main () { int (*p) (int, int); /*定义函数指针p */ int a,b,c; p = max; /*函数max的入口地址赋给函数指针p*/ scanf("%d,%d", &a, &b); c = (*p)(a,b); /*用函数指针p调用函数 */ printf("a=%d,b=%d,max=%d",a,b,c); } 用函数指针变量调用函数时,只须将(*p)代替函数名max,并加上实参

§10.6 返回指针的函数 (自学) 一般形式: 类型标识符 * 函数名(参数表) 例、 int * a (int x, int y)   类型标识符 * 函数名(参数表) 例、  int * a (int x, int y) 声明一个函数,函数名为a,其返回值类型是“指向整型 的指针”, 函数形式参数为int x 和 int y。 注意:在a的两侧分别为*运算符和( )运算符,a先与( ) 结合,这是函数形式;函数前有个*号,表示该函数为指针 型函数.

§10.7 指针数组和指向指针的指针 (自学) 一、指针数组 概念:指针数组是一个数组,该数组中的 每一个元素均是指针变量。 形式:类型标识符 *数组名[数组元素个数] 例: int * p[4];   定义一个指针数组,数组名p,有4个元素, 每一个元 素是指向整型变量的指针。如: char *name[3]={”math”,”computer”,”ccm”}; 可用 puts(name[i]) 语句输出。

p 二、指向指针的指针 定义举例: char * * p; char *name[]={“Ann”,“Hare”,“Jack”}; p=name; p是一个指向指针的指针。 被p指向的指针指向字符变量。 name指针数组 二维字符数组 p name[0] name[1] name[2] Ann Hare Jack

程序举例: main() { int i; char *name[]={"Ann","Hare","Jack","Mary"}; char **p; printf("\n Students's names are:\n"); for(i=0;i<4;i++) { p=name+i; printf("%6s\t",*p); } 运行结果: Ann Hare Jack Mary name指针数组 二维字符数组 p name[0] name[1] name[2] Ann Hare Jack name[3] mary

§10.8 指针使用小结 一、有关指针的数据类型 定义: int i; 定义整型变量i int *p; p是指向整型数据的指针变量 §10.8 指针使用小结 一、有关指针的数据类型 定义: int i; 定义整型变量i int *p; p是指向整型数据的指针变量 int a[n]; 定义数组a,元素类型为int,元素个数是n int *p[n]; p是指针数组,包含n个指针,每一个指针可 以指向整型数据 int f(); f是函数,返回值是int int (*p)(); p是函数指针,所指向的函数返回整型数据 int *p(); p是函数,返回值是指针,该指针指向整型数据 int **p; p是指针,指向一个指向整型数据的指针

二、指针运算小结 1、指针变量加/减运算 2、指针变量赋值 p++、p--、p+i、p-i、p+=i、p-=i 加1表示指向下一个数据。    加1表示指向下一个数据。 2、指针变量赋值  p = &a; 变量a的地址赋给p,即指针p指向a  p = array; 数组array首地址赋给p  p = &array[i]; 数组元素array[i]的地址赋给p  p = max; 函数max的入口地址赋给p  p1 = p2; 指针p2的值赋给指针p1, 即p1、p2所指的数据相同 p=NULL; 指针变量可以由空值,NULL的值为0

3、空指针 p = NULL 空指针p=NULL表示p不指向任何数据。 在stdio.h中,NULL被定义为0:     #define NULL 0 习惯上,不使用 p = 0而使用 p = NULL 指针变量p可以与NULL作比较, 例: if (p = = NULL) ... 注意:空指针不指向任何数据,与p未赋值不同。 当p未赋值时,其值是不确定的,而空指针 的值是确定数0。

4、指针变量相减 当p1、p2指向同一个数组的元素,指针相减p2-p1等于p1、p2间的元素个数。 注意:指针相加无意义。 5、两个指针的比较 当p1、p2指向同一个数组的元素时可以比较,如:p1 > p2。表示p1在p2之后。若p1、p2不是指向 同一个数组的元素,比较无意义。

三、空类型指针 void 例、 char *p1; void *p2; p1 = (char *)p2; p2 = (void *)p1; 空类型指针与其他类型指针之间赋值时,应进行强制类型转换, 例、  char *p1;     void *p2;     p1 = (char *)p2;     p2 = (void *)p1;

第10 章 课堂练习 10.1 指针变量a所指的字符串长度为 , 这个长度是可以用strlen(a)测出来的。 第10 章 课堂练习 10.1 指针变量a所指的字符串长度为 , 这个长度是可以用strlen(a)测出来的。 char *a=“\nMY Name is\”zhang li\”.\n”; (1)26 (2) 27 (3) 28 (4) 24 (5) 23 10.2 下面程序的作用是: 将两个变量中的值互换, 请检查程序是否正确,如不正确的,改正之。 main ( ) { int a=3,b=4; int *p1,*p2,*p; p1=&a;p2=&b; p=p1;p1=p2;p2=p; printf(“a= %d,b= %d\n”,a,b); }

第10 章 课堂练习 10.3已知p1和p2为指针变量, 且已指向同一个整 型数组中的元素,a是一个整型变量,问下面 第10 章 课堂练习 10.3已知p1和p2为指针变量, 且已指向同一个整 型数组中的元素,a是一个整型变量,问下面 哪一个语句不能正确执行? (1) a=*p1 (2) a=*p1+*p2 (3) a=*p1-*p2 (4) p1=a-p2 10.4 有一个二维数组a[3][4],第2行第3列元素的正 确表示方法为 。 (1) &a[2][3] (2)a[2]+3 (3) *(a+2)+3 (4)*(a[2]+3) 10.5 指向一个包含4个整型元素的一维数组的指针 变量的定义形式为: (1) int (*p)[4] (2) int *p[4] (3) int * (p[4]) (4) int (*p)[ ]

第10 章 课堂练习 10.6 若有语句:int a=4,*p=&a; 下面均代表地址的一组选项的是: 第10 章 课堂练习 10.6 若有语句:int a=4,*p=&a; 下面均代表地址的一组选项的是: 1) a,p,&*a 2) *&a,&a,*p 3) &a,p,&*p 4) *&p,*p,&a 10.7 以下程序段的输出结果为: char a[]=“Program”,*ptr; ptr =a; for ( ;ptr<a+7;ptr+=2) putchar(*ptr); 1) Program 2) Porm 3) 有语法错误; 4) Por