C语言基础——指针的高级应用 Week 05.

Slides:



Advertisements
Similar presentations
《C语言程序设计》复习
Advertisements

第六章 指针 指针的概念 指针变量 指针与数组 指针与函数 返回指针值的函数.
电子成绩单项目实现.
Loops.
C语言程序设计教程 单位:德州学院计算机系.
第8章 指针 ● 8.1 指针简介 ● 8.2 指针变量的操作 ● 8.3 数组与指针 ● 8.4 二维数组与指针 ●本章小结 ●本章练习.
第六节 二维数组和指针 二维数组的地址 对于一维数组: (1)数组名array表示数组的首地址, 即array[0]的地址;
专题研讨课二: 数组在解决复杂问题中的作用
第九章 指针 目录 指针与指针变量的概念 变量的指针和指向变量的指针变量 数组的指针和指向数组的指针变量
第九章 系 统 安 全 性 9.1 结构体 9.2 结构体型数组  9.3 结构体型指针 9.4 内存的动态分配 9.5 共用体
第7章 结构体、联合体和枚举类型 本章导读 本章主要知识点 《 C语言程序设计》 (Visual C++ 6.0环境)
C语言程序设计 第十二章 位运算.
第5章 函数与模块化设计 学习目的与要求: 掌握函数的定义及调用方法 理解并掌握参数的传递方法 理解函数的嵌套与递归调用
复习与总结.
程序设计基础.
第六章 数 组 主讲教师 贾月乐 联系电话:
C语言程序设计 课程 第5章 数组 主讲:李祥 博士、副教授 单位:软件学院软件工程系.
循环结构又称为重复结构:用来处理需要重复处理的问题,它是程序中一种很重要的结构。
選擇排序法 通訊一甲 B 楊穎穆.
补充内容 结构体 概述 定义结构体类型和定义结构体变量 结构体变量的引用 结构体变量的初始化 指针与结构体 用typedef定义类型的别名.
Introduction to the C Programming Language
排序 Sorting.
目录 10.1 指针的基本概念 10.2 指向变量的指针变量 10.3 指向数组的指针变量 10.4 指向函数的指针变量和指针型函数
第4章 选择结构程序设计 4.1 选择结构和条件判断 4.2 用if语句实现选择结构 4.3关系运算符和关系表达式
项目六 用指针优化学生成绩排名 项目要求 项目分析
程序讲解 第一题: 将指定文件的m行到n行字符写到显示屏上,m和n值从键盘输入。 运行时输入及结果: please enter m,n:
Introduction to the C Programming Language
Introduction to the C Programming Language
目录 第八章 数组 1 简单学生成绩管理系统的开发 2 一维数组 3 多维数组 4 字符数组 5 数组作函数参数.
计算概论 第十八讲 C语言高级编程 结构与习题课 北京大学信息学院.
Introduction to the C Programming Language
Chap 8 指针 8.1 寻找保险箱密码 8.2 角色互换 8.3 冒泡排序 8.4 电码加密 8.5 任意个整数求和*
C语言程序设计 李祥.
第八章 函数.
第8章 善于利用指针 8.1 指针是什么 8.2 指针变量 8.3 通过指针引用数组 8.4 通过指针引用字符串 8.5 指向函数的指针
第7章 编译预处理 本章要求: 本章重点: 本章难点: 掌握用#define定义无参数宏和带有参数宏定义和调用方法;
第五章 指针 5.1 指针的概念和定义 5.2 指针运算 5.3 指针和数组 5.4 字符串指针 5.5 指针数组 5.6 指向指针的指针
6.4.1指针与二维数组 1、二维数组结构的分析 设有数组定义为:int a[3][4]; 则有: a表示数组在内存中的首地址。
C语言 程序设计基础与试验 刘新国、2012年秋.
多维数组与指针 用指针变量可以指向一维数组中的元素,也可以指向多维数组中的元素。但在概念上和使用上,多维数组的指针比一维数组的指针要复杂一些。 1. 多维数组元素的地址 先回顾多维数组的性质,可以认为二维数组是“数组的数组”,例 : 定义int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};
第13章 结构体的应用 13.1 了解由用户构造的数据类型 13.2 结构体类型说明及结构体变量 13.3 结构体数组
第八章 使用指针.
第十章 指针.
数组 梁春燕 华电信息管理教研室.
C语言概述 第一章.
資料結構與C++程式設計進階 排序與搜尋 講師:林業峻 CSIE, NTU 6/ 14, 2010.
C语言复习3----指针.
C语言大学实用教程 第6章 数组 西南财经大学经济信息工程学院 刘家芬
函数 概述 模块化程序设计 基本思想:将一个大的程序按功能分割成一些小模块, 特点: 开发方法: 自上向下,逐步分解,分而治之
第八章 指標 (Pointer).
C语言的特点 1. C程序由许多函数组成 2. C程序必须有且只有一个主函数main( ) 3. 函数用“{”和“}”表示起点和终点
第六章 指针 C++程序设计中使用指针可以: 使程序简洁、紧凑、高效 有效地表示复杂的数据结构 动态分配内存 得到多于一个的函数返回值.
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
7.1 C程序的结构 7.2 作用域和作用域规则 7.3 存储属性和生存期 7.4 变量的初始化
第十章 指针 指针是C语言的重要概念,是C语言的特色,是C语言的精华。 10.1 地址和指针的概念 内存中的每一个字节都有一个地址。
本节内容 字符与字符串 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C语言程序设计 李祥 QQ:
第九章 指针.
第二章 类型、对象、运算符和表达式.
C程序设计.
本节内容 指针类型.
第七章  数 组.
Chap 7 数 组 7.1 排序问题 7.2 找出矩阵中最大值所在的位置 7.3 进制转换.
第九章 指针 C程序设计中使用指针可以: 使程序简洁、紧凑、高效 有效地表示复杂的数据结构 动态分配内存 得到多于一个的函数返回值.
C/C++基礎程式設計班 陣列 講師:林業峻 CSIE, NTU 3/14, 2015.
第9章 C++程序设计初步 9.1 C++的特点 9.2 最简单的C++程序 9.3 C++的输入输出 9.4 函数的重载
第六章 复合数据类型 指针的声明与使用 数组的声明与使用 指针与数组的相互引用 字符串及相关库函数 new与delete
本节内容 指针类型 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C语言基础学习 从外行到入门.
C++语言程序设计 C++语言程序设计 第二章 基本数据类型与表达式 第十一组 C++语言程序设计.
Presentation transcript:

