第-八-章-指-针教学课件_第1页
第-八-章-指-针教学课件_第2页
第-八-章-指-针教学课件_第3页
第-八-章-指-针教学课件_第4页
第-八-章-指-针教学课件_第5页
已阅读5页,还剩86页未读 继续免费阅读

下载本文档

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

文档简介

第八章指针31、园日涉以成趣,门虽设而常关。32、鼓腹无所思。朝起暮归眠。33、倾壶绝余沥,窥灶不见烟。34、春秋满四泽,夏云多奇峰,秋月扬明辉,冬岭秀孤松。35、丈夫志四海,我愿不知老。第八章指针第八章指针31、园日涉以成趣,门虽设而常关。32、鼓腹无所思。朝起暮归眠。33、倾壶绝余沥,窥灶不见烟。34、春秋满四泽,夏云多奇峰,秋月扬明辉,冬岭秀孤松。35、丈夫志四海,我愿不知老。第八章指针指针是C语言的一个重要概念,也是C语言的一个重要特色。深刻理解和正确使用指针是学习本章的基本要求。本章是一个难点,也是一个重点,初学者不易掌握。在理解和熟悉基本内容的前提下,上机实验是必不可少的环节。8.1指针的概念二、举例

如有定义:charc=‘A’;inta=3;则所占内存情况如下:注意:c和a的地址可能相邻,也可能不相邻,是由系统分配的,我们不用关心。118.1指针的概念三、指针与指针变量1、指针:简单地说,指针就是地址。二者是同一个概念的两种说法。只不过指针更形象一些,就像一个针一样,可以指向某个内存单元。2、指针变量:首先指针变量就是一个变量,和我们以前所讲的其它变量没有本质区别。不同之处在于这种变量中所存放的内容是地址。什么是指针变量呢?我们回忆一下什么叫整型变量例如:先定义了某整型变量a,再定义一个指针变量b,将变量a的内存地址赋给指针变量b,即b=&a;这就代表指针b指向变量a。打个比方8.1指针的概念四、直接访问和间接访问有两个上锁且放着物品的盒子A、B,如果你有A盒子的钥匙,则可以直接打开A盒子将物品取出;如果你有B盒子的钥匙,而A盒子的钥匙在B盒子中,要想取出A盒子中的物品,则必须先打开B盒子,取出A盒子的钥匙,再打开A盒子将物品取出。上面两种情况就是直接访问和间接访问的概念。8.1指针的概念1、直接访问通过变量本身对变量进行存取的方式,称为直接访问。如定义:intx;则x=10;x+=5;等等这种访问方式只需要变量本身就得到了该变量的全部信息,不需要其它内容,是直接的。2、间接访问通过指针变量实现对变量的访问方式,称为间接访问。首先要定义一个指针变量,然后将一个同类型变量的地址赋给该指针变量(这时我们称指针变量指向该变量),这样就可以进行间接访问了。间接访问的过程是:由指针变量得到变量的地址,根据该地址找到变量的存储区,再对该存储区的内容进行存取,从而实现了对变量的间接访问。例如:inta,*p;p=&a;*p=6;/*相当于a=6;*/printf(“%d”,*p);该节结束,返回目录*p相当于变量a8.2指针变量的定义和引用一、指针变量的定义和赋值1、格式:类型名*指针变量名;2、举例int*p1;char*s1,*s2;float*a1,*a2,f;3、说明a.类型名:指针变量所指向的变量类型。b.*是定义指针变量的标志,不可丢掉。c.指针变量定义后,其值是不确定的。8.2指针变量的定义和引用4、赋值:可以进行初始化,也可以使用赋值语句(1)、初始化:inta,*s=&a;int*f=NULL;(2)、赋值语句inta,*s;s=&a;说明:

