指针程序设计(一)
内容
说明
主要内容
1.指针与指针变量的概念
2.指针变量的定义、引用及运算
3.一维数组与指针
重点变量指针和一维数组指针
主要针对一维数组
重点讲解
通过此图讲解变量与地址的关系
通过例子说明指针变量的定义和初始化应注意的问题
重点
指针的概念变量指针和一维数组指针
3.指向变量、一维数组的指针变量
难点
1.变量指针和一维数组指针的引用
2.指向变量、一维数组的指针变量的引用
问题提出
定义变量系统会为变量开辟一定单元的存储空间,如何利用存储空间解决变量的运算问题呢?
一、间接访问与直接访问举例:打开A抽屉方法直接访问:将A钥匙带在身上,需要时直接打开间接访问:将A钥匙放在B抽屉,需要时,打开B抽屉取出A钥匙,打开A抽屉。
二、指针
1.什么是指针定义:指针就是地址。
2.内存单元和地址内存单元地址:计算机内部存储器由很多内存单元组成,每个内存单元都有自己独有的地址,称内存单元地址。
3.变量与地址当一个变量只占用一个内存单元时,内存单元的地址就是变量的地址;当变量占用连续的若干个内存单元时,最前面一个单元的地址就是该变量的地址。
例:int i=3;float f;
变量i的地址:2001,变量f的地址:2008
由于地址起到寻找操作对象的作用,像一个指向对象的指针,所以常把地址称为“指针”。
4.数组与地址数组元素占用连续的内存单元。数组类型不同,每个数组元素占用的内存单元数也不同。数组占用的总单元数等于数组长度×每个数组元素占用的内存单元数。
数组元素a[0]的地址称为数组的首地址。
数组元素a[i]的地址=数组首地址+i×数组元素的数据类型所占用的内存单元数
例:int a[3]={1,2,3};
三、指针变量
1.什么是指针变量定义:存放地址的变量称为“指针变量”。
2.指针变量的定义和初始化指针变量在使用前必须定义,定义的同时可以赋初值。
【格式】存储类型 数据类型 *指针变量名1[=初值1],…;
【功能】定义指向指定“数据类型”或数组的若干个指针变量,同时给这些变量赋初值。
例:int a;int *p=&a;float f1,f[10],*p1=&f1,*p2=f;
3.指针变量的引用方式
(1)给指针变量赋值
【格式】指针变量=地址表达式例,int i,*p;p=&i;
(2)直接引用指针变量名例:int i,j,*p=&i,*q;q=p;scanf(“%d,%d”,q,&j);
(3)通过指针变量来引用它所指向的变量
【格式】*指针变量名例如:int i=1,j=2,k,*p=&i;k=*p+j;
四、取地址运算符与指针运算符取地址运算符(&):取运算对象的地址。如&a
指针运算符(*):取指针变量所指向的变量或数组元素的值。
例如:int *p,a;p=&a;则*p= =a为真。
【例】利用指针,求两个整数的和。
main( )
{ int i,j,sum ;
int *p,*q; /*定义指针变量*/
p=&i; q=&j; /*建立关联*/
scanf(″%d,%d″,p,q);
sum=*p+*q; /*使用指针变量*/
printf (″%d,%d\n″,*p,*q);
printf(″和= %d \n″,sum);
}
五、用指针变量引用一维数组元素如何将指针变量指向数组的首地址?
(1)初始化:数据类型 *指针变量=数组名
(2)程序中赋值:指针变量=数组名
(3)若指针变量指向某数组元素:*指针变量=&数组名[下标]
1.用指向数组元素的指针变量处理数组元素
(1)当指针变量指向数组的首地址,引用数组元素的方法
引用“数组元素[0]”,*(指针变量+0)或*指针变量
引用“数组元素[i]”,*(指针变量+i)
(2)当指针变量指向下标为i的数组元素,引用数组元素的方法
引用“数组元素[i]”,*(指针变量+0)或*指针变量
引用“数组元素[i-k]”,*(指针变量-k)
引用“数组元素[i+k]”,*(指针变量+k)
(3)当指针变量指向数组首地址,对下标i的数组元素引用方法
① *(指针变量+i)②*(数组名+i)③ 指针变量[i]④数组名[i]
2.指向数组元素的指针变量的运算
(1)指针变量算术运算指针变量+整数 指针变量-整数 ++指针变量 --指针变量 指针变量++ 指针变量-- 指针变量1-指针变量2
(2)指针变量的关系运算指针变量1 关系运算符 指针变量2
【例】指针法实现数组的输入,输出
main( )
{ int a[10];
int i,*p; /*定义指针变量*/
p=a; /*建立关联*/
for(i=0; i<10; i++)
scanf (″%d″,p++);
printf(″\n″);
for (p=a; p<a+10; p++) /*使用*/
printf(″%3d″,*p);
}
实例讲解
举例
两个指针变量必须指向同一数组
六、小结本节主要讲述了指针与指针变量的概念、指针变量的定义、引用及运算以及指向一维数组的指针变量的定义和应用。重点是对变量指针和一维数组指针概念的理解。
七、作业
教师自留
指针程序设计(二)
内容
说明
主要内容
1.二维数组与指针
2.字符串与指针
3.字符指针与字符数组的区别
主要讲字符指针
先复习指针在一维数组中的应用
重点
指向字符串的指针变量的引用字符指针与字符数组的区别
难点
指向字符串的指针变量字符指针与字符数组的不同用法
问题引入
前面学习了指针的概念、指针在一维数组中的应用方法,那么如何使用指针变量解决字符串的操作问题?
使用指针表示二维数组二维数组元素的地址
int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};
二维数组a[3][4]可看成由3个一维数组a[0]、a[1]、a[2]组成,每个一维数组由4个元素组成。如下图所示。
a代表二维数组首元素的地址,a[0]、a[1]、a[2]是一维数组名,而C语言规定数组名代表数组首元素的地址,即a[0]等于&a[0][0]、a[1]等于&a[1][0]、a[2]等于&a[2][0]。
2、使用指针表示二位数组元素进一步分析:a[0]等于&a[0][0],a[0]+1等于&a[0][1],a[0]+2等于&a[0][2],a[0]+3等于&a[0][3]。
因为a[0]和*(a+0)等价,a[1]和*(a+1)等价,a[i]和*(a+i)等价,因此:
a[0]+1等价 *(a+0)+1等价 &a[0][1]
a[1]+2等价 *(a+1)+2等价 &a[1][2]
注意:不要将*(a+1)+2 错写成*(a+1+2)相当 a[3]。
进一步分析:因为&a[0][1]等价a[0]+1等价 *(a+0)+1,那么*(*(a+0)+1)或*(*a+1)等价a[0][1]的值。*(a[i]+j)或*(*a+i)+j)等价a[i][j]的值二、用指针变量引用二维数组元素
1.用指向数组元素的指针变量引用二维数组元素,此种方法是将二维数组当作一维数组来处理。
例1:用指针变量输出数组元素的值。
main()
{int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int *p;
for(p=a[0];p<a[0]+12;p++)
{if((p-a[0])%4==0) printf(“\n”);
printf(“%4d”,*p);
}
}
2.用指向由m个元素组成的一维数组的指针变量引用二维数组元素为了和二维数组名相对应,可以定义一个行指针变量来引用二维数组元素。
定义行指针的一般形式为:
类型 (*指针变量名)[M]
如int (*p)[4]
表示定义了一个指向包含4个整型元素的一维数组的指针变量。
例2:输出二维数组任一行任一列元素的值。
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));
}
三、指向字符串的指针变量的使用
1.将指针变量指向字符串常量的方法例:将字符指针变量p指向“abcd”
方法一:初始化形式数据类型 *指针变量=字符串常量 char *p=“abcd”;
方法二:赋值语句指针变量=字符串常量 char *p;p=“abcd”;
2.指向字符串常量的指针变量的使用
(1)处理整个字符串
输出字符串 printf(“%s“,指针变量);
输入新的字符串代替原字符串 scanf(“%s”,指针变量);
(2)处理字符串中的单个字符
第i个字符的表示方法,*(指针变量+i)
3.指向存放字符串的字符数组的指针变量的使用处理字符串中的单个字符就是处理一维数组的元素,方法同处理一维数组元素。
注意:字符数组元素的类型是字符型。
注意两种输出方式的不同
举例说明
【例】 用字符数组实现字符串的复制。
main()
{
char a[]="I love my Motherland !",b[40];
int i=0;
while(a[i]!= '\0'))
{ b[i]=a[i];
i++; }
b[i]= '\0';
printf("%s",b);
}
在例题中使用的是字符数组,由于复制的是字符串,所以在字符元素复制完成之后,要置一个字符串结束标志'\0'。
【例】 用字符指针实现字符串的复制。
main()
{
char *a="I love my Motherland !",b[40],*p1,*p2;
p1=a;
p2=b;
printf("%s",p1);
while(*p1)
*p2++=*p1++;
*p2='\0';
printf("%s",b);
}
在上例中使用的是字符指针,虽然源字符串可以用指针变量定义,但目标字符串必须用字符数组来定义。因为指针变量只能定义一个保存字符串首地址的指针,而没有保存字符的空间。如:
main()
{
char *a="I love my Motherland !",*b,*p1,*p2;
p1=a;
p2=b;
printf("%s",p1);
while(*p1)
*p2++=*p1++;
*p2='\0';
printf("%s",b);
}
则是错误的,有可能造成系统崩溃。
强调语句
b[i]='\0';
的作用
让学生将该程序改编为“将字符数组a中的ASCII码为奇数的字符复制到b数组中去。”
将循环部分改写为用for语句实现。
强调该例与上例的异同。
当然该程序还可以写得更简洁些:
main()
{
char *a="I love my Motherland !",b[40],*p1,*p2;
p1=a;
p2=b;
printf("%s",p1);
while(*p2++=*p1++);
printf("%s",b);
}
四、字符指针与字符数组的区别虽然字符数组和字符指针变量都能实现对字符串的存储和运算,但二者有本质的区别。
1.字符数组只能在初始化时赋初值,而不能在语句中赋值。
例如,
char a[]="I love my Motherland!";
而不能char a[30]
a="I love my Motherland!";
字符指针变量不仅可以初始化,也可以在语句中为其赋值。
如:
char *a="I love my Motherland!";
又可以
char *a;
a="I love my Motherland!";
2.字符数组既有确定的首地址,也有存储字符的空间;而字符指针变量只能保存一个字符串的首地址,在未指向具体字符串或字符数组之前,是没有保存字符的空间的。
如:
char *t;
scanf("%s",t); 是错误的,有可能造成系统崩溃。
举例
五、小结本节主要讲述了指向字符串的指针变量的引用;字符指针与字符数组的区别。重点要掌握指向字符串的指针变量的引用方法以及字符指针与字符数组的不同用法,这也是本章的难点。并对指向二维数组的指针变量的引用方法做简单了解。
六、作业
指针程序设计(三)
内容
说明
主要内容
精选习题引导学生利用指针进行程序设计
在交换存储单元的内容时,使用的中间变量temp不能为指针变量。
强调变量temp的作用
数组名法也即位移法
与数组名法对比说明
强调语句
b[j]=0;与
b[i]='\0';
的异同
将循环部分改写为用for语句实现。
可根据不同教学班学生掌握的情况增删例题
教师自留
重点
变量指针的引用实例指向一维数组的指针变量的引用实例指向字符串的指针变量的引用实例
难点
指向一维数组的指针变量的用法指向字符串的指针变量的用法
前面学习了指针的概念、指针在一维数组和字符串中的应用理念,那么如何在程序设计中灵活使用指针变量解决具体问题?
一、程序设计举例
【例1】 输入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("\n a=%d,b=%d",a,b);
printf("\n min=%d,max=%d",*p1,*p2);
}
程序运行时若输入:
30 20↙
则程序输出结果为:
a=30,b=20
min=20,max=30
由于输入后a>b,所以p1与p2交换。交换前后的情况分别见图1(a) 和图1(b)。
(a) (b)
图1
注意:指针变量未指向具体变量时,不可使用间接访问方式为其赋值。
【例2】 输入a和b两个整数,按从小到大的顺序输出。
main()
{
int *p1,*p2,a,b,temp;
p1=&a;p2=&b;
scanf("%d%d",p1,p2);
if(*p1>*p2)
{ temp=*p1; *p1=*p2; *p2=temp; }
printf("\n min=%d,max=%d",a,b);
}
【例3】 用数组名法从键盘接收并输出数组元素。
main()
{
int a[10],i;
for(i=0;i<10;i++)
scanf("%d",a+i);
for(i=0;i<10;i++;)
printf("%4d",* (a+i));
}
【例4】 用指针变量法从键盘接收并输出数组元素。
main()
{
int a[10],i,*p;
for(p=a;p<a+10;p++)
scanf(“%d”,p);
for(p=a;p<a+10;)
printf("%4d",*p++);
}
在例3中,是通过数组名来访问数组元素的,这种方法可以称为数组名法。实际上它与下标法没有什么不同,只是书写上有区别而已。而在例4中,是通过指针变量来访问数组元素的,这种方法可以称为指针变量法。在例7.4中,由于在接收数组元素的过程中,使用了p++,每循环一次指针变量p的指向向下移动一个元素,所以在第一个for循环结束时,p已指向最后一个元素a[9]的下一个存储单元,因而在第二个循环开始时,指针变量p必须重新赋值,使p指向数组的第一个元素,即p=a或p=&a[0]。而在第二个for循环中,使用了*p++。由于++与*优先级相同,结合方向为自右至左,因此它等价于*(p++),其作用是先取p所指向变量的值,然后再执行p=p+1。与前面介绍的(*p)++的作用有本质区别。而表达式 *(++p),是先执行p=p+1,而后再引用p所指变量的内容。
【例5】 若有字符串“ab*cde*fg*****”,删除字符串最后的“*”,删除后的字符串为“ab*cde*fg”。
main()
{ char *q="ab*cde*fg*****";
char b[20],*p;
int i,j,len;
clrscr();
len=strlen(q);
i=0;
for(p=q+len-1;*p=='*';p--)
i++;
for(j=0;j<len-i;j++)
b[j]=q[j];
b[j]=0;
printf("len=%d,i=%d,%s",len,i,b); }
【例6】从字符串s1中找出子串s2出现的次数。如s1为“dddsdfsded”,s2为“sdf”,则查找结果为1。
main()
{
char *s1="dddsdfsded",*s2="sdf";
int k,m,count=0;
clrscr();
k=strlen(s2);
for(;*s1!=0;)
{ m=0;
while(*s1= =*s2 && m<k) {m++;s2++;s1++;}
if(m= =k) count++;
else
{s2="sdf";s1++;} }
printf("%d",count);
}
总结与作业
二、小结
⑴ 指针就是地址,指针变量就是存放地址的变量。通过指针变量可以实现对变量的“间接访问”。
⑵ 一维数组名代表数组第一个元素的地址,且数组元素在内存中是连续存放的。数组元素不仅可以用下标方式进行访问,还可以使用指针方式进行访问。
⑶ 字符数组和字符指针与一维数组和指针的关系没有什么特别之处,只是字符指针可以直接定义字符串常量。
三、作业
内容
说明
主要内容
1.指针与指针变量的概念
2.指针变量的定义、引用及运算
3.一维数组与指针
重点变量指针和一维数组指针
主要针对一维数组
重点讲解
通过此图讲解变量与地址的关系
通过例子说明指针变量的定义和初始化应注意的问题
重点
指针的概念变量指针和一维数组指针
3.指向变量、一维数组的指针变量
难点
1.变量指针和一维数组指针的引用
2.指向变量、一维数组的指针变量的引用
问题提出
定义变量系统会为变量开辟一定单元的存储空间,如何利用存储空间解决变量的运算问题呢?
一、间接访问与直接访问举例:打开A抽屉方法直接访问:将A钥匙带在身上,需要时直接打开间接访问:将A钥匙放在B抽屉,需要时,打开B抽屉取出A钥匙,打开A抽屉。
二、指针
1.什么是指针定义:指针就是地址。
2.内存单元和地址内存单元地址:计算机内部存储器由很多内存单元组成,每个内存单元都有自己独有的地址,称内存单元地址。
3.变量与地址当一个变量只占用一个内存单元时,内存单元的地址就是变量的地址;当变量占用连续的若干个内存单元时,最前面一个单元的地址就是该变量的地址。
例:int i=3;float f;
变量i的地址:2001,变量f的地址:2008
由于地址起到寻找操作对象的作用,像一个指向对象的指针,所以常把地址称为“指针”。
4.数组与地址数组元素占用连续的内存单元。数组类型不同,每个数组元素占用的内存单元数也不同。数组占用的总单元数等于数组长度×每个数组元素占用的内存单元数。
数组元素a[0]的地址称为数组的首地址。
数组元素a[i]的地址=数组首地址+i×数组元素的数据类型所占用的内存单元数
例:int a[3]={1,2,3};
三、指针变量
1.什么是指针变量定义:存放地址的变量称为“指针变量”。
2.指针变量的定义和初始化指针变量在使用前必须定义,定义的同时可以赋初值。
【格式】存储类型 数据类型 *指针变量名1[=初值1],…;
【功能】定义指向指定“数据类型”或数组的若干个指针变量,同时给这些变量赋初值。
例:int a;int *p=&a;float f1,f[10],*p1=&f1,*p2=f;
3.指针变量的引用方式
(1)给指针变量赋值
【格式】指针变量=地址表达式例,int i,*p;p=&i;
(2)直接引用指针变量名例:int i,j,*p=&i,*q;q=p;scanf(“%d,%d”,q,&j);
(3)通过指针变量来引用它所指向的变量
【格式】*指针变量名例如:int i=1,j=2,k,*p=&i;k=*p+j;
四、取地址运算符与指针运算符取地址运算符(&):取运算对象的地址。如&a
指针运算符(*):取指针变量所指向的变量或数组元素的值。
例如:int *p,a;p=&a;则*p= =a为真。
【例】利用指针,求两个整数的和。
main( )
{ int i,j,sum ;
int *p,*q; /*定义指针变量*/
p=&i; q=&j; /*建立关联*/
scanf(″%d,%d″,p,q);
sum=*p+*q; /*使用指针变量*/
printf (″%d,%d\n″,*p,*q);
printf(″和= %d \n″,sum);
}
五、用指针变量引用一维数组元素如何将指针变量指向数组的首地址?
(1)初始化:数据类型 *指针变量=数组名
(2)程序中赋值:指针变量=数组名
(3)若指针变量指向某数组元素:*指针变量=&数组名[下标]
1.用指向数组元素的指针变量处理数组元素
(1)当指针变量指向数组的首地址,引用数组元素的方法
引用“数组元素[0]”,*(指针变量+0)或*指针变量
引用“数组元素[i]”,*(指针变量+i)
(2)当指针变量指向下标为i的数组元素,引用数组元素的方法
引用“数组元素[i]”,*(指针变量+0)或*指针变量
引用“数组元素[i-k]”,*(指针变量-k)
引用“数组元素[i+k]”,*(指针变量+k)
(3)当指针变量指向数组首地址,对下标i的数组元素引用方法
① *(指针变量+i)②*(数组名+i)③ 指针变量[i]④数组名[i]
2.指向数组元素的指针变量的运算
(1)指针变量算术运算指针变量+整数 指针变量-整数 ++指针变量 --指针变量 指针变量++ 指针变量-- 指针变量1-指针变量2
(2)指针变量的关系运算指针变量1 关系运算符 指针变量2
【例】指针法实现数组的输入,输出
main( )
{ int a[10];
int i,*p; /*定义指针变量*/
p=a; /*建立关联*/
for(i=0; i<10; i++)
scanf (″%d″,p++);
printf(″\n″);
for (p=a; p<a+10; p++) /*使用*/
printf(″%3d″,*p);
}
实例讲解
举例
两个指针变量必须指向同一数组
六、小结本节主要讲述了指针与指针变量的概念、指针变量的定义、引用及运算以及指向一维数组的指针变量的定义和应用。重点是对变量指针和一维数组指针概念的理解。
七、作业
教师自留
指针程序设计(二)
内容
说明
主要内容
1.二维数组与指针
2.字符串与指针
3.字符指针与字符数组的区别
主要讲字符指针
先复习指针在一维数组中的应用
重点
指向字符串的指针变量的引用字符指针与字符数组的区别
难点
指向字符串的指针变量字符指针与字符数组的不同用法
问题引入
前面学习了指针的概念、指针在一维数组中的应用方法,那么如何使用指针变量解决字符串的操作问题?
使用指针表示二维数组二维数组元素的地址
int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};
二维数组a[3][4]可看成由3个一维数组a[0]、a[1]、a[2]组成,每个一维数组由4个元素组成。如下图所示。
a代表二维数组首元素的地址,a[0]、a[1]、a[2]是一维数组名,而C语言规定数组名代表数组首元素的地址,即a[0]等于&a[0][0]、a[1]等于&a[1][0]、a[2]等于&a[2][0]。
2、使用指针表示二位数组元素进一步分析:a[0]等于&a[0][0],a[0]+1等于&a[0][1],a[0]+2等于&a[0][2],a[0]+3等于&a[0][3]。
因为a[0]和*(a+0)等价,a[1]和*(a+1)等价,a[i]和*(a+i)等价,因此:
a[0]+1等价 *(a+0)+1等价 &a[0][1]
a[1]+2等价 *(a+1)+2等价 &a[1][2]
注意:不要将*(a+1)+2 错写成*(a+1+2)相当 a[3]。
进一步分析:因为&a[0][1]等价a[0]+1等价 *(a+0)+1,那么*(*(a+0)+1)或*(*a+1)等价a[0][1]的值。*(a[i]+j)或*(*a+i)+j)等价a[i][j]的值二、用指针变量引用二维数组元素
1.用指向数组元素的指针变量引用二维数组元素,此种方法是将二维数组当作一维数组来处理。
例1:用指针变量输出数组元素的值。
main()
{int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int *p;
for(p=a[0];p<a[0]+12;p++)
{if((p-a[0])%4==0) printf(“\n”);
printf(“%4d”,*p);
}
}
2.用指向由m个元素组成的一维数组的指针变量引用二维数组元素为了和二维数组名相对应,可以定义一个行指针变量来引用二维数组元素。
定义行指针的一般形式为:
类型 (*指针变量名)[M]
如int (*p)[4]
表示定义了一个指向包含4个整型元素的一维数组的指针变量。
例2:输出二维数组任一行任一列元素的值。
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));
}
三、指向字符串的指针变量的使用
1.将指针变量指向字符串常量的方法例:将字符指针变量p指向“abcd”
方法一:初始化形式数据类型 *指针变量=字符串常量 char *p=“abcd”;
方法二:赋值语句指针变量=字符串常量 char *p;p=“abcd”;
2.指向字符串常量的指针变量的使用
(1)处理整个字符串
输出字符串 printf(“%s“,指针变量);
输入新的字符串代替原字符串 scanf(“%s”,指针变量);
(2)处理字符串中的单个字符
第i个字符的表示方法,*(指针变量+i)
3.指向存放字符串的字符数组的指针变量的使用处理字符串中的单个字符就是处理一维数组的元素,方法同处理一维数组元素。
注意:字符数组元素的类型是字符型。
注意两种输出方式的不同
举例说明
【例】 用字符数组实现字符串的复制。
main()
{
char a[]="I love my Motherland !",b[40];
int i=0;
while(a[i]!= '\0'))
{ b[i]=a[i];
i++; }
b[i]= '\0';
printf("%s",b);
}
在例题中使用的是字符数组,由于复制的是字符串,所以在字符元素复制完成之后,要置一个字符串结束标志'\0'。
【例】 用字符指针实现字符串的复制。
main()
{
char *a="I love my Motherland !",b[40],*p1,*p2;
p1=a;
p2=b;
printf("%s",p1);
while(*p1)
*p2++=*p1++;
*p2='\0';
printf("%s",b);
}
在上例中使用的是字符指针,虽然源字符串可以用指针变量定义,但目标字符串必须用字符数组来定义。因为指针变量只能定义一个保存字符串首地址的指针,而没有保存字符的空间。如:
main()
{
char *a="I love my Motherland !",*b,*p1,*p2;
p1=a;
p2=b;
printf("%s",p1);
while(*p1)
*p2++=*p1++;
*p2='\0';
printf("%s",b);
}
则是错误的,有可能造成系统崩溃。
强调语句
b[i]='\0';
的作用
让学生将该程序改编为“将字符数组a中的ASCII码为奇数的字符复制到b数组中去。”
将循环部分改写为用for语句实现。
强调该例与上例的异同。
当然该程序还可以写得更简洁些:
main()
{
char *a="I love my Motherland !",b[40],*p1,*p2;
p1=a;
p2=b;
printf("%s",p1);
while(*p2++=*p1++);
printf("%s",b);
}
四、字符指针与字符数组的区别虽然字符数组和字符指针变量都能实现对字符串的存储和运算,但二者有本质的区别。
1.字符数组只能在初始化时赋初值,而不能在语句中赋值。
例如,
char a[]="I love my Motherland!";
而不能char a[30]
a="I love my Motherland!";
字符指针变量不仅可以初始化,也可以在语句中为其赋值。
如:
char *a="I love my Motherland!";
又可以
char *a;
a="I love my Motherland!";
2.字符数组既有确定的首地址,也有存储字符的空间;而字符指针变量只能保存一个字符串的首地址,在未指向具体字符串或字符数组之前,是没有保存字符的空间的。
如:
char *t;
scanf("%s",t); 是错误的,有可能造成系统崩溃。
举例
五、小结本节主要讲述了指向字符串的指针变量的引用;字符指针与字符数组的区别。重点要掌握指向字符串的指针变量的引用方法以及字符指针与字符数组的不同用法,这也是本章的难点。并对指向二维数组的指针变量的引用方法做简单了解。
六、作业
指针程序设计(三)
内容
说明
主要内容
精选习题引导学生利用指针进行程序设计
在交换存储单元的内容时,使用的中间变量temp不能为指针变量。
强调变量temp的作用
数组名法也即位移法
与数组名法对比说明
强调语句
b[j]=0;与
b[i]='\0';
的异同
将循环部分改写为用for语句实现。
可根据不同教学班学生掌握的情况增删例题
教师自留
重点
变量指针的引用实例指向一维数组的指针变量的引用实例指向字符串的指针变量的引用实例
难点
指向一维数组的指针变量的用法指向字符串的指针变量的用法
前面学习了指针的概念、指针在一维数组和字符串中的应用理念,那么如何在程序设计中灵活使用指针变量解决具体问题?
一、程序设计举例
【例1】 输入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("\n a=%d,b=%d",a,b);
printf("\n min=%d,max=%d",*p1,*p2);
}
程序运行时若输入:
30 20↙
则程序输出结果为:
a=30,b=20
min=20,max=30
由于输入后a>b,所以p1与p2交换。交换前后的情况分别见图1(a) 和图1(b)。
(a) (b)
图1
注意:指针变量未指向具体变量时,不可使用间接访问方式为其赋值。
【例2】 输入a和b两个整数,按从小到大的顺序输出。
main()
{
int *p1,*p2,a,b,temp;
p1=&a;p2=&b;
scanf("%d%d",p1,p2);
if(*p1>*p2)
{ temp=*p1; *p1=*p2; *p2=temp; }
printf("\n min=%d,max=%d",a,b);
}
【例3】 用数组名法从键盘接收并输出数组元素。
main()
{
int a[10],i;
for(i=0;i<10;i++)
scanf("%d",a+i);
for(i=0;i<10;i++;)
printf("%4d",* (a+i));
}
【例4】 用指针变量法从键盘接收并输出数组元素。
main()
{
int a[10],i,*p;
for(p=a;p<a+10;p++)
scanf(“%d”,p);
for(p=a;p<a+10;)
printf("%4d",*p++);
}
在例3中,是通过数组名来访问数组元素的,这种方法可以称为数组名法。实际上它与下标法没有什么不同,只是书写上有区别而已。而在例4中,是通过指针变量来访问数组元素的,这种方法可以称为指针变量法。在例7.4中,由于在接收数组元素的过程中,使用了p++,每循环一次指针变量p的指向向下移动一个元素,所以在第一个for循环结束时,p已指向最后一个元素a[9]的下一个存储单元,因而在第二个循环开始时,指针变量p必须重新赋值,使p指向数组的第一个元素,即p=a或p=&a[0]。而在第二个for循环中,使用了*p++。由于++与*优先级相同,结合方向为自右至左,因此它等价于*(p++),其作用是先取p所指向变量的值,然后再执行p=p+1。与前面介绍的(*p)++的作用有本质区别。而表达式 *(++p),是先执行p=p+1,而后再引用p所指变量的内容。
【例5】 若有字符串“ab*cde*fg*****”,删除字符串最后的“*”,删除后的字符串为“ab*cde*fg”。
main()
{ char *q="ab*cde*fg*****";
char b[20],*p;
int i,j,len;
clrscr();
len=strlen(q);
i=0;
for(p=q+len-1;*p=='*';p--)
i++;
for(j=0;j<len-i;j++)
b[j]=q[j];
b[j]=0;
printf("len=%d,i=%d,%s",len,i,b); }
【例6】从字符串s1中找出子串s2出现的次数。如s1为“dddsdfsded”,s2为“sdf”,则查找结果为1。
main()
{
char *s1="dddsdfsded",*s2="sdf";
int k,m,count=0;
clrscr();
k=strlen(s2);
for(;*s1!=0;)
{ m=0;
while(*s1= =*s2 && m<k) {m++;s2++;s1++;}
if(m= =k) count++;
else
{s2="sdf";s1++;} }
printf("%d",count);
}
总结与作业
二、小结
⑴ 指针就是地址,指针变量就是存放地址的变量。通过指针变量可以实现对变量的“间接访问”。
⑵ 一维数组名代表数组第一个元素的地址,且数组元素在内存中是连续存放的。数组元素不仅可以用下标方式进行访问,还可以使用指针方式进行访问。
⑶ 字符数组和字符指针与一维数组和指针的关系没有什么特别之处,只是字符指针可以直接定义字符串常量。
三、作业