C语言基础——指针的高级应用 Week 05

内容指要 指针内容复习 指针与多维数组 指针数组 多级指针 *函数指针

Max=100,min=-3 指针 运行结果: enter 10 integer numbers -2 4 6 8 0 -3 45 67 89 100  the 10 integer numbers: -2 4 6 8 0 -3 45 67 89 100 Max=100,min=-3 指针 void main() { int i,number[10],*p; p=number; printf("enter 10 integer numbers:\n"); for(i=0;i<10;i++,p++) scanf("%d",p); printf("the 10 integer numbers:\n"); for(p=number,i=0;i<10;i++,p++) printf("%d ",*p); max_min_value(p,10); printf("\nmax=%d,min=%d\n",max,min); } int max,min; void max_min_value(int *array, int n) { int *p,*array_end; array_end=array+n; max=min=*array; for(p=array+1;p<array_end;p++) if(*p>max) max=*p; else if(*p<min) min=*p; return; }

指针 void copy_string(char *from,char *to) { for(;*to++=*from++;); } void main() { char a[]="I am a teacher."; char b[]="You are a student."; printf("string_a=%s\nstring_b=%s\n",a,b); copy_string(a,b); printf("\nstring_a=%s\nstring_b=%s\n",a,b); }

指针与多维数组 由于多维数组使用较少,且使用方法可以由一维和二维的关 系推得,因此这里主要讲的是指针与二维数组的关系 二维数组可以看作是n个相同数据类型的一维数组的集合,而 每个一维数组数组名是一个静态指针,因此二维数组也可看 做是n个相同类型的静态指针的集合,而二维数组名就是n个 静态指针中第一个指针的地址 例:定义二维数组: int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}}; 该二维数组由三个一维int型数组组成,且三个int数组的头地址分别是 a[0],a[1],a[2],因此a[0]==&a[0][0],a[1]==&a[1][0], a[2]==&a[2][0] 以上结论可得,二维数组名也就是a本质上是a[0]的地址,也就是一个 指针的地址,因此*a取出的值是a[0],依然是一个地址