a、“&”代表取地址运算符,&a代表变量a的地址,&a是一个指针常量,可为一个指针变量赋值。b、还可将数组名和函数名赋给某些类型的指针变量,因为数组名和函数名代表相应的起始地址。不定8.2指针变量的定义和引用在分析有关指针的程序时,画图是很好的方法:若有:inta,*s;则sa若有:inta=5,*s=&a;则不定5&a8.2指针变量的定义和引用c、注意:只能用同类型变量的地址进行赋值!如定义:int*s;floatf;则s=&f;是非法的。d、不能给指针变量赋以整型量或其它地址量。如:int*p;则p=2000;是错误的。8.2指针变量的定义和引用二、指针变量的引用1、两个运算符:&与*

&:取地址,注意与作位运算符时的不同(双目)

*:指针运算符(间接访问符),取存储单元的内容,*P表示P所指向的变量,注意与乘运算符不同。2、说明a.&既可作用于一般变量,也可作用于指针变量b.*只能作用于指针变量,*s等同于变量a。c.定义指针变量时的*与该处的含义不同8.2指针变量的定义和引用3、指针变量可以进行的操作(1)赋值:inta,*p1=&a,*p2;p2=p1;(2)输出:printf(“%x”,p1);(3)增减:p1++;p2--;p1+=4;(只能和一个整数)(4)取内容:*p1=5;a=5;printf(“%d”,*p1);(5)比较:一般与指针常量NULL进行比较;两指针变量值的大小比较无意义。表示空指针,即不指向任何单元,在头文件stdio.h中定义。是指拨一个变量的位置,并非地址值简单加1。8.2指针变量的定义和引用例8.1

#include<stdio.h>

main()

{

inta1=11,a2=22;

int*p1,*p2;

p1=&a1;

p2=&a2;

printf(“%d,%d\n”,*p1,*p2);

p2=p1;

printf(“%d,%d\n”,*p1,*p2);

}举例p1&a11122a1p2a2&a2*p1*p2&a1运行结果如下:

11,2211,11*p2*p28.2指针变量的定义和引用例8.2

#include<stdio.h>

main()

{

inta1=11,a2=22;

int*p1,*p2,*p;

p1=&a1;

p2=&a2;

printf(“%d,%d\n”,*p1,*p2);

p=p1;p1=p2;p2=p;

printf(“%d,%d\n”,*p1,*p2);

}p1&a11122a1p2a2&a2&a1&a2举例运行结果如下:

11,2222,118.2指针变量的定义和引用例8.3

#include<stdio.h>

main()

{

inta1=11,a2=22,t;

int*p1,*p2;

p1=&a1;

p2=&a2;

printf(“%d,%d\n”,a1,a2);

t=*p1;*p1=*p2;*p2=t;

printf(“%d,%d\n”,a1,a2);

}p1&a11122a1p2a2&a2*p1*p22211举例运行结果如下:

11,2222,118.2指针变量的定义和引用三、指针作为函数的参数1、形式:只需要形式参数名前加上一个*即可。如:voidtest(int*pointer,charf,char*s)2、说明参数的传递是值传递,单向的(从实参到形参)。这样改变形参的值不改变实参的值。通过指针作为参数可以将主调函数中某变量的地址传递到被调函数中,从而可以改变该地址对应变量的值,即改变主调函数中局部变量的值。但如果形参本身改变了,其值不会传给实参。即形参指针的值改变了,不会影响实参指针的地址值。8.2指针变量的定义和引用11实参a函数调用形参b11调用结束11实参a函数调用形参*p调用结束15传递地址&a22普通变量参数传递指针类型参数传递8.2指针变量的定义和引用例8.4:#include<stdio.h>

voidtest(int*pt);

main()

{inta=11,*p=&a;

printf(“beforecall,a=%d,p=%x\n”,a,p);

test(p);

printf(“aftercall,a=%d,p=%x\n”,a,p);

}

voidtest(int*pt)

