《C语言课件-ppt:第九章-指针.ppt》由会员分享,可在线阅读,更多相关《C语言课件-ppt:第九章-指针.ppt(76页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第九章第九章指指 针针常州信息职业技术学院软件学院主讲教师:李春华2023/3/61教学要求、重点与难点教学要求、重点与难点l教学要求教学要求1、了解地址与指针的概念;2、掌握指针变量的定义与使用;3、掌握将一个变量或数组的地址赋给指针类型的变量;4、掌握通过指针类型的变量去访问某个变量或数组元素的值。l重点与难点重点与难点1、指针变量的定义与引用;2、指针与数组;3、指针与函数2内内 容容2 2 指针变量的定义与引用指针变量的定义与引用3 3 指针与数组指针与数组4 4 指针与字符串指针与字符串 本章小结本章小结 本章作业本章作业1 1 指针的概念指针的概念6 6 返回指针的函数返回指针的函
2、数7 7 指针数组与指向指针的指针指针数组与指向指针的指针8 8 动态内存分配与回收动态内存分配与回收5 5 指针与函数指针与函数3指指 针针 指针是C语言的一个重要概念,也是C语言的一个重要特色。深刻理解和正确使用指针是学习本章的基本要求。49.1指针的概念指针的概念一、地址一、地址 在计算机中,把内存区划分为一个一个的存储单元,每个单元为一个字节(位),它们都有一个编号,这个编号就是内存地址。如下图所示:注意:注意:1、程序中定义的每个变量在编译、程序中定义的每个变量在编译时分配内存单元,系统通过内存地址对变量时分配内存单元,系统通过内存地址对变量进行存取。进行存取。2、数据所占有的存储单
3、元个数是由其类型、数据所占有的存储单元个数是由其类型决定的。决定的。3、首地址:第、首地址:第1个单元的地址个单元的地址4、表示地址的数与整数的区别、表示地址的数与整数的区别59.1指针的概念指针的概念二、举例二、举例 如有定义:char c=A;int a=3;则所占内存情况如下:注意:注意:c和和a的地的地址可能相邻,也址可能相邻,也可能不相邻,是可能不相邻,是由系统分配的,由系统分配的,我们不用关心。我们不用关心。0000001169.1指针的概念指针的概念三、指针与指针变量三、指针与指针变量1、指针:简单地说,指针就是地址。二者是同一个概念的两种说法。只不过指针更形象一些,就像一个针一
4、样,可以指向某个内存单元。什么是指针变量呢?我们回忆一下什么叫整型变量什么是指针变量呢?我们回忆一下什么叫整型变量2、指针变量:首先指针变量就是一个变量,和我们以前所讲的其它变量没有本质区别。不同之处在于这种变量中所存放的内容是地址。79.1指针的概念指针的概念打个比方打个比方四、直接访问和间接访问四、直接访问和间接访问 有两个上锁且放着物品的盒子A、B:如果你有A盒子的钥匙,则可以直接打开A盒子将物品取出;如果你有B盒子的钥匙,而A盒子的钥匙在B盒子中,要想取出A盒子中的物品,则必须先打开B盒子,取出A盒子的钥匙,再打开A盒子将物品取出。上面两种情况就是直接访问和间接访问的概念。89.1指针
5、的概念指针的概念1 1、直接访问、直接访问 通过变量本身对变量进行存取的方式,称为直接访问。如定义:int x;则x=10;x+=5;等等 这种访问方式只需要变量本身就得到了该变量的全部信息,不需要其它内容,是直接的。2 2、间接访问、间接访问 通过指针变量实现对变量的访问方式,称为间接访问。首先要定义一个指针变量,然后将一个同类型变量的地址赋给该指针变量(这时我们称指针变量指向该变量),这样就可以进行间接访问了。间接访问的过程是:由指针变量得到变量的地址,根据该地址找到变量的存储区,再对该存储区的内容进行存取,从而实现了对变量的间接访问。99.2指针变量的定义和引用指针变量的定义和引用一、指
6、针变量的定义和赋值一、指针变量的定义和赋值1、格式:类型名 *指针变量名;2、举例 int *p1;char *s1,*s2;float *a1,*a2,f;3、说明 a.类型名:指针变量所指向的变量类型。b.*是定义指针变量的标志,不可丢掉。c.指针变量定义后,其值是不确定的。109.2指针变量的定义和引用指针变量的定义和引用4、赋值:可以进行初始化,也可以使用赋值语句(1)、初始化:int a,*s=&a;int *f=NULL;(2)、赋值语句 int a,*s;s=&a;(3)、注意:只能用同类型变量的地址进行赋值!如定义:int *s;float f;则 s=&f;是非法的。(4)、
7、不能给指针变量赋以整型量或其它地址量。如:int *p;则 p=2000;是错误的。119.2指针变量的定义和引用指针变量的定义和引用不定在分析有关指针的程序时,画图是很好的方法:若有:int a,*s;则sa若有:int a=5,*s=&a;则不定5&a12二、指针变量的引用二、指针变量的引用1、两个运算符:&与*&:取地址,注意与作位运算符时的不同(双目)*:指针运算符(间接访问符),取内容,*P表示 P所指向的变量,注意与乘运算符不同(双目)2、说明 a.&既可作用于一般变量,也可作用于指针变量 b.*只能作用于指针变量,*s等同于变量a。c.定义指针变量时的*与该处的含义不同 d.优先
8、级别相同。e.结合是自右向左方向结合。9.2指针变量的定义和引用指针变量的定义和引用133、指针变量可以进行的操作(1)赋值:int a,*p1=&a,*p2;p2=p1;(2)输出:printf(“%x”,p1);(3)增减:p1+;p2-;p1+=4;(只能和一个整数)(4)取内容:*p1=5;a=5;printf(“%d”,*p1);(5)比较:一般与指针常量NULL进行比较;当两指针变量同时指向一连续数据区(如数组)时,通过指针值的大小比较判断其指向关系。(6)相减:两个指针变量可进行相减,相减结果表示两指针之间的元素个数。9.2指针变量的定义和引用指针变量的定义和引用14例10-1#
9、include main()int a1=11,a2=22;int *p1,*p2;p1=&a1;p2=&a2;printf(“%d,%dn”,*p1,*p2);p2=p1;printf(“%d,%dn”,*p1,*p2);9.2指针变量的定义和引用指针变量的定义和引用p1&a11122a1p2a2&a2*p1*p2&a115例10-2#include main()int a1=11,a2=22;int *p1,*p2,*p;p1=&a1;p2=&a2;printf(“%d,%dn”,*p1,*p2);p=p1;p1=p2;p2=p;printf(“%d,%dn”,*p1,*p2);9.2指针
10、变量的定义和引用指针变量的定义和引用p1&a11122a1p2a2&a2*p1*p2&a1&a2*p2*p1*p1*p216例10-3#include main()int a1=11,a2=22,t;int *p1,*p2;p1=&a1;p2=&a2;printf(“%d,%dn”,a1,a2);t=*p1;*p1=*p2;*p2=t;printf(“%d,%dn”,a1,a2);9.2指针变量的定义和引用指针变量的定义和引用p1&a11122a1p2a2&a2*p1*p2221117三、指针作为函数的参数三、指针作为函数的参数1、形式:只需要形式参数名前加上一个*即可。如:void test
11、(int *pointer,char f,char*s)2、说明 参数的传递是值传递,单向的(从实参到形参)。这样改变形参的值不改变实参的值。通过指针作为参数可以将主调函数中某变量的地址传递到被调函数中,从而可以改变该地址对应变量的值,即改变主调函数中变量的值。但如果形参本身改变了,其值不会传给实参。9.2指针变量的定义和引用指针变量的定义和引用18例10-4#include void test(int *pt);main()int a=11,*p=&a;printf(“before call,a=%d,p=%xn”,a,p);test(p);printf(“after call,a=%d,p
12、=%xn”,a,p);void test(int *pt)*pt=22;pt+;printf(“pointer=%x”,pt);9.2指针变量的定义和引用指针变量的定义和引用19例10-5 swap(int*p1,int *p2)int t;t=*p1;*p1=*p2;*p2=t;/*交换a,b的值*/main()int a,b,*p1,*p2;scanf(“%d,%d”,&a,&b);p1=&a;p2=&b;if(ab)swap(p1,p2);printf(“%d,%d”,a,b);9.2指针变量的定义和引用指针变量的定义和引用20 在语言中,指针与数组有着密切的关系。对数组元素,既可以采用
13、数组下标来引用,也可以通过指向数组元素的指针来引用。采用指针方法处理数组,可以产生代码长度小、运行速度快的程序。一、通过指针访问一维数组一、通过指针访问一维数组1、数组结构的分析、数组结构的分析设有数组定义为:int a5;则有:(1)a表示数组在内存中的首地址,也就是数组中第1 个元素的首地址,它是一个地址常量,其值由系 统在编译时确定,程序运行期间不能改变。(2)数组中的各元素表示为:a0、a1、a2、a3、a4 或者是:*(a+0)(或*a)、*(a+1)、*(a+2)、*(a+3)、*(a+4)9.3指针与数组指针与数组21(3)数组中的各元素的地址表示为:&a0、&a1、&a2、&a
14、3、&a4 或者是:a+0(或a)、a+1、a+2、a+3、a+4(4)另一种解释:数组名是基地址,下标是偏移量,ai就表示以a为基地址,偏移i个元素的那个元素。(5)数组的逻辑结构如下:9.3指针与数组指针与数组a4a3a2a1a0a&a0&a1&a2&a3&a4222、指针与数组的关系、指针与数组的关系现定义一个指针变量:int *s;并进行赋值:s=a;或 s=&a0;则,指针变量s指向了数组a的开始,二者产生了联系,这样就可以通过指针变量s访问数组a了。注意:注意:a是指针常量,是指针常量,s是指针变量。是指针变量。9.3指针与数组指针与数组a4a3a2a1a0a&a0&a1&a2&a
15、3&a4s23当然,对s也可以进行其它赋值,如:s=a+2;或 s=&a2;图变为:说明:若进行操作说明:若进行操作 s=a;s+=2;效果与上述相同。效果与上述相同。9.3指针与数组指针与数组a4a3a2a1a0a&a0&a1&a2&a3&a4s24 当一个指针变量指向数组的首地址后,关系图为:9.3指针与数组指针与数组数组数组int a5 s=a指向数组元素的指针指向数组元素的指针对指向数组元素的访问对指向数组元素的访问a,&a0,s,&s0a+1,&a1,s+1,&s1a+i,&ai,s+i,&sia0,*a,s0,*sa1,*(a+1),s1,*(s+1)ai,*(a+i),si,*(
16、s+i)25 3、一维数组的访问、一维数组的访问 例10-6 用多种方法访问一维数组各元素#include main()static int a5=1,3,5,7,9,i,*p=a;for(i=0;i5;i+)printf(“%d”,ai);/*下标法*/for(i=0;i5;i+)printf(“%d”,*(a+i);/*数组名+下标*/for(i=0;i5;i+)printf(“%d”,pi);/*指针下标法*/for(i=0;i5;i+)printf(“%d”,*(p+i);/*指针+下标*/for(;pa+5;p+)printf(“%d”,*p);/*指针的移动*/p=a;while(
17、pa+5)printf(“%d”,*p+);/*指针的移动*/9.3指针与数组指针与数组264、几个表达式的分析、几个表达式的分析l设定义:static int a3=1,2,3,*s=a;ls,*s a,*als+,*s+,a+,*a+l*(s+),(*s)+*(a+),(*a)+l初始化时的*s=a;与语句*s=a;的不同l一个指针变量加/减一个整数后,指针变量值的变化情况9.3指针与数组指针与数组错误错误错误27二、数组名作函数参数二、数组名作函数参数1、数组名作函数形参与实参的一般形式、数组名作函数形参与实参的一般形式函数类型 函数名(类型 数组名,int n)函数名(数组名,n)函数
18、体;也可以写为:类型 函数名(类型 *指针名,int n)函数名(数组名,n)函数体;例如:int func(int array,int n)int a10;func(a,10)函数体;也可以写为:int func(int *pointer,int n)int a10;func(a,10)函数体;9.3指针与数组指针与数组282、函数的说明形式、函数的说明形式l如有函数定义:int func(int array,int n)函数体;l则对该函数的说明形式可以写为:lint func(int array,int n);lint func(int *array,int n);lint func(i
19、nt ,int);lint func(int *,int);lint func();9.3指针与数组指针与数组注意:作为形参定义注意:作为形参定义的数组名是一个指针的数组名是一个指针变量,它在函数体中变量,它在函数体中可以变化,这一点与可以变化,这一点与变量定义时不同。变量定义时不同。29例10-7 编写在数组的最后一个元素中存放其它元素和的函数#include void summary(int *p,int n);main()static int a11=1,2,3,4,5,6,7,8,9,10;summary(a,10);printf(“Sum is%dn”,a10);void summa
20、ry(int *p,int n)int s=0;while(n-)s+=*(p+);*p=s;9.3指针与数组指针与数组函数还可写为:void summary(int arr,int n)int i,s=0;for(i=0;in;i+)s+=arri;arrn=s;30例10-8调用子程序,实现求解一维数组中的最大元素#include main()int sub_max();/*函数声明*/int n,a10,*ptr=a;/*定义变量,并使指针指向数组*/int max;for(n=0;n =10-1;n+)/*输入数据*/scanf(%d ,&an);max=sub_max(ptr,10)
21、;/*函数调用,其实参是指针*/printf(max=%d n ,max);9.3指针与数组指针与数组31/*函数定义,其形参为数组*/int sub_max(int b,int i)int temp,j;temp=b 0 ;for(j=1;j =9;j+)if(tempbj)temp=bj;return temp;9.3指针与数组指针与数组/*函数定义,其形参为指针*/int sub_max(int*b,int i)int temp,j;temp=b0;for(j=1;j =9;j+)if(tempbj)temp=bj;return temp;32例10-9用指向数组的指针变量实现一维数组的
22、由小到大的冒泡排序。编写三个函数用于输入数据、数据排序、数据输出。#include#define N 10main()void input();/*函数声明*/void sort();void output();int aN,*p;/*定义一维数组和指针变量*/input(a,N);/*数据输入函数调用,实参a 是数组名*/p=a;/*指针变量指向数组的首地址*/sort(p,N);/*排序,实参p 是指针变量*/output(p,N);/*输出,实参p 是指针变量*/9.3指针与数组指针与数组33void input(int arr,int n)/*无需返回值的输入数据函数定义,形参arr是
23、数组*/int i;printf(input data:n);for(i=0;i n;i+)/*采用传统的下标法*/scanf(%d ,&arr i );void sort(int*ptr,int n)/*冒泡排序,形参ptr 是指针变量*/int i,j,t;for(i=0;i n-1;i+)for(j=0;j*(ptr+j+1)/*相邻两个元素进行比较*/t=*(ptr+j);/*两个元素进行交换*/*(ptr+j)=*(ptr+j+1);*(ptr+j+1)=t;9.3指针与数组指针与数组34void output(int arr,int n)/*数据输出*/int i,*ptr=arr
24、;/*利用指针指向数组的首地址*/printf(output data:n);for(;ptr-arr n;ptr+)/*输出数组的n 个元素*/printf(%4d ,*ptr);printf(n);9.3指针与数组指针与数组35 实 参 形 参1 数组名 数组名2 数组名 指针变量3 指针变量 数组名4 指针变量 指针变量9.3指针与数组指针与数组实参与形参的对应关系小结:36三、指向多维数组的指针三、指向多维数组的指针1、二维数组结构的分析、二维数组结构的分析l设有数组定义为:int a34;则有:la表示数组在内存中的首地址,也就是数组中第1个元素(也是第一行)的首地址,它是一个地址常
25、量,其值由系统在编译时确定,程序运行期间不能改变。l该二维数组可以理解为:它是一个一维数组,含有3个元素,每个元素又是一个一维数组,该一维数组含有4个元素,每个元素是int类型。9.3指针与数组指针与数组37l二维数组的逻辑结构图如下:9.3指针与数组指针与数组a03a02a01a00a13a12a11a10a23a22a21a20a0a1a2a+0a+2a+1382、指向二维数组中一行的指针变量、指向二维数组中一行的指针变量(1)格式:类型名 (*指针变量名)长度;(2)例如:int (*pa)4;(3)含义:pa是指针变量,它指向一个数组,数组 含有4个元素,每个元素的类型是int。(4)
26、说明:a.与定义 int *pa;以及 int (*pa)4;含义不同。b.如果执行pa+,则pa实际增加了多少呢?9.3指针与数组指针与数组pa实际增加了实际增加了2*4=8个字节个字节399.3指针与数组指针与数组 c.若定义:若定义:int a34,(*pa)4=a;则关系图为:则关系图为:a23a22a21a20a13a12a11a10a03a02a01a00apa (*pa)0 (*pa)1 (*pa)2 (*pa)3如果执行如果执行pa+,则变为如图所示则变为如图所示papa第一行各元素还可以表示为第一行各元素还可以表示为那么那么(*pa)0、(*pa)1、(*pa)2、(*pa)
27、3 也变了也变了409.3指针与数组指针与数组 3、几个表达式、几个表达式 由由xi *(x+i)和和&xi x+i可以得出:可以得出:aij(*(a+i)j*(ai+j)*(*(a+i)+j)&aij*(a+i)+j ai+j419.3指针与数组指针与数组例10-10利用指针可以对二维实型数组进行scanf输入main()int i,j;float*p,a22;p=a;for(i=0;i4;i+)scanf(%f,p+);for(i=0;i2;i+)for(j=0;j2;j+)printf(%4.1f,aij);printf(n);429.3指针与数组指针与数组例10-11 用各种方法访问二
28、维数组各元素#include main()static int aa34=1,2,3,4,5,6,7,8,9,10,11,12;int i,j,*p,(*pa)4;/*第一种方法*/for (pa=aa,i=0;i3;i+)printf(“n”);for (j=0;j4;j+)printf(“%5d”,paij);439.3指针与数组指针与数组/*第二种方法*/for (pa=aa;paaa+3;pa+)printf(“n”);for (j=0;j4;j+)printf(“%5d”,(*pa)j);/*第三种方法*/for (p=&aa00;p aa+3*4;p+)if (p-&aa00)%4
29、=0)printf(“n”);printf(“%5d”,*p);449.3指针与数组指针与数组4、多维数组多维数组的指针的指针作作函数的参数函数的参数例如:int func(int array4,int n)函数体;也可以写为:int func(int (*pa)4,int n)函数体;实参调用:main()int a34;,func(a,3);459.3指针与数组指针与数组5、函数的说明形式、函数的说明形式如有函数定义:int func(int array4,int n)函数体;则对该函数的说明形式可以写为:int func(int array4,int n);int func(int (*
30、pa)4,int n);int func(int 4,int);int func(int (*)4,int);int func();注意:作为形参定义的数组名是一个指针变量,它在函数体中可以变化,这一点与变量定义时不同。469.3指针与数组指针与数组例10-12 求3行4列二维数组中的最大元素#include int max_value(int (*pa)4,int row);main()static int aa34=1,3,5,7,2,4,6,8,20,15,32,12;printf(“max element is%dn”,max_value(aa,3);int max_value(int
31、 (*pa)4,int row)int i,j,m=pa00;for(i=0;irow;i+)for(j=0;jm)m=paij;return(m);479.3指针与数组指针与数组例10-12 求3行4列二维数组中的最大元素(另一种方法)#include int max_value(int *p,int n);main()static int aa34=1,3,5,7,2,4,6,8,20,15,32,12;int max;max=max_value(&aa00,3*4);printf(“max element is%dn”,max);int max_value(int *p,int n)in
32、t i,m=*p;for(i=0;im)m=*p;return(m);489.4指针与字符串指针与字符串 字符串是一种特殊的一维数组,所以上节中介绍的方法同样适用于对字符串的访问。字符串的特殊性在于:字符串的末尾是结束标志0,所以访问字符串时常用结束标志进行判断。一、通过指针访问字符串一、通过指针访问字符串1、字符串结构的分析、字符串结构的分析 设有数组定义为:char s=“abcde”;则s是一个字符数组,它里面存放的是一个字符串。它在内存中占用6个字节,但长度为5。其结构为:0edcbas s0 s1 s2 s3 s4 s5结束标志499.4指针与字符串指针与字符串 字符串还可以定义为:
33、char *s=“abcde”;它在内存中占用6个字节,长度为5。其结构为:0edcbas s0 s1 s2 s3 s4 s5结束标志结束标志509.4指针与字符串指针与字符串2、用字符数组与用指针使用字符串的比较、用字符数组与用指针使用字符串的比较定义及初始化char s=“abcde”;char *p=“abcde”;赋值char s6;char *p;s=“abcde”;/*不对,应为*/p=“abcde”;strcpy(s,“abcde”);p=s;strcpy(p,“abcde”);使用s不能加/减 p可以加/减 s是一个指针常量 p是指针变量scanf(“%s”,s);p=s;sc
34、anf(“%s”,p);printf(“”%s”,s);printf(“”%s”,p);注意:char s=“abc”;与char s=a,b,c;的区别519.4指针与字符串指针与字符串例10-13 将字符数组a中的字符串拷贝到字符数组b中(1)下标法 (2)指针法#include#include main()main()char a=“Hello,world!”,b20;char a=“Hello,world!”,b20;int i;char*pa,*pb;for(i=0;ai!=0;i+)for(pa=a,pb=b;*pa!=0;pa+,pb+)bi=ai;*pb=*pa;bi=0;*p
35、b=0;printf(“%sn”,b);printf(“%sn”,b);该功能相当于:该功能相当于:strcpy(b,a);529.4指针与字符串指针与字符串二、通过指针在函数间传递字符串二、通过指针在函数间传递字符串1、函数的定义形式、函数的定义形式例如:char func(char a,char b)函数体;也可以写为:char func(char *a,char *b)函数体;539.4指针与字符串指针与字符串例10-14 设计一函数,实现与标准函数strcpy类似的功能。#include void mystrcpy(char *to,char *from);main()char ca2
36、0,*cp=“Hello,world!”;mystrcpy(ca,cp);printf(“%s”,ca);void mystrcpy(char *to,char *from)while (*from!=0)*to=*from;to+;from+;*to=0;思考:调用 mystrcpy(ca,cp+2);结果如何?549.5指针与函数指针与函数一、指向函数的指针一、指向函数的指针1、函数名的含义 函数名代表一个地址,它是函数的入口,即函数代码在内存中的起始位置,函数名是指针常量,类似于数组名。2、概念 如果一个指针指向一个函数,则称该指针为函数指针。3、定义 类型名 (*指针变量名)(形参表)
37、;如:int (*f)(int a,int b);4、引用 (*指针变量名)(实参表);5、对函数指针变量,象p+n等运算无意义559.5指针与函数指针与函数例10-15 函数指针举例#include int max(int a,int b);int min(int a,int b);main()int x=3,y=4,z;int (*pf)(int,int );pf=max;z=(*pf)(x,y);printf(max is%dn”,z);pf=min;printf(“min is%dn,(*pf)(x,y);int max(int a,int b)return(ab?a:b);int m
38、in(int a,int b)return(ab?a:b);569.5指针与函数指针与函数二、函数指针作函数参数二、函数指针作函数参数 函数指针是变量,可以充当函数的参数。用于不知道函数名但可以获取函数入口的情况。也可以用于在一个函数中实现对数据的不同处理。例10-16 int process(int(*p)(),int a,int b)return(*p)(a,b);int add(int a,int b)return a+b;int substract(int a,int b)return a-b;main()int a,b;a=process(add,2,3);b=process(sub
39、stract,3,2);579.6返回指针的函数返回指针的函数1、概念、概念 当函数的返回值是指针类型(地址)时,则称为指针函数。注意不能返回指向局部变量的指针2、定义、定义 类型名 *函数名(形参表)说明部分;语句部分;如:int *f(int a);等等。注意int(*p)()与int*p()的区别589.6返回指针的函数返回指针的函数例10-17 将一个字符串转换为大写形式并输出#include char *mytoupper(char *s);main()char ps80,*s;gets(ps);s=mytoupper(ps);puts(s);char *mytoupper(char
40、 *s)char *t=s;while (*t!=0)*t=(*t=a&*t=z)?*t32:*t;t+;return(s);599.7指针数组和指向指针的指针指针数组和指向指针的指针一、指针数组一、指针数组 1、指针数组的概念、指针数组的概念 指针数组是一种特殊的数组,它每个元素的类型都是指针类型(即地址),其它与一般数组相同。当把某个量的地址放入某元素中后,即可通过该元素对相应的量进行间接访问。2、指针数组的定义、指针数组的定义 类型名 *指针数组名常量表达式;如:int *ap3;char *s10;等等。609.7指针数组和指向指针的指针指针数组和指向指针的指针3、指针数组的初始化、指
41、针数组的初始化(1)int a15,a25,a35,*ap3=a1,a2,a3;(2)char *sp=“abc”,“123”,“Hello”;4、指针数组的赋值、指针数组的赋值 上面的情况中,可以先定义变量,再进行赋值,即(1)int a15,a25,a35,*ap3;ap0=a1;ap1=a2;ap2=a3;(2)char *sp3;sp0=“abc”;sp1=“123”;sp2=“Hello”;619.7指针数组和指向指针的指针指针数组和指向指针的指针例10-18 显示多个字符串#include main()/*用指针数组实现*/static char *ap3=“CPU”,“Compu
42、ter”,“Microprocessor”;int i;for (i=0;i3;i+)puts(api);#include main()/*用二维字符数组实现*/static char aa315=“CPU”,“Computer”,“Microprocessor”;int i;for (i=0;i3;i+)puts(aai);629.7指针数组和指向指针的指针指针数组和指向指针的指针两种方法中所占内存空间的比较两种方法中所占内存空间的比较0rossecorporciM0retupmoC0UPCap2ap1ap0aa0aa1aa2ap0UPC0retupmoC0rossecorporciM639
43、.7指针数组和指向指针的指针指针数组和指向指针的指针二、指向指针的指针二、指向指针的指针1、多级指针的概念、多级指针的概念 所谓多级指针,是指指针有多级指向关系。2、多级指针的定义、多级指针的定义 类型标识符 *指针变量名;注:*的个数代表级数,要求掌握到二级即可。如:char *pp,*p,ch=A;又p=&ch;pp=&p;则:&p&chApppch649.7指针数组和指向指针的指针指针数组和指向指针的指针3、多级指针的含义、多级指针的含义若定义:char *ps=“abc”,“123”,*pp=ps;则:*pp 为 “abc”*(pp+1)为 “123”*(*(pp+1)+2)为 3执行
44、pp+;则:*pp 为 “123”659.7指针数组和指向指针的指针指针数组和指向指针的指针例10-19 显示并选择菜单条目#include int getchoice(char *menu,int n);main()int chc;static char *mn5=“1.Input”,“2.Copy”,“3.Move”,“4.Delete”,“0.Exit”;chc=getchoice(mn,5);if (chc=0&chc5)printf(“You choice No.is%dn”,chc);else printf(“Invalid choice!n”);int getchoice(cha
45、r *menu,int n)int i;for(i=0;in;i+)puts(*(menu+i);printf(“nInput your choice:”);return(getchar()0);669.7指针数组和指向指针的指针指针数组和指向指针的指针三、命令行参数三、命令行参数1、命令行参数的概念、命令行参数的概念1)DOS命令:copy file1 file22)以前的main函数形式:main()3)main函数的调用由系统完成4)带参main函数:main(int argc,char *argv);或 main(int argc,char *argv);679.7指针数组和指向指针的
46、指针指针数组和指向指针的指针2、命令行参数的说明、命令行参数的说明1)形参也可以用其它名字,习惯上为argc和argv2)argc和argv的值的获得 如有程序myprog.c,经编译和链接生成可执行程序myprog.exe,在命令行中输入:myprog argument1 argument2 则argc的值为3,argv0的值为“myprog”,argv1的值为“argument1”,argv2的值为“argument2”。3)实现:DOS提示符状态下或集成环境中。689.7指针数组和指向指针的指针指针数组和指向指针的指针例10-20 输出各命令行参数#include main(int ar
47、gc,char *argv)int i;for (i=1;iargc;i+)printf(“arg%d:%sn”,i,argvi);若可执行文件为showarg,运行时键入:showarg Computer and C language则输出为:argv1:Computer argv2:and argv3:C argv4:language699.7指针数组和指向指针的指针指针数组和指向指针的指针例10-21利用图形库函数绘制一个变化的环。它是把一个半径为R1的圆周分成n份,然后以每个等分点为圆心,以Rs为半径画n个圆。利用main()函数的带参数形式,我们可以从键盘以命令行的方式输入R1和Rs
48、及屏幕的背景色。#include /*包含图形库函数的头文件*/#include#include#define pi 4.1415926main(int argc,char*argv)/*定义带参数的main()*/int x,y,r1,rs,color;double a;int gdriver=DETECT,gmode;if(argc4&strcmp(argv1,pass)!=0)/*设置口令的比较*/printf(password error!n);exit(1);709.7指针数组和指向指针的指针指针数组和指向指针的指针 initgraph(&gdriver,&gmode,.bgi);/
49、*启动图形工作方式*/r1=atoi(argv 2 );/*计算基础圆半径*/rs=atoi(argv 3 );/*计算同心圆半径*/color=atoi(argv 4 );/*背景色*/cleardevice();/*清除图形屏幕*/setbkcolor(color);/*设置背景色*/setcolor(4);/*设置图形显示颜色*/for(a=0;a=2*pi;a+=pi/18)/*绘制同心圆*/x=r1*cos(a)+320;y=r1*sin(a)+240;circle(x,y,rs);/*以圆心坐标为x、y,半径为r s 画圆*/getch();/*等待按键继续*/closegraph
50、();/*关闭图形工作方式*/假设生成L9-22.exe文件,则命令行方式为:L9-22 pass 40 20 3719.8动态内存分配与回收动态内存分配与回收 由变量的作用域和存储类别知道,内存变量都有生存期,以前接触的变量,其内存的分配及释放都是由系统统一管理的。这一节我们介绍如何实现自己对变量空间的申请和释放。动态内存分配可以提高内存的使用效率。1、相关函数介绍、相关函数介绍1)void *malloc(unsigned size);该函数实现对内存的申请,申请大小为size,返回值为指针类型,指向所申请空间的首地址。(执行后需进行检测)2)void free(void *block);