指针与二维数组 a 因此可以很清楚的得到,当我们在对a进行运算的时候,其偏移 的单位不再是int,而是其元素值,也就是数组的长度,也就是 1 3 5 7 9 11 13 15 17 19 21 23 a[0] a[1] a[2] = 因此可以很清楚的得到,当我们在对a进行运算的时候,其偏移 的单位不再是int,而是其元素值,也就是数组的长度,也就是 说当a+1时,a+1不是指向了矩阵中第二个元素3,而是直接指向了 二维数组的第二个元素,也就是数组a[1],a+2时,也不会指向第 三个元素5,而是直接指向了第三个数组a[2]。 在对二维数组名使用了取值运算符*后,提取出的是第一个数组, 也就是其首地址,此时再进行加法运算(*a)+1,此时指针指向的就 是数组a[0]当中的第二个元素a[0][1]

指针与二维数组 a[0]+0 a[0]+1 a[0]+2 a[0]+3 *(a+0)+0 *(a+0)+1 *(a+0)+2 2000 a[0][0] 2004 a[0][1] 2008 a[0][2] 200C a[0][3] a[1]+0 a[1]+1 a[1]+2 a[1]+3 *(a+1)+2 *(a+1)+0 *(a+1)+1 *(a+1)+3 a+1 2010 a[1][0] 2014 a[1][1] 2018 a[1][2] 201C a[1][3]

指针与二维数组 a[2]+0 a[2]+2 a[2]+1 a[2]+3 *(a+2)+2 *(a+2)+3 *(a+2)+1 2020 a[2][0] 2024 a[2][1] 2028 a[2][2] 202C a[2][3]

指针与二维数组 由于增加了一个维度,在操作上会有很多的层次嵌套问题, 因此必须清楚常见的二维数组操作表达式代表的意思 例:对二维数组 int a[3][4],有 a-----二维数组的首地址,即第0行的首地址 a+i-----第i行的首地址 a[i] ↔ *(a+i)------第i行第0列的元素地址 a[i]+j ↔ *(a+i)+j -----第i行第j列的元素地址 *(a[i]+j) ↔ *(*(a+i)+j) ↔ a[i][j]

指针与二维数组 例:输出二维数组相关的值 #define FORMAT "%d,%d\n" void main() {int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}; printf(FORMAT,a,*a); printf(FORMAT,a[0],*(a+0)); printf(FORMAT,&a[0],&a[0][0]); printf(FORMAT,a[1],a+1); printf(FORMAT,&a[1][0],*(a+1)+0); printf(FORMAT,a[2],*(a+2)); printf(FORMAT,&a[2],a+2); printf(FORMAT,a[1][0],*(*(a+1)+0)); }

指针与二维数组 之前所提到的,都是在二维数组名这个静态指针上面进行的 指针操作,并没有真的定义一个指针变量来存储二维数组。 由于二维数组是一维数组的集合,因此使用指针来定义二维 数组和一维数组的指针定义一样——通过一个指针来指向第 一个元素,也就是第一个数组,所以只需要将数组第一维改 成指针形式即可 定义形式: 数据类型 (*指针名)[一维数组维数]; 例 int (*p)[4];定义了指向包含4个整型元素的一维数组 注:切记不能忘记括号,由于只是将第一维改变为指针形式, 如果不写括号就会变成指针数组的定义方式,二者完全不同

指针与二维数组 void main() {int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}; int (*p)[4],i,j; p=a; scanf("i=%d,j=%d",&i,&j); printf("a[%d,%d]=%d\n",i,j,*(*(p+i)+j)); } 运行结果: i=1,j=2 a[1][2]=13