{*pt=22;pt++;printf(“pointer=%x”,pt);}执行test(&a)返回8.2指针变量的定义和引用11实参a形参*ptpt++22指针类型参数传递实参p=&a&a编一函数,找出一维数组中的最大值和最小值。例8.5复习指针变量:是一种特殊的变量,存放的是其它变量的地址,如:inta,*p=&a;此时指针p就指向了变量a,就可以用指针p对变量a进行间接访问,即*p等价于a;指针作为函数参数:如希望函数调用结束后,主调函数中实参变量的值改变,或希望通过指针参数将函数中的结果传递给主调函数,此时形参应定义成指针类型,函数调用时用某变量的地址或指向该变量的指针作为实参调用。例如a的地址编号:ffd9………………p的地址编号:ffe211011001111111110000010100000000分清几种含义:printf(“%d”,p);printf(“%d”,*p);printf(“%d”,a);printf(“%d”,&a);printf(“%d”,&p);8.3指针与一维数组在C语言中,指针与数组有着密切的关系。对数组元素,既可以采用数组下标来引用,也可以通过指向数组元素的指针来引用。采用指针方法处理数组,可以产生代码长度小、运行速度快的程序。8.3指针与一维数组一、通过指针访问一维数组1、数组结构的分析设有数组定义为:inta[5];则有:(1)a表示数组在内存中的首地址,也就是数组中第0个元素a[0]的地址,其值由系统在编译时确定,程序运行期间不能改变,所以它是一个地址常量,即指针常量,所以*a就代表第0个元素a[0]。(2)数组中的各元素按顺序存放,表示为:

a[0]、a[1]、a[2]、a[3]、a[4]8.3指针与一维数组(3)数组中的各元素的地址表示为:

&a[0]、&a[1]、&a[2]、&a[3]、&a[4]或者是:a+0(或a)、a+1、a+2、a+3、a+4(4)另一种解释:数组名是基地址,下标是偏移量,a[i]就表示以a为基地址,偏移i个元素的那个元素。所以a[i]的地址可表示为a+i;a+i就是指向第i个元素的指针常量,所以*(a+i)代表第i个元素a[i]。所以数组各元素也可表示为:*(a+0)(或*a)、*(a+1)、*(a+2)、*(a+3)、*(a+4)注意:所谓的偏移量是偏移一个元素的位置,并非是原指针值+1,例如一个整型数组的一个偏移量应该是两个字节,如数组a的首地址是2002单元,则a+1的值应是2004单元。8.3指针与一维数组这样,下标表达式a[i]和指针表达式*(a+i)都表示数组下标为i的元素;a+i和&a[i]都表示下标为i的元素的地址。数组元素,即可通过下标法直接访问,也可通过指针变量间接访问。使用指针变量访问数组,可通过使指针变量的加减运算使其指向数组的各个元素,从而遍历数组各元素。转8.3指针与一维数组2、指针与数组的关系现定义一个指针变量:int*s;并进行赋值:s=a;或s=&a[0];则,指针变量s指向了数组a的开始,二者产生了联系,这样就可以通过指针变量s访问数组a了。a[0]a[1]a[2]a[3]a[4]a&a[0]&a[1]&a[2]&a[3]&a[4]ss++8.3指针与一维数组当然,对s也可以进行其它赋值,如:s=a+2;或s=&a[2];图变为:a[0]a[1]a[2]a[3]a[4]a&a[0]&a[1]&a[2]&a[3]&a[4]s说明:若进行操作s=a;s+=2;效果与上述相同。8.3指针与一维数组当一个指针变量指向数组的首地址,即inta[5],*p;p=a;就可用p访问数组,*p就表示p所指向的数组元素,p+i表示p指向的当前元素向下的第i个元素的地址,*(p+i)就表示这个元素,与下标运算p[i]是等价的。所以a[i],*(a+i),p[i],*(p+i)都表示数组的第i个元素,a+i,&a[i],p+i,&p[i]都表示数组的第i个元素的地址。数组名a与指针变量p的区别在于:a是指针常量,而p是指针变量,p的值可以改变,而a的值不能变,如a++或a=a+2都是非法的,而p++是合法的。8.3指针与一维数组数组inta[5]指向数组元素的指针数组元素的访问a,&a[0],p,&p[0]a+1,&a[1],p+1,&p[1]a+i,&a[i],p+i,&p[i]a[0],*a,p[0],*pa[1],*(a+1),p[1],*(p+1)a[i],*(a+i),p[i],*(p+i)使用指针访问数组元素的真正意义在于通过指针变量的加减访问数组的各个元素,如指针p指向数组的首地址,在循环程序中可进行p++运算,通过*p访问数组的各元素。如以下程序段:

