内容正文:
项目六 用指针优化学生成绩排名
项目要求
一个班有40位学生参加了期终考试(考了三门课),请用指针优化学生成绩排名。即用指针实现数组的输入输出以及数组的排序(在函数中进行)。
项目分析
要用指针优化学生成绩排名,第一必须要了解指针的概念、引用;第二必须会用指针实现数组的输入输出;第三在函数中用指针实现数组的排序,然后调用此函数。为了在介绍的时候条理清晰,所以分解成5个任务。
任务1 了解指针
一、任务提出
一个班进行了一次考试,现要将几个学生的成绩输入,用指针的方式输出。
二、具体实现
#include <stdio.h>
void main()
{ int *p1,*p2,a,b;
printf("输入:");
scanf("%d,%d",&a,&b);
p1=&a;p2=&b;
printf("输出:");
printf("a=%d,b=%d
",a,b);
printf("*p1=%d,*p2=%d
",*p1,*p2);
}
程序运行后显示器上的结果为:
输入:5,6
输出:a=5,b=6
*p1=5,*p2=6
知识点:
1、指针的概念;
2、指针的引用;
三、相关知识
(一) 地址和指针的概念
计算机内存空间是由顺序排列的以字节为单位的存储单元,将这些存储单元从0开始顺序编号,这些编号就构成了每个存储单元的地址,如图
每个变量名都与一个唯一的地址相对应,因此我们对变量的访问实质上还是通过地址来进行数据的存取。
指针是存储特定数据类型的地址。该地址处存放的数据也形象地称为”指针所指向的数据”。
指针也有类型。指针的类型就是指针所指向的数据的类型。指针的类型限定指针的用途,
(二)指向变量的指针变量
1. 指针变量的定义
用来存放数据地址的变量叫指针变量。
定义格式:
类型标识符 *变量名[=地址表达式]
其中:类型标识符是指针变量所指向单元的值的数据类型。
“*”指针变量的定义符;
“变量名”命名规则同一般变量,但表示一个地址;
如:int x, *pointer1;pointer1=&x;则pointer1表示x的内存地址。
2. 指针变量的初始化:在定义变量的同时给指针变量赋地址值。
int x=3;
float y;
int *pointer1=&x;
float *pointer2=&y;
指针变量没有指向一个具体的地址,这样的指针叫空指针,空指针是“危险”的。
3. 指针变量的引用
(1) &:取地址运算符
用于变量名之前,表示该变量的内存地址。
(2) *:指针运算符(间接访问运算符)
用于指针变量名之前,获取该指针所指向的目标单元的值。
在定义变量时用“*”号,表示定义了一个指针变量,在引用时用“*”号,表示间接运算。
4. 指针变量的算术运算
含义:对于地址的运算,只能进行整型数据的加、减运算。
p=p+n;p=p-n
注意p+n不是加(减)n个字节,而是加(减)n个数据单元。
#include <stdio.h>
void main()
{
int a,b,*pointer_1,*pointer_2;
a=100,b=200;
pointer_1=&a;
pointer_2=&b;
printf("%d,%d
",a,*pointer_1);
printf("%d,%d
",b,*pointer_2);
}
程序运行结果:
100,100
200,200
【例6-1】指针与地址的应用
5.“&”和“*”两个运算符
“&”和“*”两个运算符的优先级别是相同的,结合规律是右结合性:
若point1=&a; 则 &*point1等价于&a;*&a 等价于 a;
在定义指针变量时,还未规定它指向哪一个变量,此时不能用*运算符访问指针。
int a;
int *p; /*未规定指向哪个变量*/
*p=289;
int a;
int *p=&a;
*p=289;
【例6-2】输入两个学生的成绩,按从小到大的顺序输出。
#include <stdio.h>
void main()
{ int *p1,*p2,*p,a,b;
printf("输入:");
scanf("%d,%d",&a,&b);
p1=&a;p2=&b;
if(a>b)
{p=p1;p1=p2;p2=p;}
printf("输出:");
printf("a=%d,b=%d
",a,b);
printf("min=%d,max=%d
",*p1,*p2);
}
程序提示:
p1=&a;p2=&b;
使p1指向a,p2指向b
if(a>b)
{p=p1;p1=p2;p2=p;}
如果a>b,则交换指针,即p1指向较小值,p2指向较大值
(三) 指针变量作为函数参数
函数可以通过return返回一个值,如果要函数返回多个值怎么办?
指针传递的方式来改变
【例6-3】用指针变量作为函数参数,实现数据的交换。
#include <stdio.h>
void swap(int *p1,int *p2)
/*用指针变量实现数据的交换*/
{
int temp;
temp=*p1;
*p1=*p2;
*p2=temp;
}
void main()
{ int a,b,*pointer_1,*pointer_2;
printf("输入a,b的值:");
scanf("%d,%d",&a,&b);
pointer_1=&a,pointer_2=&b;
if(a<b) //如果a<b交换两数
swap(pointer_1,pointer_2);
printf("调用函数后输出a,b的值为:");
printf("%d,%d
",a,b);
}
1. 指针变量作为参数,从调用函数向被调用函数传递的不是一个变量,而是变量的地址。
2. 指针变量作为函数的参数,从实参向形参的数据传递仍然遵循“单向值传递”的原则,只不过此时传递的是地址,因此对形参的任何操作都相当于对实参的操作。
【例6-4】输入a、b、c 3个整数,按从大到小顺序输出。
#include <stdio.h>
void swap(int *a,int *b)
{int t;
t=*a;
*a=*b;
*b=t;
}
void main()
{int a,b,c,*p1,*p2,*p3;
printf("请输入3个数,以逗号隔开:");
scanf("%d,%d,%d",&a,&b,&c);
p1=&a; p2=&b;p3=&c;
if(a<b)swap(p1,p2);
if(a<c)swap(p1,p3);
if(b<c)swap(p2,p3);
printf("从大到小的顺序为:");
printf("%d,%d,%d
",a,b,c);
}
程序的运行情况为:
程序提示:因为在swap()函数中交换的是指针所指向的值,所以在调用swap()函数后会导致二个数的交换。
举一反三
【例6-5】如果上例中的交换函数交换的是指针,则结果如何?即如下程序:
#include <stdio.h>
void swap(int *p1,int *p2)
{ int *temp;
temp=p1;
p1=p2;
p2=temp;
}
void main()
{ int a,b,*pointer_1,*pointer_2;
printf("输入a,b的值:");
scanf("%d,%d",&a,&b);
pointer_1=&a,pointer_2=&b;
swap(pointer_1,pointer_2);
printf("调用函数后输出a,b的值为:");
printf("%d,%d
",a,b);
printf("调用函数后输出*pointer_1,*pointer_2的值为:");
printf("%d,%d
",*pointer_1,*pointer_2);}
程序的运行情况为:
程序提示:因为在swap()函数中交换的是指针,不是指针所指向的值,所以在调用swap()函数后不会导致二个数的交换。即a,b维持原值不变,同样指针变量pointer_1,pointer_2所指向的值也保持不变。
任务2 用指针优化全班同学一门课成绩的输入输出
一、问题情景
一个班有40个同学进行了一次考试,现要用指针实现全班同学成绩的输入输出。
二、具体实现(以十个学生为例)
方法一:下标法(常用,很直观)
#include <stdio.h>
main()
{int score[10],i;
printf("请输入10个学生的成绩
");
for(i=0;i<10;i++)
scanf("%d",&score [i]);
printf("输出的10个学生的成绩为
");
for(i=0;i<10;i++)
printf("%3d", score [i]);
printf("
");
}
方法二:用数组名访问(效率与下标法相同,不常用)
#include <stdio.h>
main()
{int score[10],i;
printf("请输入10个学生的成绩
");
for(i=0;i<10;i++)
scanf("%d",& score [i]);
printf("输出的10个学生的成绩为
");
for(i=0;i<10;i++)
printf("%3d", *(score+i));
printf("
");
}
方法三:用指针变量访问(常用,效率高)
#include <stdio.h>
main()
{int score[10],*p,i;
printf("请输入10个学生的成绩
");
for(i=0;i<10;i++)
scanf("%d",& score [i]);
printf("输出的10个学生的成绩为
");
for(p=score;p<score+10;p++)
printf("%3d", *p);
printf("
");}
1、指向一维数组元素的指针;
2、一维数组元素的指针访问方式;
三、相关知识
(一) 指向数组元素的指针
int a[10],*p;
float b[10];
float *pf=&b[0];
*p=&a[0];
在数组中,数组名表示该数组在内存的起始地址。第一个元素的地址也是数组的起始地址。p=a;或者p=&a[0];等价。都代表数组的首地址。
1. 计算两地址间数据单元的个数(指针相减)。
int n,m[12],*p1=&m[5],*p2=&m[10];
n=p2-p1; //n=5
2. 指针移动
int m[12],*p1=&m[6],*p2=&m[8],*p3;
p1-=3; //指针变量p1指向数组元素m[3]
p3=p2+2;//指针变量p3指向数组元素m[10]。
(二) 一维数组元素的指针访问方式
一维数组的数组名实际上就是指向该数组的第一个单元的指针。
int a[10]; 因此*a和a[0]访问的是同一个元素
*(a+1)等价于a[1];
*(a+2)等价于a[2];
……
*(a+i)等价于a[i];
因此访问数组元素的操作可以采用两种方法,一种叫下标法;一种叫指针法。采用指针法比采用下标法更为简洁,执行效率也更高。
int a[10],*pa=a;
*(pa+1)等价于a[1];
*(pa+2)等价于a[2];
……
*(pa+i)等价于a[i];
【例6-6】数组元素的访问
#include <stdio.h>
void main()
{int a[5]={7,9,4,3,8};
int *pa=a;
/*用下标法访问各数组元素*/
printf("%d ",a[0]);
printf("%d
",a[2]);
/*用数组名访问数组元素的地址*/
printf("%d ",*a);
printf("%d
",*(a+2));
/*用指针变量访问各数组元素*/
printf("%d ",*pa);
printf("%d
",*(pa+2));
}
执行结果: 7 4
7 4
7 4
【例6-7】下面的程序在输入1 2 3 4 5 6 7 8 9 0后的输出结果还是1 2 3 4 5 6 7 8 9 0吗?
#include <stdio.h>
void main()
{
int a[10],*p,i;
p=a;
for(i=0;i<10;i++)
scanf("%d",p++);
/*特别要注意输入时指针的变化*/
printf("
");
for(i=0;i<10;i++,p++) /*指针p的值已经变化*/
printf("%d ",*p);
}
输入:1 2 3 4 5 6 7 8 9 0
怎样解决?
输出:
#include <stdio.h>
void main()
{ int a[10],*p,i;
p=a;
for(i=0;i<10;i++)
scanf("%d",p++);
/*特别要注意输入时指针的变化*/
printf("
");
p=a;
/*使p指针重新指向了数组的首地址*/
for(i=0;i<10;i++,p++)
printf("%d ",*p);
}
小结:
(1) 指针变量可以实现自身值的改变。如:pa++;而数组名所代表的地址则不能改变,a++是错误的用法。
(2)应注意指针变量的当前值。如上例。
(3)指针变量可以指向数组中各个内存单元。
举一反三
【例6-8】写出程序运行的结果。
#include <stdio.h>
main()
{
int a[10]={1,2,3,4,5,6,7,8,9,10},*p=&a[3],b;
b=p[5];
printf("%d
",b);
}
A.5 B.6 C.8 D.9
分析:因为*p=&a[3],所以p[5]是往下移动5,即a[8],所以b的值为9。
答案:D
【例6-9】写出程序运行的结果。
#include <stdio.h>
main()
{int arr[]={6,7,8,9,10};
int *ptr;
ptr=arr;
*(ptr+2)+=2;
printf ("%d,%d
",*ptr,*(ptr+2));
}
A.8,10 B.6,8 C.7,9 D.6,10
分析:ptr=arr,表示ptr是指向arr数组的首地址,所以*ptr即为arr[0],而*(ptr+2)+=2表示*(ptr+2)=*(ptr+2)+2,其中*(ptr+2)即为arr[2],所以新的r[2]的值为10
答案为:D
【例6-10】写出程序运行的结果。
#include <stdio.h>
main()
{ int a[]={2,4,6,8,10,12},*p=a;
printf ("%d,%d
",*(p+1),*(a+5));
}
分析:因为*p=a,说明p为数组a的首地址,即p=&a[0],所以p+1是a[1]的首地址,所以程序输出的值为a[1]和a]5],即输出结果为:4,12。
任务3 用指针优化一个班同学三门课成绩的输入输出
一、问题情景
一个班有40个同学进行了三门课的考试,现要用指针实现学生三门课成绩的输入输出。
二、具体实现
解法一:
#include <stdio.h>
void main()
{int s[4][3];
int i,j,(*p)[3];
p=s;
for(i=0;i<4;i++)
{ for(j=0;j<3;j++)
scanf("%8d",(*(p+i)+j)); }
printf("******************
"); for(i=0;i<4;i++)
{ for(j=0;j<3;j++)
printf("%8d",*(*(p+i)+j)); printf("
");
} }
解法二:
#include <stdio.h>
void main()
{ int s[4][3];
int i,j;
for(i=0;i<4;i++)
{ for(j=0;j<3;j++)
scanf("%8d",(*(s+i)+j)); }
printf("******************
");
for(i=0;i<4;i++)
{ for(j=0;j<3;j++)
printf("%8d",*(*(s+i)+j));
printf("
");
} }
解法三:
#include <stdio.h>
void main()
{ int s[4][3];
int i,j,row,col;
row=4;col=3;
for(i=0;i<row;i++)
{ for(j=0;j<col;j++)
scanf("%8d", (&s[0][0]+i*col+j));}
printf("*****************
");
for(i=0;i<row;i++)
{ for(j=0;j<col;j++)
printf("%8d",*(&s[0][0]+i*col+j));
printf("
");
} }
这三种方法,其输出结果均是:(假如数据是如下的话)
1、指向二维数组元素的指针;
2、二维数组元素的指针访问方式;
三、相关知识
(一) 多维数组元素的指针访问方式(以二维数组为例介绍多维数组的指针访问方式。 )
二维数组可以看成是一种特殊的一维数组,每一个一维数组元素本身又是一个有若干个数组元素的一维数组。
例如:int b[3][4]; 理解为:有3个元素b[0]、b[1]、b[2],每一个元素代表一行,每一个元素是一个包含4个元素的数组。
设p为指向二维数组的指针变量,若p=b[0],可定义为int(*p)[4],p=b,则p+i指向一维数组b[i],而*(*(p+i)+j)则是i行j列元素的值。
*(*(b+i)+j)式子是根据二维数组名计算i行j列元素的值;
还有一种直接采用首元素地址计算i行j列元素的方法。其格式如下:
*(首元素地址+行号*列数+列号)
【例6-11】 用几种方法输出二维数组各元素的值。
#include <stdio.h>
void main()
{ int s[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
int i,j,(*p)[4];
int row,col;
p=s;
printf("用二维数组的指针变量计算i行j列元素的方法
");
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
printf("%8d",*(*(p+i)+j));
printf("
");
}
printf("用二维数组的数组名计算i行j列元素的方法
");
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
printf("%8d",*(*(s+i)+j));
printf("
");
}
printf("用直接采用首元素地址计算i行j列元素的方法
");
row=3;col=4;
for(i=0;i<row;i++)
{ for(j=0;j<col;j++)
printf("%8d",*(&s[0][0]+i*col+j)); printf("
");
}}
举一反三
#include <stdio.h>
main()
{
int a[2][3]={2,4,6,8,10,12};
printf("a[1][0]=%d
",a[1][0]);
printf("*(*(a+1)+0=%d
",*(*(a+1)+0));
}
分析:int a[2][3]表示定义一个二行,三列的二维数组,
a[0][0] a[0][1] a[0][2] 2 4 6
a[1][0] a[1][1] a[1][2] 8 10 12
所以,a[1][0]的值为8,*(*(a+1)+0)也是表示a[1][0],所以也是8。
【例6-12】写出程序运行结果。
【例6-13】写出程序运行结果。
#include <stdio.h>
main()
{
int a[3][3]={1,2,3,4,5,6,7,8,9};
int m,*p;
p=&a[0][0];
printf("%d
",*p);
printf("%d
",*p+5);
printf("%d
",*p+7);
m=(*p)*(*p+2)*(*p+4);
printf("m=%d
",m);
}
分析:int a[3][3]表示定义为一个三行三列的二维数组
a[0][0] a[0][1] a[0][2] 1 2 3
a[1][0] a[1][1] a[1][2] 4 5 6
a[2][0] a[2][1] a[2][2] 7 8 9
p=&a[0][0]表示p指向二维数组的首地址,*p=a[0][0],*p+5表示第2行的第3列,即a[1][2],所以值为6,*p+7表示第3行的第2列,即a[2][1],即8,m=(*p)*(*p+2)*(*p+4)表示m=a[0][0]*a[0][3]*a[1][1]=1*3*5=15。
任务4 用指针实现输出最高分的记录
一、问题情景
一个班有40位学生参加了期终考试(考了三门课),请用指针优化学生成绩单。即用指针实现全班同学成绩的输入输出以及输出最高分的同学(在函数中进行)。
二、具体实现
方法一
#include <stdio.h>
/*输出数组元素的函数*/
void pp(int score[][5],int n)
{int i,j;
for(i=0;i<n;i++)
{for(j=0;j<5;j++)
printf("%5d",*(*(score+i)+j));
printf("
");}}
/*求每个同学三门课的总分*/
void sum(int score[][5],int n)
{int i,j;
for(i=0;i<n;i++)
for(j=0;j<4;j++)
*(*(score+i)+4)+=*(*(score+i)+j);}
/*求最高分的是第几位同学*/
int max(int score[][5],int n)
{int i,max,k;
max=score[0][4];k=0;
for(i=1;i<3;i++)
if(score[i][4]>max)
{k=i;}
return k;
}
/*主函数*/
void main()
{ int s[3][5]={1,2,3,4,0,5,6,7,8,0,9,10,11,12,0}; /*0的位置放总分*/
int i,kk;
sum(s,3); /*调用求每个同学的三门课总分的函数 */
pp(s,3); //调用输出函数
printf("最高分为:
");
kk=max(s,3); /*调用求最高分同学的序号*/
for(i=0;i<5;i++)
printf("%5d",s[kk][i]);
printf("
"); }
方法二
#include <stdio.h>
/*输出数组元素的函数*/
void pp(int (*p)[5],int n)
{int i,j;
for(i=0;i<n;i++)
{for(j=0;j<5;j++)
printf("%5d",*(*(p+i)+j));
printf("
");}
}
/*求每个同学三门课的总分*/
void sum(int (*p)[5],int n)
{int i,j;
for(i=0;i<n;i++)
for(j=0;j<4;j++)
*(*(p+i)+4)+=*(*(p+i)+j);
}
/*求最高分的是第几位同学*/
int max(int (*p)[5],int n)
{int i,*max,k;
max=p[0];k=0;
for(i=1;i<3;i++)
if(*(*(p+i)+4)>*max)
{k=i;}
return k;}
void main()
{ int s[3][5]={1,2,3,4,0,5,6,7,8,0,9,10,11,12,0};
int i,kk;
sum(s,3);
pp(s,3);
printf("最高分为:
");
kk=max(s,3);
for(i=0;i<5;i++)
printf("%5d",s[kk][i]);
printf("
"); }
三、相关知识
在C语言中,不可能将一维实参数组的所有元素整体赋给形参数组变量,而只能将实参数组的指针或数组元素赋值给对应的形参变量。
数组名就是数组的首地址,实参在函数调用时,是把数组首地址传送给形参,所以实参向形参传送数组名实际上就是传送数组的首地址。形参得到该地址后指向同一个数组,从而在函数调用后,实参数组的元素值可能会发生变化。这就好象同一件物品有两个不同的名称一样。同样,数组指针变量的值即为数组的首地址,当然也可以作为函数的参数使用。
【例6-14】 将数组a中的n个整数按相反的顺序存放。
#include <stdio.h>
void inv(int x[],int n)
{ int m,temp,i,j;
m=(n-1)/2;
for(i=0;i<=m;i++)
{ j=n-1-i;
temp=x[i];x[i]=x[j];x[j]=temp;
} }
void main()
{ int i,*p,a[10]={3,7,9,11,0,6,7,5,4,2};
p=a;
inv(p,10);
for(i=0;i<10;i++)
printf("%d,",a[i]);
printf("
"); }
/*将形参修改为指针变量*/
#include <stdio.h>
void inv(int *x,int n)
{ int *p,m,t,*i,*j;
m=(n-1)/2;
i=x;
j=x+n-1;
p=x+m;
for(;i<=p;i++,j--)
{ t=*i; *i=*j; *j=t; }
}
void main()
{ int a[10]={3,7,9,11,0,6,7,5,4,2};
int *p;
p=a;
inv(p,10);
for(p=a;p<a+10;p++)
printf("%d,",*p);
printf("
");
}
输出结果:2 4 5 7 6 0 11 9 7 3
【例6-15】 将数组a中的n个整数按从高到低的顺序存放。
#include <stdio.h>
void sort(int *x,int n)
{ int i,j,t;
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)
if(*(x+i)<*(x+j))
{t=*(x+i);*(x+i)=*(x+j);*(x+j)=t;}
}
void main()
{ int a[10]={3,7,9,11,0,6,7,5,4,2};
int *p;
p=a;
sort(p,10);
for(p=a;p<a+10;p++)
printf("%d,",*p);
printf("
"); }
【例6-16】输出二维数组中各元素的值,要求用函数输出。
方法一:函数参数用指向二维数组的指针
#include <stdio.h>
void pp(int (*p)[4])
{int i,j;
for(i=0;i<3;i++)
{for(j=0;j<4;j++)
printf("%5d",*(*(p+i)+j));
printf("
");}
}
void main()
{ int s[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
int i,j;
pp(s);}
方法二:函数参数用数组
#include <stdio.h>
void pp(int aa[][4])
{int i,j;
for(i=0;i<3;i++)
{for(j=0;j<4;j++)
printf("%5d",*(*(aa+i)+j));
printf("
");}
}
void main()
{ int s[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
int i,j;
pp(s);
}
注意:参数(int (*p)[4],不能写成(int (*p)[ ],参数int aa[][4],必须要注明列的下标,可以省略行的下标。
知识扩展
一个班里有40个学生,在选举班干部时有3个候选人,现要求对候选人以姓氏的英文顺序排序,请用C中的字符指针解决此问题。
分析:要将3个候选人以姓氏的英文顺序排队,要求用C中的字符指针解决此问题,所以,在本任务中将要解决什么是字符指针,字符指针如何引用。
#include <stdio.h>
#include "string.h" /*因为用到strcmp()*/
main()
{char *name1="张小明",*name2="李大刚",*name3="周建华",*tt;
if( strcmp(name1,name2)<0)
{tt=name1;name1=name2;name2=tt;}
if( strcmp(name1,name3)<0)
{tt=name1;name1=name3;name3=tt;}
if( strcmp(name2,name3)<0)
{tt=name2;name2=name3;name3=tt;}
printf("输出的姓名为:
");
printf("%s
",name1);
printf("%s
",name2);
printf("%s
",name3);
}
程序如下
1. 用字符数组实现
#include <stdio.h>
main()
{ char string[ ]="I love China! ";
printf("%s
",string);
}
说明:string是数组名,代表数组的首地址;
string[i]代表数组的第i个元素;
string[i]等价于*(string+i)。其相应的处理方法同一般数组相似。
2. 用字符指针实现
#include <stdio.h>
main()
{ char *string="I love China! ";
printf("%s
",string);
}
说明:
(1)字符串指针:是指向字符变量的指针变量。可以用来描述和处理一个字符串。
如 char *str="I love China!";
(2)含义理解:
不是将字符串的内容赋值给指针变量,而是将其起始地址赋给它。
char *str;
str="I am a student.";
可以将字符数组表示为
char s1[]=“I am a student.”;
或
char s1[]={'I',' ','a','m',' ','a',' ','s','t','u','d','e','n','t'};
不能表示为:
char *str={'I',' ','a','m',' ','a',' ','s','t','u','d','e','n','t'};
(3) 字符指针变量在使用之前必须初始化,使其指向一个具体的存储单元。
如:char str[];
scanf("%s",str);是正确的
而 char *str;
scanf("%s",str); 是错误的。
(一)字符串的表示形式
【例6-17】将字符串a复制到字符串b。
方法一
#include <stdio.h>
void main()
{ char a[]="I am a boy.",b[20],*p1,*p2;
int i;
p1=a;
p2=b;
for(;*p1!='\0';p1++,p2++)
*p2=*p1; /*当*p1=='\0'时结束循环,因此'\0'并没有复制到*p2上*/
*p2='\0';
printf("string a is:%s
",a);
printf("string b is:%s
",b);
printf("
");
}
方法二
#include <stdio.h>
void main()
{ char *a="I am a boy.",*b;
b=a;
printf("string a is:%s
",a);
printf("string b is:%s
",b);
printf("
");
}
方法一和方法二输出结果都是:
string a is:I am a boy.
String a is:I am a boy.
注意:若a,b都是字符指针,则可以用b=a,即将a的地址赋给b,但是若a,b是字符数组,则不能用b=a,应用strcpy(b,a),即
举一反三
#include "stdio.h"
void f(int *x,int *y)
{
int t;
t=*x;*x=*y;*y=t;
}
main()
{
int a[9]={1,2,3,4,5,6,7,8,9},i,*p,*q;
p=a;q=&a[8];
while(*p!=*q){f(p,q);p++;q--;}
for(i=0;i<9;i++) printf("%d,",a[i]);
}
分析:函数f的功能是交换二个数,主函数是当指针p和q不指向同一个变量时,调用f函数,当第一次循环时,a[0]和a[8]交换,第二次循环时,a[1]和a[7]交换,…直到a[3]和a[5]交换,所以程序的运行结果逆序输出数组a。
【例6-18】写出程序运行结果
#include "stdio.h"
int f(int b[][4])
{ int i,j,s=0;
for(j=0;j<4;j++)
{ i=j;
s+=b[i][j];
}
return s;
}
main( )
{ int a[4][4]={{1,2,3,4},{0,2,4,5},{3,6,9,12},{3,2,1,0}};
printf("%d
",f(a) );
}
分析:函数f的功能是计算二维数组b的主对角线元素的和,主函数是调用f函数,将实参二维数组a传递给形参二维数组b,所以程序的运行结果是a[0][0]+a[1][1]+a[2][2]+a[3][3]=1+6+9+0=16。
【例6-19】写出程序运行结果
#include <stdio.h>
main()
{
char a[]="programming",b[]="language";
char *p1,*p2;
int i;
p1=a;p2=b;
for(i=0;i<8;i++)
if(*(p1+i)!=*(p2+i))
printf("%c",*(p1+i));
printf("
");
}
分析:p1指向字符数组a,p2指向字符数组b,当i=0时,*p1=’p’,*p2=’l’,二者不相同,输出*p1;当i=1时,*(p1+1)=’r’, *(p2+1)=’a’,二者不同,输出*(p1+1);…一共循环8次,所以程序的运行结果是:prorm。
【例6-20】写出程序运行结果
#include <stdio.h>
#include <string.h>
main()
{ char *s1="AbDeG";
char *s2="AbdEg";
s1+=2;s2+=2;
printf("%d
",strcmp(s1,s2));
}
分析:因为*s1<*s2,所以strcmp(s1,s2)的结果为-1。
【例6-21】写出程序运行结果
$$