指针与二维数组 例:3个学生各4门课,计算总平均分,并输出第n个学生成绩 void average(float *p,int n); void search(float (*p)[4],int n); void main( ) {float score[3][4]={{65,67,79,60},{80,87,90,81},{90,99,100,98}}; average(*score,12); search(score,2); } void average(float *p,int n) { float *p_end, sum=0,aver; p_end=p+n-1; for(;p<=p_end;p++) sum=sum+(*p); aver=sum/n; printf("average=%5.2f\n",aver); } void search(float (*p)[4], int n) { int i; printf(" No.%d :\n",n); for(i=0;i<4;i++) printf("%5.2f ",*(*(p+n)+i)); } 运行结果: Average=82.25 90.00 99.00 100.00 98.00

指针与二维数组 运行结果: No.1fails,his scores are: 65.0 57.0 70.0 60.0 例 3个学生各学4门课,查找一门以上课程不及格学生, 输出其各门 课程的成绩 void search(float (*p)[4], int n) { int i,j,flag; for(j=0;j<n;j++) { flag=0; for(i=0;i<4;i++) if(*(*(p+j)+i)<60) flag=1; if(flag==1) { printf("No.%d is fail,his scores are:\n",j+1); printf("%5.1f ",*(*(p+j)+i)); printf("\n"); } void search(float (*p)[4], int n); void main() {float score[3][4]={{...},{...},{...}}; search(score,3); 运行结果: No.1fails,his scores are: 65.0 57.0 70.0 60.0 No.2fails,his scores are: 58.0 87.0 90.0 81.0

指针数组 数组可以用来存放任何数据类型的集合,因此也可以用于存 放指针类型。通常,指针数组是用来存放多个字符串的 指针数组 定义:数组中的元素为指针变量 定义形式:[存储类型] 数据类型 *数组名[数组长度]; 例 int *p[4]; //注意与二维数组指针形式的区别 指针数组的赋值与初始化 赋值: void main() { int b[2][3],*pb[2]; pb[0]=b[0]; pb[1]=b[1]; …….. } 初始化: void main() { int b[2][3],*pb[ ]={b[0],b[1]}; …….. }

指针数组 int *pb[2] pb[0] pb[1] int b[2][3] 1 2 3 4 6

指针数组 赋值: 或: 初始化: void main() void main() { char a[]="Fortran"; L i s p \0 F o r t r a n \0 B a s i c \0 p[0] p[1] p[2] p[3] 赋值: void main() { char a[]="Fortran"; char b[]="Lisp"; char c[]="Basic"; char *p[4]; p[0]=a; p[1]=b; p[2]=c; p[3]=NULL; …….. } 或: { char *p[4]; p[0]= "Fortran"; p[1]= "Lisp"; p[2]= "Basic"; p[3]=NULL; 初始化: void main() { char *p[]={"Fortran", "Lisp", "Basic",NULL}; …….. } L i s p \0 F o r t r a n \0 B a s i c \0 p[0] p[1] p[2] p[3]

指针数组 通常,指针数组用来存放多个字符串信息,与用二维数组相 比,指针数组有着很大的优势,因为二维数组存放的数组长 度必须是相同的,在用来存放许多长度不相同的字符串的时 候就会出现空间的浪费——因为必须要用这些字符串当中最 长的字符串来定义二维数组中存放的数组长度 例: char name[5][9]={“gain”,“much”,“stronger”, “point”,“bye”}; g a i n \0 s t r o n g e r \0 p o i n t \0 m u c h \0 name[0] name[1] name[2] name[3] name[4] b y e \0 g a i n \0 s t r o n g e r \0 p o i n t \0 m u c h \0 b y e \0 char *name[5]={“gain”,“much”,“stronger”, “point”,“bye”};

指针数组 例:对字符串由小到大排序(简单选择排序)

指针数组 void sort(char *name[],int n); void print(char *name[],int n); void main() { char *name[]={"Follow me","BASIC", "Great Wall","FORTRAN","Computer "}; int n=5; sort(name,n); print(name,n); } void sort(char *name[],int n) { char *temp; int i,j,k; for(i=0;i<n-1;i++) { k=i; for(j=i+1;j<n;j++) if(strcmp(name[k],name[j])>0) k=j; if(k!=i) { temp=name[i]; name[i]=name[k]; name[k]=temp;}

指针数组 k k j j j j i=0 name name[0] Follow me BASIC name[1] name[2] Great Wall FORTRAN Computer Follow me BASIC k k j j j j i=0

指针数组 k j k j k j i=1 name name[0] Follow me BASIC name[1] name[2] Great Wall k j name[3] FORTRAN k j name[4] Computer i=1

指针数组 k k j j i=2 name name[0] Follow me BASIC name[1] name[2] Great Wall k j name[3] FORTRAN j name[4] Computer i=2

指针数组 k k j i=3 name name[0] Follow me BASIC name[1] name[2] Great Wall FORTRAN k j name[4] Computer i=3

指针数组 name name[0] Follow me BASIC name[1] name[2] Great Wall name[3] FORTRAN name[4] Computer

多级指针 定义:指向指针的指针 一级指针:指针变量中存放目标变量的地址 例 int *p; int i=3; 二级指针:指针变量中存放一级指针变量的地址 例 int *p; int i=3; p=&i; *p=3; &i 3 P(指针变量) i(整型变量) 例 int *p1; int **p2; int i=3; p1=&i; p2=&p1; **p2=3; p2 &p1 &i 3 P1(指针变量) i(整型变量)

二级指针 i p1 p2 3 &i &p1 **p2, *p1 *p2 定义形式:[存储类型] 数据类型 **指针名; 定义形式:[存储类型] 数据类型 **指针名; 如 char **p; i p1 p2 3 &i &p1 例 int i=3; int *p1; int **p2; p1=&i; p2=&p1; **p=3; **p2, *p1 *p2 例 int i, **p; p=&i; ()//p是二级指针,不能用变量地址为其赋值

二级指针 1 2 2004 2000 2008 200C 2000 输出: 2,1 (main) 2000 变量a 变量b 2004 2010 2014 2004 2008 200C 1 2 变量a 变量b (main) 指针变量p 指针变量q #include <stdio.h> void swap(int **r,int **s) { int *t; t=*r; *r=*s; *s=t; } void main() { int a=1,b=2,*p,*q; p=&a; q=&b; swap(&p,&q); printf("%d,%d\n",*p,*q); 2004 2000 二级指针s 二级指针r (swap) 指针变量t 200C 2008 2000 输出: 2,1

二级指针 p a q b p r a s b q p r a s b q p b q a #include <stdio.h> void swap(int **r,int **s) { int *t; t=*r; *r=*s; *s=t; } void main() { int a=1,b=2,*p,*q; p=&a; q=&b; swap(&p,&q); printf("%d,%d\n",*p,*q); a b r s p q a b r s p q b a p q

二级指针 #define NULL 0 void main() { char **p; name[0] name[1] name[2] name[3] name[4] char *name[5] world bye \0 hello good name p 二级指针 #define NULL 0 void main() { char **p; char *name[]={"hello","good","world","bye",""}; p=name+1; printf("%o : %s ", *p,*p); p+=2; while(**p!=NULL) printf("%s\n",*p++); }

二级指针 二级指针与指针数组的关系 指针数组名是二级指针常量 p=q; p+i 是q[i]的地址 int **p 与 int *q[10] 指针数组名是二级指针常量 p=q; p+i 是q[i]的地址 指针数组作形参,int *q[ ]与int **q完全等价;但 作为变量定义两者不同 系统只给p分配能保存一个指针值的内存区;而给 q分配10块内存区,每块可保存一个指针值

小结 指针的数据类型 定义 含义 int i; 定义整型变量i p为指向整型数据的指针变量 int *p; int a[n]; int *p[n]; int (*p)[n]; int f(); int *p(); int (*p)(); int **p; 定义整型变量i p为指向整型数据的指针变量 定义含n个元素的整型数组a n个指向整型数据的指针变量组成的指针数组p p为指向含n个元素的一维整型数组的指针变量 f为返回整型数的函数 p为返回指针的函数,该指针指向一个整型数据 p为指向函数的指针变量,该函数返回整型数 p为指针变量,它指向一个指向整型数据的指针变量 指针的数据类型