inta[5]={1,3,5,7,9},*p;for(p=a;p<a+5;p++)printf(“%d”,*p);3、一维数组的访问例8.6用多种方法访问一维数组各元素

#include<stdio.h>

main()

{inta[5]={1,3,5,7,9},i,*p=a;

for(i=0;i<5;i++)printf(“%d”,a[i]);第一种方法,最直观

for(i=0;i<5;i++)printf(“%d”,*(a+i));第二种方法

for(i=0;i<5;i++)printf(“%d”,p[i]);第三种方法

for(i=0;i<5;i++)printf(“%d”,*(p+i));第四种方法

for(;p<a+5;p++)printf(“%d”,*p);第五种方法,最有效

p=a;while(p<a+5){printf(“%d”,*p);p++;}第六种方法

p=a;while(p<a+5)printf(“%d”,*p++);第七种方法}注意:此处不能是p<=a+5使用指针访问数组元素,应特别注意指针变量的当前指向,尤其是循环结束后,如:

for(;p<a+5;p++)printf(“%d”,*p);循环结束后p的值是a+5,而数组a的最后一个元素的地址是a+4,即此时p已指向数组外了,如果不重新为p赋值,直接引用*p将产生不可预料的后果。此种错误隐蔽性强,编译器不指出。8.3指针与一维数组4、几个表达式的分析设定义:inta[3]={1,2,3},*s=a;s,*sa,*as++,*s++,a++,*a++*(s++),(*s)++*(a++),(*a)++表达式*(s++)与*s++是等价的,都是先取出值,再使指针向下拨1个位置。(*s)++表示使当前指向的变量值加1。初始化时的*s=a;与语句*s=a;的不同×××返回例题用指针的方法完成,将数组中的最小的数与第一个数对换,把最大的数与最后一个数对换。8.3指针与一维数组二、通过指针在函数间传递一维数组1、函数的定义形式例如:intfunc(intarray[],intn)

{函数体;}也可以写为:intfunc(int*array,intn)

{函数体;}8.3指针与一维数组2、函数的说明形式如有函数定义:

intfunc(intarray[],intn)

{函数体;}则对该函数的说明形式可以写为:intfunc(intarray[],intn);intfunc(int*array,intn);intfunc(int[],int);intfunc(int*,int);intfunc(intarray[],intn)函数的形参是数组(指针),函数调用时可以用数组名作为实参,从便于理解的角度可认为形参数组与实参数组具有相同的起始地址,共占一段内存。而实际上形参是一个指针变量,调用时将实参数组的首地址赋给该指针变量,从而使该指针变量指向实参数组的第0个元素。如:func(a,5);因此,在函数内部可用指针arry间接访问数组a,如:while(arry<a+n)*arry++=2;注意:作为形参定义的数组名是一个指针变量,它在函数体中值可以变化,而函数内部定义的数组,其数组名是指针常量,其值不能改变,如。既然调用的实参是某一地址,也可以是数组中任意元素的地址,如将第3个元素的地址作为实参调用也可以,此时后面的参数将加以调整,如:func(a+2,3);8.3指针与一维数组例8.7编写在数组的最后一个元素中存放其它元素和

的函数

#include<stdio.h>

voidsummary(int*p,intn);

main()

{staticinta[11]={1,2,3,4,5,6,7,8,9,10};

summary(a,10);

printf(“Sumis%d\n”,a[10]);

}

voidsummary(int*p,intn)

{

ints=0,i=0;;

while(i<n){s+=*p++;i++;}*p=s;

}该节结束,返回目录函数还可写为:

voidsummary(intarr[],intn)

{inti,s=0;

for(i=0;i<n;i++)s+=arr[i];

arr[n]=s;}8.4指针与字符串字符串是一种特殊的一维数组,所以上节中介绍的方法同样适用于对字符串的访问。字符串的特殊性在于:字符串长度任意,末尾的结束标志是‘\0’,所以访问字符串时常用结束标志进行判断。8.4指针与字符串一、通过指针访问字符串1、字符串结构的分析设有数组定义为:chars[]=“abcde”;则s是一个字符数组,它里面存放的是一个字符串。它在内存中占用6个字节,但字符串长度为5。其结构为:‘a’‘b’‘c’‘d’‘e’‘\0’ss[0]s[1]s[2]s[3]s[4]s[5]结束标志8.4指针与字符串字符串还可以定义为:char*s=“abcde”;它在内存中占用6个字节,长度为5。其结构为:‘a’‘b’‘c’‘d’‘e’‘\0’ss[0]s[1]s[2]s[3]s[4]s[5]结束标志8.4指针与字符串2、用字符数组与用指针使用字符串的比较定义及初始化

chars[]=“abcde”;char*p=“abcde”;赋值

chars[6];char*p,b[20];

s=“abcde”;/*不对*/

p=“abcde”;p=b;

strcpy(s,“abcde”);strcpy(p,“abcde”);使用

s不能加/减,s++;p可以加/减,p++;注意:chars[]=“abc”;与chars[]={‘a’,’b’,’c’};的区别补充:如果定义了一个指向字符型变量的指针,未给它赋任何地址之前是不能直接使用它进行函数调用的,如:gets(p);或strcpy(p,“se”);8.4指针与字符串例8.8将字符数组a中的字符串拷贝到字符数组b中(1)下标法(2)指针法#include<stdio.h>#include<stdio.h> main()main(){{chara[]=“Hello,world!”,b[20];chara[]=“Hello,world!”,b[20];inti;char*pa,*pb;for(i=0;a[i]!=‘\0’;i++)for(pa=a,pb=b;*pa!=‘\0’;pa++,pb++)b[i]=a[i];*pb=*pa;b[i]=‘\0’;*pb=‘\0’;printf(“%s\n”,b);printf(“%s\n”,b);}}该功能相当于:strcpy(b,a);pa=a;pb=b;while(*pa++=*pb++)8.4指针与字符串例8.9将指针变量cp所指向的字符串拷贝到字符数组ca中(1)下标法(2)指针法#include<stdio.h>#include<stdio.h> main()main(){{charca[20],*cp=“Hello,world!”;charca[20],*cp=“Hello,world!”;inti;char*p;for(i=0;cp[i]!=‘\0’;i++)for(p=ca;*cp!=‘\0’;p++,cp++)ca[i]=cp[i];*p=*cp;ca[i]=‘\0’;*p=‘\0’;printf(“%s\n”,ca);printf(“%s\n”,ca);}}该功能相当于:strcpy(ca,cp);p=ca;while(*p++=*cp++)注意:循环结束后的指针指向,p已指向ca外,未重新赋值前,不能用p输出ca内的串。cp也指向字符串常量外。8.4指针与字符串二、通过指针在函数间传递字符串1、函数的定义形式例如:charfunc(chara[])

{函数体;}也可以写为:charfunc(char*a)

{函数体;}8.4指针与字符串例8.10设计一函数,实现与标准函数strcpy类似的功能。

#include<stdio.h>

voidmystrcpy(char*to,char*from);

main()

{charca[20],*cp=“Hello,world!”;

mystrcpy(ca,cp);

printf(“%s”,ca);

}

voidmystrcpy(char*to,char*from)

{

while(*from!=‘\0’){*to=*from;to++;from++;}

*to=‘\0’;

}思考:调用mystrcpy(ca,cp+2);结果如何?调用mystrcpy(ca+2,cp);结果又如何?while(*from!=‘\0’)*to++=*from++;*to=‘\0’;while(*to++=*from++);8.4指针与字符串例8.21编写比较两个字符串大小的函数,如果两串相同,返回值为0,否则,返回它们二者第一个不同字符的ASCII码差值。

#include<stdio.h>

intmystrcmp(char*,char*);

main()

{charca[50],cp[50];inti;gets(ca);gets(cp);i=mystrcmp(ca,cp);

if(i>0)printf(“%s>%s”,ca,cp);

elseif(i=0)printf(“%s=%s”,ca,cp);

elseprintf(“%s<%s”,ca,cp);

}

intmystrcmp(char*s1,char*s2)

{while(*s1!=‘\0’&&*s2!=‘\0’){if(*s1!=*s2)break;s1++;s2++;}

return(*s1-*s2);}该节结束,返回目录8.5指针与多维数组数组是具有相同“数据类型”的数据的顺序集合,而数组本身也是C语言的一种数据类型,同样可以作为数组的元素类型。当一个一维数组的元素类型为数组时,便构成了多维数组。熟记下面两组等价式:

x[i]*(x+i)

&x[i]x+i8.5指针与多维数组一、通过指针访问多维数组1、二维数组结构的分析设有数组定义为:inta[3][4];则有:a表示数组在内存中的首地址,也就是数组中第1

个元素(也是第一行)的首地址,它是一个地址常量,其值由系统在编译时确定,程序运行期间不能改变。该二维数组可以理解为:它是一个一维数组,含有3个元素,每个元素又是一个一维数组(该一维数组含有4个元素,每个元素是int类型)。8.5指针与多维数组二维数组的逻辑结构图如下:a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1]a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]a[0]a[1]a[2]a+0a+2a+18.5指针与多维数组2、指向二维数组中一行的指针变量(或指向一维数组的指针变量)(1)格式:类型名(*指针变量名)[长度];(2)例如:int(*pa)[4];(3)含义:pa是指针变量,它指向一个数组,数组

含有4个元素,每个元素的类型是int。(4)说明:

a.与定义int*pa;以及int*pa[4];含义不同。b.如果执行pa++,则pa实际增加了多少呢?pa实际增加了2*4=8个字节8.5指针与多维数组

c.若定义:inta[3][4],(*pa)[4]=a;则关系图为:a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1]a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]apa(*pa)[0](*pa)[1](*pa)[2](*pa)[3]如果执行pa++,则*pa代表a[1],变为如图所示papa*pa代表a[0],即第0行,第0行各元素还可以表示为那么(*pa)[0]、(*pa)[1]、(*pa)[2]、(*pa)[3]也变了8.5指针与多维数组3、几个表达式由x[i]*(x+i)和&x[i]x+i可以得出:

a[i][j](*(a+i))[j]*(a[i]+j)*(*(a+i)+j)&a[i][j]*(a+i)+ja[i]+j8.5指针与多维数组例8.11用各种方法访问二维数组各元素#include<stdio.h>

main()

{

staticintaa[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};

inti,j,*p,(*pa)[4];//第一种方法

for(pa=aa,i=0;i<3;i++){printf(“\n”);

for(j=0;j<4;j++)printf(“%5d”,pa[i][j]);

}8.5指针与多维数组//第二种方法

for(pa=aa;pa<aa+3;pa++){printf(“\n”);

for(j=0;j<4;j++)printf(“%5d”,(*pa)[j]);

}//第三种方法

for(p=&aa[0][0];p<&aa[0][0]+3*4;p++){if((p-&aa[0][0])%4==0)printf(“\n”);

printf(“%5d”,*p);

}

}8.5指针与多维数组二、通过指针在函数间传递多维数组1、函数的定义形式例如:intfunc(intarray[][4],intn)

{函数体;}也可以写为:intfunc(int(*array)[4],intn)

{函数体;}8.5指针与多维数组2、函数的说明形式如有函数定义:

intfunc(intarray[][4],intn)

{函数体;}则对该函数的说明形式可以写为:intfunc(intarray[][4],intn);intfunc(int(*array)[4],intn);intfunc(int[][4],int);intfunc(int(*)[4],int);注意:作为形参定义的数组名是一个指针变量,它在函数体中可以变化,这一点与变量定义时不同。8.5指针与多维数组例8.12求3行4列二维数组中的最大元素#include<stdio.h>

intmax_value(int(*pa)[4],introw);

main()

{staticintaa[3][4]={{1,3,5,7},{2,4,6,8},{20,15,32,12}};

printf(“maxelementis%d\n”,max_value(aa,3));

}

intmax_value(int(*pa)[4],introw)

{inti,j,m=pa[0][0];

for(i=0;i<row;i++)

for(j=0;j<4;j++)if(pa[i][j]>m)m=pa[i][j];return(m);

}int(*pb)[4];for(pb=pa;pa<pb+3;pa++)for(j=0;j<4;j++)if((*pa)[j]>m)m=(*pa)[j];8.5指针与多维数组例8.12求3行4列二维数组中的最大元素(另一种方法)#include<stdio.h>

intmax_value(int*p,intn);

main()

{staticintaa[3][4]={{1,3,5,7},{2,4,6,8},{20,15,32,12}};

intmax;

max=max_value(&a[0][0],3*4);

printf(“maxelementis%d\n”,max);

}

intmax_value(int*p,intn)

{inti,m=*p;

for(i=0;i<n;i++,p++)

if(*p>m)m=*p;

return(m);

}该节结束,返回目录复习2int*p;

指向普通的整型变量或一维数组的首地址,*p代表一个整型变量或一维数组中的某一个元素。p++的含义?

int(*p)[4];

指向二维数组一整行,或指向整个一维数组,*p代表一整个一维数组,其中的每一个元素用(*p)[i]表示。p++的含义?当作为函数参数时都是指针变量,二维数组的访问有两种方法:下标法、指针法(一维数组指针、普通整型指针)。8.6指针数组与指向指针的指针一、指针数组1、指针数组的概念指针数组是一种特殊的数组,它每个元素的类型都是指针类型(即地址),其它与一般数组相同。2、指针数组的定义类型名*指针数组名[常量表达式];如:int*ap[3];char*s[10];等等。每个元素ap[i]都等同于一个普通整型指针变量,可把某个量的地址赋给该元素(指针变量),该元素即指向那个变量,即可通过该元素对相应的变量进行间接访问。8.6指针数组与指向指针的指针3、指针数组的初始化(1)inta1[5],a2[5],a3[5],*ap[3]={a1,a2,a3};(2)char*sp[]={“abc”,“123”,“Hello”};4、指针数组的赋值上面的情况中,可以先定义变量,再进行赋值,即(1)inta1[5],a2[5],a3[5],*ap[3];

ap[0]=a1;ap[1]=a2;ap[2]=a3;(2)char*sp[3];

sp[0]=“abc”;sp[1]=“123”;sp[2]=“Hello”;例8.13显示多个字符串#include<stdio.h>

main()

{

staticchar*ap[3]={“CPU”,“Computer”,“Microprocessor”};

inti;

for(i=0;i<3;i++)puts(ap[i]);

}//以上用指针数组实现#include<stdio.h>

main()

{

staticcharaa[3][15]={“CPU”,“Computer”,“Microprocessor”};

inti;

for(i=0;i<3;i++)puts(aa[i]);

}//以上用二维字符数组实现8.6指针数组与指向指针的指针两种方法中所占内存空间的比较CPU\0Computer\0Microprocessor\0ap[0]ap[1]ap[2]aa[0]aa[1]aa[2]apCPU\0Computer\0Microprocessor\08.6指针数组与指向指针的指针8.6指针数组与指向指针的指针二、指向指针的指针2、多级指针的定义类型标识符**指针变量名;

注:*的个数代表级数,要求掌握到二级即可。如:char**pp,*p,ch=‘A’;又p=&ch;pp=&p;则:1、多级指针的概念所谓多级指针,是指指针有多级指向关系。&p&ch‘A’pppch8.6指针数组与指向指针的指针3、多级指针的含义若定义:char*ps[]={“abc”,“123”,“asd”},**pp=ps;则:*pp为ps[0],即指向“abc”当执行了pp++后,*pp为ps[1],即指向“123”或*(pp+1)为ps[1],即指向“123”*(pp+2)为ps[2],即指向“asd”二级指针通常用来访问字符型的指针数组,即访问由指针数组指向的多个字符串。例8.14显示并选择菜单条目#include<stdio.h>

intgetchoice(char**menu,intn);

main()

{

intchc;

staticchar*mn[5]={“1.Input”,“2.Copy”,

“3.Move”,“4.Delete”,

“5.Exit”};

chc=getchoice(mn,5);

if(chc>=0&&chc<5)printf(“YouchoiceNo.is%s\n”,mn[chc-1]);

elseprintf(“Invalidchoice!\n”);

}8.6指针数组与指向指针的指针8-14.c传递的是指针数组的首地址,或二维字符数组的首地址。n代表的是字符串的个数。intgetchoice(char**menu,intn)

{

inti,choice;

for(i=0;i<n;i++){puts(*menu);menu++;}printf(\nInputyourchoice:”);

scanf(“%d”,&choice);

return(choice);}8.6指针数组与指向指针的指针8.6指针数组与指向指针的指针三、命令行参数1、命令行参数的概念1)DOS命令:copyfile1file22)以前的main函数形式:main()3)带参main函数:

main(intargc,char**argv);或

main(intargc,char*argv[]);或

main(intargc,charargv[][]);8.6指针数组与指向指针的指针2、命令行参数的说明1)形参也可以用其它名字,习惯上为argc和argv2)argc和argv的值得获得注:main函数的调用由系统完成,所以执行程序时给出的命令行参数是实参。如有程序myprog.c,经编译和链接生成可执行程序myprog.exe,在命令行中输入:

myprogargument1argument28.6指针数组与指向指针的指针例:myprogargument1argument2则argc的值为3,argv[0]的值为“myprog”,argv[1]的值为“argument1”,argv[2]的值为“argument2”。3)实现:DOS提示符状态下或集成环境中。例8.15输出各命令行参数#include<stdio.h>

main(intargc,char**argv)

{inti;

for(i=1;i<argc;i++)printf(“arg%d:%s\n”,i,argv[i]);

}8.6指针数组与指向指针的指针该节结束,返回目录执行或*(argv+i)若可执行文件为myprog,运行时键入:myprogComputerandClanguage则输出为:arg1:Computer

arg2:and

arg3:C

arg4:language8.7返回指针值的函数1、概念当函数的返回值是指针类型(地址)时,则称为指针函数。2、定义类型名*函数名(形参表);如:int*f(inta);等等。源程序例8.16:编写函数

char*mystrchr(char*str,charch);

功能是在str中查找字符ch,返回ch第一次出现的地址,如果找不到,返回空指针NULL。(8_16.c或8_16_2.c)例8.17将一个字符串转换为大写形式并输出#include<stdio.h>

char*mytoupper(char*s);

main()

{charps[80],*s;

gets(ps);s=mytoupper(ps);puts(s);

}

char*mytoupper(char*s)

{

char*t=s;

while(*t!=‘\0’){*t=(*t>=‘a’&&*t<=‘z’)?*t-32:*t;t++;}

return(s);

}8.7返回指针值的函数该节结束,返回目录动态内存分配8.8指向函数的指针1、函数名的含义函数名代表一个地址,它是函数的入口,即函数代码在内存中的起始位置,是一个指针常量,类似于数组名。2、概念如果一个指针指向一个函数,则称该指针为函数指针。(注意与指针函数的区别)3、定义

类型名(*指针变量名)(形参表);如:int(*f)(inta,intb);例8.17函数指针举例#include<stdio.h>

intmax(inta,intb);

intmin(inta,intb);

main()

{intx=3,y=4,z;

int(*pf)(int,int);

pf=max;z=(*pf)(x,y);printf(maxis%d\n”,z);

pf=min;printf(“minis%d\n,(*pf)(x,y));

}

intmax(inta,intb)

{return(a>b?a:b);}

intmin(inta,intb)

{return(a<b?a:b);}8.8指向函数的指针该节结

温馨提示

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

评论

0/150

提交评论