谭浩强c语言程序设计教程学习笔记第8章.docx
《谭浩强c语言程序设计教程学习笔记第8章.docx》由会员分享,可在线阅读,更多相关《谭浩强c语言程序设计教程学习笔记第8章.docx(38页珍藏版)》请在冰豆网上搜索。
谭浩强c语言程序设计教程学习笔记第8章
第8章指针
8.1地址和指针的概念
按变量地址存取变量值的方式,成为“直接访问”方式。
“间接访问”将变量的地址存放在另一个变量中。
一个变量的地址称为该变量的“指针”。
如果有一个变量专门用来存放另一个变量的地址(即指针),则它称为“指针变量”,指针变量就是地址变量(存放地址的变量)。
指针变量的值(即指针变量中存放的值)是地址(指针)。
8.2变量的地址和指向变量的指针地址
变量的指针就是变量的地址。
存放地址的变量是指针变量,它用来指向另一个变量。
用“*”表示“指向的对象”。
8.2.1怎样定义指针变量?
指针变量的基类型用来指定此指针变量可以指向的变量类型。
定义指针变量一般形式为:
基类型*指针变量名;
说明:
(1)指针变量前的“*”表示该变量的类型为指针类型。
(2)定义指针类型时必须指定基类型。
对指针变量赋值时需要注意:
(1)指针变量中只能存放地址。
(2)赋给指针变量的变量地址不能是任意类型,而只能是与指针变量的基类型具有相同类型的变量的地址。
8.2.2怎样引用指针变量
(1)给指针变量赋值。
p=&a;
(2)引用指针变量的值。
如:
printf(“%o”,p);作用是以八进制输出指针变量p的值,如果p指向了a,就是输出a的地址,即&a。
(3)引用指针变量指向的变量。
(1)“&”算去地址运算符。
(2)“*”指针运算符。
例8.1通过指针变量访问整型变量
#include
intmain()
{
inta,b;
int*pointer_1,*pointer_2;
a=100;
b=200;
pointer_1=&a;
pointer_2=&b;
printf("a=%d,b=%d\n",a,b);
printf("*pointer_1=%d,*pointer_2=%d",*pointer_1,*pointer_2);
return0;
}
例8.2输入a,b连个整数,按先大后小的顺序输出a,b。
int*p,*p1,*p2;
printf("pleaseentera,b:
\n");
scanf("%d,%d",&a,&b);
p1=&a;
p2=&b;
if(a
p=p1;
p1=p2;
p2=p;
printf("max=%d,min=%d\n",*p1,*p2);
8.2.3指针变量作为函数参数
指针变量作函数参数的作用是将一个变量的地址传到另一个函数中。
例8.3输入a,b连个整数,按先大后小的顺序输出a,b。
用指针变量作函数参数。
voidswap(int*,int*);
int*p1,*p2;
swap(p1,p2);
voidswap(int*p1,int*p2)
inttemp;
temp=*p1;
*p1=*p2;
*p2=temp;
不可能通过执行调用函数来改变实参指针变量的值,但是却可以改变实参指针变量所指变量的值。
例8.4输入3个整数a,b,c,要求按大小顺序将它们输出。
用函数实现改变这3个变量的值。
voidexchange(int*,int*,int*);
int*p3,*p1,*p2;
inta,b,c;
printf("pleaseentera,b,c:
scanf("%d,%d,%d",&a,&b,&c);
p3=&c;
exchange(p1,p2,p3);
printf("%d,%d,%d\n",a,b,c);
voidexchange(int*q1,int*q2,int*q3)
if(*q1<*q2)
swap(q1,q2);
if(*q1<*q3)
swap(q1,q3);
if(*q2,*q3)
swap(q2,q3);
8.3通过指针引用数组
8.3.1数组元素的指针
所谓数组元素的指针就是数组元素的地址。
8.3.2指针的运算
(1)P+1指向同一数组中的下一个元素,p-1指向同一数组中的上一个元素。
(2)如果p原来指向a[0],执行++p后p的值改变了,在p的原值基础上加d,这样p就指向数组的下一个元素a[1].
(3)如果p的初值是&a[0],则p+i和a+i就是数组元素a[i]的地址。
(4)*(p+i)或*(a+i)是p+i或a+i所指向的数组元素,即a[i].
(5)如果指针变量p1和p2都指向同一数组,如执行p2-p1,结果是两个数组之差,除以数组元素长度。
8.3.3通过指针引用数组元素
(1)下标法,a[i]。
(2)指针法,*(a+i)。
例8.5有一个整型数组a,有10个元素,输出数组中的全部元素。
(1)下标法
inta[10];
inti;
for(i=0;i<10;i++)
scanf("%d",&a[i]);
printf("%d\t",a[i]);
printf("\n");
(2)通过数组名计算数组元素地址,找出元素的值。
printf("%d\t",*(a+i));
(3)用指针变量指向数组元素
inti,*p;
for(p=a;p<(a+10);p++)
printf("%d\t",*p);
例8.6通过指针变量输出a数组的10个元素。
int*p,i,a[10];
p=a;
scanf("%d",p++);
for(i=0;i<10;i++,p++)
8.3.4用数组名作函数参数
表以变量名和数组名作为函数参数的比较
实参类型
变量名
数组名
要求形参的类型
数组名或指针变量
传递的信息
变量的值
实参数组首元素的地址
通过函数调用能否改变实参的值
不能
能改变是参数组元素的值
用变量名作为函数参数传递的是变量的值,当用数组名作为函数参数时,由于数组名代表的是数组首元素地址,因此传递的值是地址,所以要求形参是指针变量。
例8.7将数组a中n个整数按相反顺序存放。
voidinv(intx[],intn);
inta[10]={23,445,6,67,7,67,576,4,3,324},i;
printf("Theoriginalarray:
inv(a,10);
printf("Thearrayhasbeenreversed:
voidinv(intx[],intn)
inttemp,i,j,m=(n-1)/2;
for(i=0;i{j=n-1-i;temp=x[i];x[i]=x[j];x[j]=temp;}}归纳起来,如果有一个实参数组要想在函数中改变此数组种元素的值,实参与形参的对应关系有以下4种情况:(1)形参和实参都有用数组名;(2)实参用数组名,形参用指针变量;(3)实参形参都引用指针变量;(4)实参为指针变量,形参为数组名;例8.8用实参指针变量改写例8.7.#includeintmain(){voidinv(int*x,intn);int*p,a[10]={23,445,6,67,7,67,576,4,3,324},i;printf("Theoriginalarray:\n");for(i=0;i<10;i++)printf("%d\t",a[i]);printf("\n");p=a;inv(p,10);printf("Thearrayhasbeenreversed:\n");for(p=a;pprintf("%d\t",*p);return0;}voidinv(int*x,intn){inttemp,*i,*j,*p,m;m=(n-1)/2;i=x;j=x+n-1;p=x+m;for(;i<=p;i++,j--){temp=*i;*i=*j;*j=temp;}}例8.9用选择法对十个整数按由大到小排序。#includeintmain(){voidsort(intx[],intn);inta[10],i,*p;printf("pleaseenter10numbers:\n");p=a;for(i=0;i<10;i++)scanf("%d",p++);p=a;sort(p,10);for(p=a,i=0;i<10;i++){printf("%d\t",*p);p++;}printf("\n");}voidsort(intx[],intn){inti,j,k,t;for(i=0;i{k=i;for(j=i+1;jif(x[k]k=j;if(k!=i){t=x[i];x[i]=x[k];x[k]=t;}}}用指针变量作函数形参:#includeintmain(){voidsort(int*x,intn);inta[10],i,*p;printf("pleaseenter10numbers:\n");p=a;for(i=0;i<10;i++)scanf("%d",p++);p=a;sort(p,10);for(p=a,i=0;i<10;i++){printf("%d\t",*p);p++;}printf("\n");}voidsort(int*x,intn){inti,j,k,t;for(i=0;i{k=i;for(j=i+1;jif(*(x+k)<*(x+j))k=j;if(k!=i){t=*(x+i);*(x+i)=*(x+k);*(x+k)=t;}}}8.3.5通过指针引用多维数组1多维数组元素的地址多维数组中*(a+i)只是a[i]的另一种表示形式。二维数组中,a+i指的不是一个数组元素的存储单元。在二维数组中,a+i,a[i],*(a+i),&a[i],&a[i][0]的值相等,即它们代表同一地址。2.指向多维数组元素的指针变量例8.10用指向元素的指针变量输出二维数组各元素的值。#includeintmain(){int*p,a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};for(p=a[0];p{if((p-a[0])%4==0)printf("\n");printf("%d\t",*p);}return0;}例8.11输出二维数组任一行任一列元素的值。#includeintmain(){inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12},i,j;int(*p)[4];p=a;scanf("%d,%d",&i,&j);printf("a[%d][%d]=%d",i,j,*(*(p+i)+j));return0;}int(*p)[4]表示p是一个指针变量,它指向包含4个整型元素的一维数组。p是指向一维数组的指针。p不能指向一位数组中的某一元素。3.用指向数组的指针作函数参数例8.12有一个班,3个学生,各学4门课。计算总平均分数以及第n个学生的成绩。#includeintmain(){voidaverage(float*p,intn);voidsearch(float(*p)[4],intn);floatscore[3][4]={{65,67,70,60},{80,87,90,81},{90,99,100,98}};average(score,12);search(score,2);}voidaverage(float*p,intn){float*p_end;floatsum=0,aver;p_end=p+n-1;for(;p<=p_end;p++)sum=sum+(*p);aver=sum/n;printf("average=%5.2f\n",aver);}voidsearch(float(*p)[4],intn){inti;printf("ThescoreofNO.%dare:\n",n);for(i=0;i<4;i++)printf("%5.2f\t",*(*(p+n)+i));printf("\n");}例8.13在例8.12的基础上,查找有一门以上课程不及格的学生,输出他们的全部课程的成绩。#includeintmain(){voidsearch(float(*p)[4],intn);floatscore[3][4]={{65,57,70,60},{80,7,90,81},{90,99,100,98}};search(score,3);return0;}voidsearch(float(*p)[4],intn){inti,j,flag;for(j=0;j{flag=0;for(i=0;i<4;i++)if(*(*(p+j)+i)<60)flag=1;if(flag==1){printf("NO.%dfails,hisscoreare:\n",j+1);for(i=0;i<4;i++)printf("%5.1f\t",*(*(p+j)+i));printf("\n");}}}8.4通过指针引用字符串8.4.1字符串的表示形式(1)用字符数组存放一个字符串。例8.14定义一个字符数组,对它初始化,然后输出该字符串。#includeintmain(){charstring[]="Ilovexiaolei!";printf("%s\n",string);return0;}(2)用字符指针指向一个字符串#includeintmain(){charstring[]="Ilovexiaolei!";printf("%s\n",string);return0;}例8.16将字符串a复制为字符串b。#includeintmain(){chara[]="Ilovemiao!",b[20];inti;for(i=0;a[i]!='\0';i++)*(b+i)=*(a+i);*(b+i)='\0';printf("stringais:%s\n",a);printf("stringbis:");for(i=0;b[i]!='\0';i++)printf("%c",b[i]);printf("\n");}例8.17用指针变量来处理例8.16问题。#includeintmain(){chara[]="Ilovemiao!",b[20];inti;char*p1,*p2;p1=a;p2=b;for(;*p1!='\0';p1++,p2++)*p2=*p1;*p2='\0';printf("stringais:%s\n",a);printf("stringbis:");for(i=0;b[i]!='\0';i++)printf("%c",b[i]);printf("\n");}8.4.2字符指针作函数参数例8.18用函数调用实现字符串的复制。#includeintmain(){voidcopy_string(char*from,char*to);char*a="Iamateacher.";charb[]="Youareastudent!";char*p=b;printf("stringa=%s\nstringb=%s\n",a,p);printf("copystringatostringb:\n");copy_string(a,p);printf("stringa=%s\nstringb=%s\n",a,b);}voidcopy_string(char*from,char*to){for(;*from!='\0';from++,to++)*to=*from;*to='\0';}调用函数时实参与形参对应关系实参行参实参形参字符数组名字符数组名字符数组名字符指针变量字符指针变量字符指针变量字符指针变量字符数组名8.4.3对使用字符指针变量和字符数组的讨论(1)字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址,绝不是将字符串存放在字符指针变量中。(2)赋值方式。对字符数组只能对各个元素赋值。(3)数组可以再定义时整体赋初值,但不能再赋值语句中整体赋值。(4)如果定义一个字符数组,在编译时为它分配内存单元,它有确定的地址。(5)指针变量的值是可以改变的。例8.19改变指针变量的值。#includeintmain(){char*a="Ilovexiaolei!";a=a+7;printf("%s\n",a);return0;}8.5指向函数的指针8.5.1什么是函数指针?如果在程序中定义了一个函数,在编译时,编译系统为函数代码分配一段存储空间,这段代码的存储空间的起始地址(又称入口地址)称为这个函数的指针。8.5.2用函数指针变量调用函数例8.20用函数求a和b中的大者。(通过指针变量来访问它指向的函数)。#includeintmain(){intmax(int,int);int(*p)(int,int);inta,b,c;p=max;printf("pleaseentera,b\n:");scanf("%d,%d",&a,&b);c=(*p)(a,b);printf("a=%d,b=%d,max=%d\n",a,b,c);return0;}intmax(intx,inty){intz;if(x>y)z=x;elsez=y;returnz;}int(*p)(int,int);用来定义p是一个指向函数的指针变量,该函数有两个整型参数,函数值是整型。(1)指向函数的指针变量一般的定义形式是:数据类型(*指针变量名)(函数参数列表);(2)“int(*p)(int,int);”表示定义一个指向函数的指针变量p,它不是固定只指向某一个函数,而只是表示定义了这样一个类型的变量,它是专门用来存放函数的入口地址。(3)如果要用指针调用函数,必须先使指针变量指向该函数。(4)在给函数指针变量赋值时,只须给出函数名而不必给出参数。(5)用函数指针变量调用函数时,只须将(*p)代替函数名即可,在(*p)之后的括号内根据需要写上实参。(6)指向函数的指针变量,p+n,p++,p--等运算是无意义的。例8.21输入两个整数,然后让用户选择1或者2,选1时调用max函数,输出两者中的大数,选2时调用min函数,输出两者的小数。#include
j=n-1-i;
temp=x[i];
x[i]=x[j];
x[j]=temp;
归纳起来,如果有一个实参数组要想在函数中改变此数组种元素的值,实参与形参的对应关系有以下4种情况:
(1)形参和实参都有用数组名;
(2)实参用数组名,形参用指针变量;
(3)实参形参都引用指针变量;
(4)实参为指针变量,形参为数组名;
例8.8用实参指针变量改写例8.7.
voidinv(int*x,intn);
int*p,a[10]={23,445,6,67,7,67,576,4,3,324},i;
inv(p,10);
for(p=a;pprintf("%d\t",*p);return0;}voidinv(int*x,intn){inttemp,*i,*j,*p,m;m=(n-1)/2;i=x;j=x+n-1;p=x+m;for(;i<=p;i++,j--){temp=*i;*i=*j;*j=temp;}}例8.9用选择法对十个整数按由大到小排序。#includeintmain(){voidsort(intx[],intn);inta[10],i,*p;printf("pleaseenter10numbers:\n");p=a;for(i=0;i<10;i++)scanf("%d",p++);p=a;sort(p,10);for(p=a,i=0;i<10;i++){printf("%d\t",*p);p++;}printf("\n");}voidsort(intx[],intn){inti,j,k,t;for(i=0;i{k=i;for(j=i+1;jif(x[k]k=j;if(k!=i){t=x[i];x[i]=x[k];x[k]=t;}}}用指针变量作函数形参:#includeintmain(){voidsort(int*x,intn);inta[10],i,*p;printf("pleaseenter10numbers:\n");p=a;for(i=0;i<10;i++)scanf("%d",p++);p=a;sort(p,10);for(p=a,i=0;i<10;i++){printf("%d\t",*p);p++;}printf("\n");}voidsort(int*x,intn){inti,j,k,t;for(i=0;i{k=i;for(j=i+1;jif(*(x+k)<*(x+j))k=j;if(k!=i){t=*(x+i);*(x+i)=*(x+k);*(x+k)=t;}}}8.3.5通过指针引用多维数组1多维数组元素的地址多维数组中*(a+i)只是a[i]的另一种表示形式。二维数组中,a+i指的不是一个数组元素的存储单元。在二维数组中,a+i,a[i],*(a+i),&a[i],&a[i][0]的值相等,即它们代表同一地址。2.指向多维数组元素的指针变量例8.10用指向元素的指针变量输出二维数组各元素的值。#includeintmain(){int*p,a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};for(p=a[0];p{if((p-a[0])%4==0)printf("\n");printf("%d\t",*p);}return0;}例8.11输出二维数组任一行任一列元素的值。#includeintmain(){inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12},i,j;int(*p)[4];p=a;scanf("%d,%d",&i,&j);printf("a[%d][%d]=%d",i,j,*(*(p+i)+j));return0;}int(*p)[4]表示p是一个指针变量,它指向包含4个整型元素的一维数组。p是指向一维数组的指针。p不能指向一位数组中的某一元素。3.用指向数组的指针作函数参数例8.12有一个班,3个学生,各学4门课。计算总平均分数以及第n个学生的成绩。#includeintmain(){voidaverage(float*p,intn);voidsearch(float(*p)[4],intn);floatscore[3][4]={{65,67,70,60},{80,87,90,81},{90,99,100,98}};average(score,12);search(score,2);}voidaverage(float*p,intn){float*p_end;floatsum=0,aver;p_end=p+n-1;for(;p<=p_end;p++)sum=sum+(*p);aver=sum/n;printf("average=%5.2f\n",aver);}voidsearch(float(*p)[4],intn){inti;printf("ThescoreofNO.%dare:\n",n);for(i=0;i<4;i++)printf("%5.2f\t",*(*(p+n)+i));printf("\n");}例8.13在例8.12的基础上,查找有一门以上课程不及格的学生,输出他们的全部课程的成绩。#includeintmain(){voidsearch(float(*p)[4],intn);floatscore[3][4]={{65,57,70,60},{80,7,90,81},{90,99,100,98}};search(score,3);return0;}voidsearch(float(*p)[4],intn){inti,j,flag;for(j=0;j{flag=0;for(i=0;i<4;i++)if(*(*(p+j)+i)<60)flag=1;if(flag==1){printf("NO.%dfails,hisscoreare:\n",j+1);for(i=0;i<4;i++)printf("%5.1f\t",*(*(p+j)+i));printf("\n");}}}8.4通过指针引用字符串8.4.1字符串的表示形式(1)用字符数组存放一个字符串。例8.14定义一个字符数组,对它初始化,然后输出该字符串。#includeintmain(){charstring[]="Ilovexiaolei!";printf("%s\n",string);return0;}(2)用字符指针指向一个字符串#includeintmain(){charstring[]="Ilovexiaolei!";printf("%s\n",string);return0;}例8.16将字符串a复制为字符串b。#includeintmain(){chara[]="Ilovemiao!",b[20];inti;for(i=0;a[i]!='\0';i++)*(b+i)=*(a+i);*(b+i)='\0';printf("stringais:%s\n",a);printf("stringbis:");for(i=0;b[i]!='\0';i++)printf("%c",b[i]);printf("\n");}例8.17用指针变量来处理例8.16问题。#includeintmain(){chara[]="Ilovemiao!",b[20];inti;char*p1,*p2;p1=a;p2=b;for(;*p1!='\0';p1++,p2++)*p2=*p1;*p2='\0';printf("stringais:%s\n",a);printf("stringbis:");for(i=0;b[i]!='\0';i++)printf("%c",b[i]);printf("\n");}8.4.2字符指针作函数参数例8.18用函数调用实现字符串的复制。#includeintmain(){voidcopy_string(char*from,char*to);char*a="Iamateacher.";charb[]="Youareastudent!";char*p=b;printf("stringa=%s\nstringb=%s\n",a,p);printf("copystringatostringb:\n");copy_string(a,p);printf("stringa=%s\nstringb=%s\n",a,b);}voidcopy_string(char*from,char*to){for(;*from!='\0';from++,to++)*to=*from;*to='\0';}调用函数时实参与形参对应关系实参行参实参形参字符数组名字符数组名字符数组名字符指针变量字符指针变量字符指针变量字符指针变量字符数组名8.4.3对使用字符指针变量和字符数组的讨论(1)字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址,绝不是将字符串存放在字符指针变量中。(2)赋值方式。对字符数组只能对各个元素赋值。(3)数组可以再定义时整体赋初值,但不能再赋值语句中整体赋值。(4)如果定义一个字符数组,在编译时为它分配内存单元,它有确定的地址。(5)指针变量的值是可以改变的。例8.19改变指针变量的值。#includeintmain(){char*a="Ilovexiaolei!";a=a+7;printf("%s\n",a);return0;}8.5指向函数的指针8.5.1什么是函数指针?如果在程序中定义了一个函数,在编译时,编译系统为函数代码分配一段存储空间,这段代码的存储空间的起始地址(又称入口地址)称为这个函数的指针。8.5.2用函数指针变量调用函数例8.20用函数求a和b中的大者。(通过指针变量来访问它指向的函数)。#includeintmain(){intmax(int,int);int(*p)(int,int);inta,b,c;p=max;printf("pleaseentera,b\n:");scanf("%d,%d",&a,&b);c=(*p)(a,b);printf("a=%d,b=%d,max=%d\n",a,b,c);return0;}intmax(intx,inty){intz;if(x>y)z=x;elsez=y;returnz;}int(*p)(int,int);用来定义p是一个指向函数的指针变量,该函数有两个整型参数,函数值是整型。(1)指向函数的指针变量一般的定义形式是:数据类型(*指针变量名)(函数参数列表);(2)“int(*p)(int,int);”表示定义一个指向函数的指针变量p,它不是固定只指向某一个函数,而只是表示定义了这样一个类型的变量,它是专门用来存放函数的入口地址。(3)如果要用指针调用函数,必须先使指针变量指向该函数。(4)在给函数指针变量赋值时,只须给出函数名而不必给出参数。(5)用函数指针变量调用函数时,只须将(*p)代替函数名即可,在(*p)之后的括号内根据需要写上实参。(6)指向函数的指针变量,p+n,p++,p--等运算是无意义的。例8.21输入两个整数,然后让用户选择1或者2,选1时调用max函数,输出两者中的大数,选2时调用min函数,输出两者的小数。#include
voidinv(int*x,intn)
inttemp,*i,*j,*p,m;
m=(n-1)/2;
i=x;
j=x+n-1;
p=x+m;
for(;i<=p;i++,j--)
temp=*i;
*i=*j;
*j=temp;
例8.9用选择法对十个整数按由大到小排序。
voidsort(intx[],intn);
inta[10],i,*p;
printf("pleaseenter10numbers:
sort(p,10);
for(p=a,i=0;i<10;i++)
p++;
voidsort(intx[],intn)
inti,j,k,t;
for(i=0;i{k=i;for(j=i+1;jif(x[k]k=j;if(k!=i){t=x[i];x[i]=x[k];x[k]=t;}}}用指针变量作函数形参:#includeintmain(){voidsort(int*x,intn);inta[10],i,*p;printf("pleaseenter10numbers:\n");p=a;for(i=0;i<10;i++)scanf("%d",p++);p=a;sort(p,10);for(p=a,i=0;i<10;i++){printf("%d\t",*p);p++;}printf("\n");}voidsort(int*x,intn){inti,j,k,t;for(i=0;i{k=i;for(j=i+1;jif(*(x+k)<*(x+j))k=j;if(k!=i){t=*(x+i);*(x+i)=*(x+k);*(x+k)=t;}}}8.3.5通过指针引用多维数组1多维数组元素的地址多维数组中*(a+i)只是a[i]的另一种表示形式。二维数组中,a+i指的不是一个数组元素的存储单元。在二维数组中,a+i,a[i],*(a+i),&a[i],&a[i][0]的值相等,即它们代表同一地址。2.指向多维数组元素的指针变量例8.10用指向元素的指针变量输出二维数组各元素的值。#includeintmain(){int*p,a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};for(p=a[0];p{if((p-a[0])%4==0)printf("\n");printf("%d\t",*p);}return0;}例8.11输出二维数组任一行任一列元素的值。#includeintmain(){inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12},i,j;int(*p)[4];p=a;scanf("%d,%d",&i,&j);printf("a[%d][%d]=%d",i,j,*(*(p+i)+j));return0;}int(*p)[4]表示p是一个指针变量,它指向包含4个整型元素的一维数组。p是指向一维数组的指针。p不能指向一位数组中的某一元素。3.用指向数组的指针作函数参数例8.12有一个班,3个学生,各学4门课。计算总平均分数以及第n个学生的成绩。#includeintmain(){voidaverage(float*p,intn);voidsearch(float(*p)[4],intn);floatscore[3][4]={{65,67,70,60},{80,87,90,81},{90,99,100,98}};average(score,12);search(score,2);}voidaverage(float*p,intn){float*p_end;floatsum=0,aver;p_end=p+n-1;for(;p<=p_end;p++)sum=sum+(*p);aver=sum/n;printf("average=%5.2f\n",aver);}voidsearch(float(*p)[4],intn){inti;printf("ThescoreofNO.%dare:\n",n);for(i=0;i<4;i++)printf("%5.2f\t",*(*(p+n)+i));printf("\n");}例8.13在例8.12的基础上,查找有一门以上课程不及格的学生,输出他们的全部课程的成绩。#includeintmain(){voidsearch(float(*p)[4],intn);floatscore[3][4]={{65,57,70,60},{80,7,90,81},{90,99,100,98}};search(score,3);return0;}voidsearch(float(*p)[4],intn){inti,j,flag;for(j=0;j{flag=0;for(i=0;i<4;i++)if(*(*(p+j)+i)<60)flag=1;if(flag==1){printf("NO.%dfails,hisscoreare:\n",j+1);for(i=0;i<4;i++)printf("%5.1f\t",*(*(p+j)+i));printf("\n");}}}8.4通过指针引用字符串8.4.1字符串的表示形式(1)用字符数组存放一个字符串。例8.14定义一个字符数组,对它初始化,然后输出该字符串。#includeintmain(){charstring[]="Ilovexiaolei!";printf("%s\n",string);return0;}(2)用字符指针指向一个字符串#includeintmain(){charstring[]="Ilovexiaolei!";printf("%s\n",string);return0;}例8.16将字符串a复制为字符串b。#includeintmain(){chara[]="Ilovemiao!",b[20];inti;for(i=0;a[i]!='\0';i++)*(b+i)=*(a+i);*(b+i)='\0';printf("stringais:%s\n",a);printf("stringbis:");for(i=0;b[i]!='\0';i++)printf("%c",b[i]);printf("\n");}例8.17用指针变量来处理例8.16问题。#includeintmain(){chara[]="Ilovemiao!",b[20];inti;char*p1,*p2;p1=a;p2=b;for(;*p1!='\0';p1++,p2++)*p2=*p1;*p2='\0';printf("stringais:%s\n",a);printf("stringbis:");for(i=0;b[i]!='\0';i++)printf("%c",b[i]);printf("\n");}8.4.2字符指针作函数参数例8.18用函数调用实现字符串的复制。#includeintmain(){voidcopy_string(char*from,char*to);char*a="Iamateacher.";charb[]="Youareastudent!";char*p=b;printf("stringa=%s\nstringb=%s\n",a,p);printf("copystringatostringb:\n");copy_string(a,p);printf("stringa=%s\nstringb=%s\n",a,b);}voidcopy_string(char*from,char*to){for(;*from!='\0';from++,to++)*to=*from;*to='\0';}调用函数时实参与形参对应关系实参行参实参形参字符数组名字符数组名字符数组名字符指针变量字符指针变量字符指针变量字符指针变量字符数组名8.4.3对使用字符指针变量和字符数组的讨论(1)字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址,绝不是将字符串存放在字符指针变量中。(2)赋值方式。对字符数组只能对各个元素赋值。(3)数组可以再定义时整体赋初值,但不能再赋值语句中整体赋值。(4)如果定义一个字符数组,在编译时为它分配内存单元,它有确定的地址。(5)指针变量的值是可以改变的。例8.19改变指针变量的值。#includeintmain(){char*a="Ilovexiaolei!";a=a+7;printf("%s\n",a);return0;}8.5指向函数的指针8.5.1什么是函数指针?如果在程序中定义了一个函数,在编译时,编译系统为函数代码分配一段存储空间,这段代码的存储空间的起始地址(又称入口地址)称为这个函数的指针。8.5.2用函数指针变量调用函数例8.20用函数求a和b中的大者。(通过指针变量来访问它指向的函数)。#includeintmain(){intmax(int,int);int(*p)(int,int);inta,b,c;p=max;printf("pleaseentera,b\n:");scanf("%d,%d",&a,&b);c=(*p)(a,b);printf("a=%d,b=%d,max=%d\n",a,b,c);return0;}intmax(intx,inty){intz;if(x>y)z=x;elsez=y;returnz;}int(*p)(int,int);用来定义p是一个指向函数的指针变量,该函数有两个整型参数,函数值是整型。(1)指向函数的指针变量一般的定义形式是:数据类型(*指针变量名)(函数参数列表);(2)“int(*p)(int,int);”表示定义一个指向函数的指针变量p,它不是固定只指向某一个函数,而只是表示定义了这样一个类型的变量,它是专门用来存放函数的入口地址。(3)如果要用指针调用函数,必须先使指针变量指向该函数。(4)在给函数指针变量赋值时,只须给出函数名而不必给出参数。(5)用函数指针变量调用函数时,只须将(*p)代替函数名即可,在(*p)之后的括号内根据需要写上实参。(6)指向函数的指针变量,p+n,p++,p--等运算是无意义的。例8.21输入两个整数,然后让用户选择1或者2,选1时调用max函数,输出两者中的大数,选2时调用min函数,输出两者的小数。#include
k=i;
for(j=i+1;jif(x[k]k=j;if(k!=i){t=x[i];x[i]=x[k];x[k]=t;}}}用指针变量作函数形参:#includeintmain(){voidsort(int*x,intn);inta[10],i,*p;printf("pleaseenter10numbers:\n");p=a;for(i=0;i<10;i++)scanf("%d",p++);p=a;sort(p,10);for(p=a,i=0;i<10;i++){printf("%d\t",*p);p++;}printf("\n");}voidsort(int*x,intn){inti,j,k,t;for(i=0;i{k=i;for(j=i+1;jif(*(x+k)<*(x+j))k=j;if(k!=i){t=*(x+i);*(x+i)=*(x+k);*(x+k)=t;}}}8.3.5通过指针引用多维数组1多维数组元素的地址多维数组中*(a+i)只是a[i]的另一种表示形式。二维数组中,a+i指的不是一个数组元素的存储单元。在二维数组中,a+i,a[i],*(a+i),&a[i],&a[i][0]的值相等,即它们代表同一地址。2.指向多维数组元素的指针变量例8.10用指向元素的指针变量输出二维数组各元素的值。#includeintmain(){int*p,a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};for(p=a[0];p{if((p-a[0])%4==0)printf("\n");printf("%d\t",*p);}return0;}例8.11输出二维数组任一行任一列元素的值。#includeintmain(){inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12},i,j;int(*p)[4];p=a;scanf("%d,%d",&i,&j);printf("a[%d][%d]=%d",i,j,*(*(p+i)+j));return0;}int(*p)[4]表示p是一个指针变量,它指向包含4个整型元素的一维数组。p是指向一维数组的指针。p不能指向一位数组中的某一元素。3.用指向数组的指针作函数参数例8.12有一个班,3个学生,各学4门课。计算总平均分数以及第n个学生的成绩。#includeintmain(){voidaverage(float*p,intn);voidsearch(float(*p)[4],intn);floatscore[3][4]={{65,67,70,60},{80,87,90,81},{90,99,100,98}};average(score,12);search(score,2);}voidaverage(float*p,intn){float*p_end;floatsum=0,aver;p_end=p+n-1;for(;p<=p_end;p++)sum=sum+(*p);aver=sum/n;printf("average=%5.2f\n",aver);}voidsearch(float(*p)[4],intn){inti;printf("ThescoreofNO.%dare:\n",n);for(i=0;i<4;i++)printf("%5.2f\t",*(*(p+n)+i));printf("\n");}例8.13在例8.12的基础上,查找有一门以上课程不及格的学生,输出他们的全部课程的成绩。#includeintmain(){voidsearch(float(*p)[4],intn);floatscore[3][4]={{65,57,70,60},{80,7,90,81},{90,99,100,98}};search(score,3);return0;}voidsearch(float(*p)[4],intn){inti,j,flag;for(j=0;j{flag=0;for(i=0;i<4;i++)if(*(*(p+j)+i)<60)flag=1;if(flag==1){printf("NO.%dfails,hisscoreare:\n",j+1);for(i=0;i<4;i++)printf("%5.1f\t",*(*(p+j)+i));printf("\n");}}}8.4通过指针引用字符串8.4.1字符串的表示形式(1)用字符数组存放一个字符串。例8.14定义一个字符数组,对它初始化,然后输出该字符串。#includeintmain(){charstring[]="Ilovexiaolei!";printf("%s\n",string);return0;}(2)用字符指针指向一个字符串#includeintmain(){charstring[]="Ilovexiaolei!";printf("%s\n",string);return0;}例8.16将字符串a复制为字符串b。#includeintmain(){chara[]="Ilovemiao!",b[20];inti;for(i=0;a[i]!='\0';i++)*(b+i)=*(a+i);*(b+i)='\0';printf("stringais:%s\n",a);printf("stringbis:");for(i=0;b[i]!='\0';i++)printf("%c",b[i]);printf("\n");}例8.17用指针变量来处理例8.16问题。#includeintmain(){chara[]="Ilovemiao!",b[20];inti;char*p1,*p2;p1=a;p2=b;for(;*p1!='\0';p1++,p2++)*p2=*p1;*p2='\0';printf("stringais:%s\n",a);printf("stringbis:");for(i=0;b[i]!='\0';i++)printf("%c",b[i]);printf("\n");}8.4.2字符指针作函数参数例8.18用函数调用实现字符串的复制。#includeintmain(){voidcopy_string(char*from,char*to);char*a="Iamateacher.";charb[]="Youareastudent!";char*p=b;printf("stringa=%s\nstringb=%s\n",a,p);printf("copystringatostringb:\n");copy_string(a,p);printf("stringa=%s\nstringb=%s\n",a,b);}voidcopy_string(char*from,char*to){for(;*from!='\0';from++,to++)*to=*from;*to='\0';}调用函数时实参与形参对应关系实参行参实参形参字符数组名字符数组名字符数组名字符指针变量字符指针变量字符指针变量字符指针变量字符数组名8.4.3对使用字符指针变量和字符数组的讨论(1)字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址,绝不是将字符串存放在字符指针变量中。(2)赋值方式。对字符数组只能对各个元素赋值。(3)数组可以再定义时整体赋初值,但不能再赋值语句中整体赋值。(4)如果定义一个字符数组,在编译时为它分配内存单元,它有确定的地址。(5)指针变量的值是可以改变的。例8.19改变指针变量的值。#includeintmain(){char*a="Ilovexiaolei!";a=a+7;printf("%s\n",a);return0;}8.5指向函数的指针8.5.1什么是函数指针?如果在程序中定义了一个函数,在编译时,编译系统为函数代码分配一段存储空间,这段代码的存储空间的起始地址(又称入口地址)称为这个函数的指针。8.5.2用函数指针变量调用函数例8.20用函数求a和b中的大者。(通过指针变量来访问它指向的函数)。#includeintmain(){intmax(int,int);int(*p)(int,int);inta,b,c;p=max;printf("pleaseentera,b\n:");scanf("%d,%d",&a,&b);c=(*p)(a,b);printf("a=%d,b=%d,max=%d\n",a,b,c);return0;}intmax(intx,inty){intz;if(x>y)z=x;elsez=y;returnz;}int(*p)(int,int);用来定义p是一个指向函数的指针变量,该函数有两个整型参数,函数值是整型。(1)指向函数的指针变量一般的定义形式是:数据类型(*指针变量名)(函数参数列表);(2)“int(*p)(int,int);”表示定义一个指向函数的指针变量p,它不是固定只指向某一个函数,而只是表示定义了这样一个类型的变量,它是专门用来存放函数的入口地址。(3)如果要用指针调用函数,必须先使指针变量指向该函数。(4)在给函数指针变量赋值时,只须给出函数名而不必给出参数。(5)用函数指针变量调用函数时,只须将(*p)代替函数名即可,在(*p)之后的括号内根据需要写上实参。(6)指向函数的指针变量,p+n,p++,p--等运算是无意义的。例8.21输入两个整数,然后让用户选择1或者2,选1时调用max函数,输出两者中的大数,选2时调用min函数,输出两者的小数。#include
if(x[k]k=j;if(k!=i){t=x[i];x[i]=x[k];x[k]=t;}}}用指针变量作函数形参:#includeintmain(){voidsort(int*x,intn);inta[10],i,*p;printf("pleaseenter10numbers:\n");p=a;for(i=0;i<10;i++)scanf("%d",p++);p=a;sort(p,10);for(p=a,i=0;i<10;i++){printf("%d\t",*p);p++;}printf("\n");}voidsort(int*x,intn){inti,j,k,t;for(i=0;i{k=i;for(j=i+1;jif(*(x+k)<*(x+j))k=j;if(k!=i){t=*(x+i);*(x+i)=*(x+k);*(x+k)=t;}}}8.3.5通过指针引用多维数组1多维数组元素的地址多维数组中*(a+i)只是a[i]的另一种表示形式。二维数组中,a+i指的不是一个数组元素的存储单元。在二维数组中,a+i,a[i],*(a+i),&a[i],&a[i][0]的值相等,即它们代表同一地址。2.指向多维数组元素的指针变量例8.10用指向元素的指针变量输出二维数组各元素的值。#includeintmain(){int*p,a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};for(p=a[0];p{if((p-a[0])%4==0)printf("\n");printf("%d\t",*p);}return0;}例8.11输出二维数组任一行任一列元素的值。#includeintmain(){inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12},i,j;int(*p)[4];p=a;scanf("%d,%d",&i,&j);printf("a[%d][%d]=%d",i,j,*(*(p+i)+j));return0;}int(*p)[4]表示p是一个指针变量,它指向包含4个整型元素的一维数组。p是指向一维数组的指针。p不能指向一位数组中的某一元素。3.用指向数组的指针作函数参数例8.12有一个班,3个学生,各学4门课。计算总平均分数以及第n个学生的成绩。#includeintmain(){voidaverage(float*p,intn);voidsearch(float(*p)[4],intn);floatscore[3][4]={{65,67,70,60},{80,87,90,81},{90,99,100,98}};average(score,12);search(score,2);}voidaverage(float*p,intn){float*p_end;floatsum=0,aver;p_end=p+n-1;for(;p<=p_end;p++)sum=sum+(*p);aver=sum/n;printf("average=%5.2f\n",aver);}voidsearch(float(*p)[4],intn){inti;printf("ThescoreofNO.%dare:\n",n);for(i=0;i<4;i++)printf("%5.2f\t",*(*(p+n)+i));printf("\n");}例8.13在例8.12的基础上,查找有一门以上课程不及格的学生,输出他们的全部课程的成绩。#includeintmain(){voidsearch(float(*p)[4],intn);floatscore[3][4]={{65,57,70,60},{80,7,90,81},{90,99,100,98}};search(score,3);return0;}voidsearch(float(*p)[4],intn){inti,j,flag;for(j=0;j{flag=0;for(i=0;i<4;i++)if(*(*(p+j)+i)<60)flag=1;if(flag==1){printf("NO.%dfails,hisscoreare:\n",j+1);for(i=0;i<4;i++)printf("%5.1f\t",*(*(p+j)+i));printf("\n");}}}8.4通过指针引用字符串8.4.1字符串的表示形式(1)用字符数组存放一个字符串。例8.14定义一个字符数组,对它初始化,然后输出该字符串。#includeintmain(){charstring[]="Ilovexiaolei!";printf("%s\n",string);return0;}(2)用字符指针指向一个字符串#includeintmain(){charstring[]="Ilovexiaolei!";printf("%s\n",string);return0;}例8.16将字符串a复制为字符串b。#includeintmain(){chara[]="Ilovemiao!",b[20];inti;for(i=0;a[i]!='\0';i++)*(b+i)=*(a+i);*(b+i)='\0';printf("stringais:%s\n",a);printf("stringbis:");for(i=0;b[i]!='\0';i++)printf("%c",b[i]);printf("\n");}例8.17用指针变量来处理例8.16问题。#includeintmain(){chara[]="Ilovemiao!",b[20];inti;char*p1,*p2;p1=a;p2=b;for(;*p1!='\0';p1++,p2++)*p2=*p1;*p2='\0';printf("stringais:%s\n",a);printf("stringbis:");for(i=0;b[i]!='\0';i++)printf("%c",b[i]);printf("\n");}8.4.2字符指针作函数参数例8.18用函数调用实现字符串的复制。#includeintmain(){voidcopy_string(char*from,char*to);char*a="Iamateacher.";charb[]="Youareastudent!";char*p=b;printf("stringa=%s\nstringb=%s\n",a,p);printf("copystringatostringb:\n");copy_string(a,p);printf("stringa=%s\nstringb=%s\n",a,b);}voidcopy_string(char*from,char*to){for(;*from!='\0';from++,to++)*to=*from;*to='\0';}调用函数时实参与形参对应关系实参行参实参形参字符数组名字符数组名字符数组名字符指针变量字符指针变量字符指针变量字符指针变量字符数组名8.4.3对使用字符指针变量和字符数组的讨论(1)字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址,绝不是将字符串存放在字符指针变量中。(2)赋值方式。对字符数组只能对各个元素赋值。(3)数组可以再定义时整体赋初值,但不能再赋值语句中整体赋值。(4)如果定义一个字符数组,在编译时为它分配内存单元,它有确定的地址。(5)指针变量的值是可以改变的。例8.19改变指针变量的值。#includeintmain(){char*a="Ilovexiaolei!";a=a+7;printf("%s\n",a);return0;}8.5指向函数的指针8.5.1什么是函数指针?如果在程序中定义了一个函数,在编译时,编译系统为函数代码分配一段存储空间,这段代码的存储空间的起始地址(又称入口地址)称为这个函数的指针。8.5.2用函数指针变量调用函数例8.20用函数求a和b中的大者。(通过指针变量来访问它指向的函数)。#includeintmain(){intmax(int,int);int(*p)(int,int);inta,b,c;p=max;printf("pleaseentera,b\n:");scanf("%d,%d",&a,&b);c=(*p)(a,b);printf("a=%d,b=%d,max=%d\n",a,b,c);return0;}intmax(intx,inty){intz;if(x>y)z=x;elsez=y;returnz;}int(*p)(int,int);用来定义p是一个指向函数的指针变量,该函数有两个整型参数,函数值是整型。(1)指向函数的指针变量一般的定义形式是:数据类型(*指针变量名)(函数参数列表);(2)“int(*p)(int,int);”表示定义一个指向函数的指针变量p,它不是固定只指向某一个函数,而只是表示定义了这样一个类型的变量,它是专门用来存放函数的入口地址。(3)如果要用指针调用函数,必须先使指针变量指向该函数。(4)在给函数指针变量赋值时,只须给出函数名而不必给出参数。(5)用函数指针变量调用函数时,只须将(*p)代替函数名即可,在(*p)之后的括号内根据需要写上实参。(6)指向函数的指针变量,p+n,p++,p--等运算是无意义的。例8.21输入两个整数,然后让用户选择1或者2,选1时调用max函数,输出两者中的大数,选2时调用min函数,输出两者的小数。#include
k=j;
if(k!
=i)
t=x[i];
x[i]=x[k];
x[k]=t;
用指针变量作函数形参:
voidsort(int*x,intn);
voidsort(int*x,intn)
for(i=0;i{k=i;for(j=i+1;jif(*(x+k)<*(x+j))k=j;if(k!=i){t=*(x+i);*(x+i)=*(x+k);*(x+k)=t;}}}8.3.5通过指针引用多维数组1多维数组元素的地址多维数组中*(a+i)只是a[i]的另一种表示形式。二维数组中,a+i指的不是一个数组元素的存储单元。在二维数组中,a+i,a[i],*(a+i),&a[i],&a[i][0]的值相等,即它们代表同一地址。2.指向多维数组元素的指针变量例8.10用指向元素的指针变量输出二维数组各元素的值。#includeintmain(){int*p,a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};for(p=a[0];p{if((p-a[0])%4==0)printf("\n");printf("%d\t",*p);}return0;}例8.11输出二维数组任一行任一列元素的值。#includeintmain(){inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12},i,j;int(*p)[4];p=a;scanf("%d,%d",&i,&j);printf("a[%d][%d]=%d",i,j,*(*(p+i)+j));return0;}int(*p)[4]表示p是一个指针变量,它指向包含4个整型元素的一维数组。p是指向一维数组的指针。p不能指向一位数组中的某一元素。3.用指向数组的指针作函数参数例8.12有一个班,3个学生,各学4门课。计算总平均分数以及第n个学生的成绩。#includeintmain(){voidaverage(float*p,intn);voidsearch(float(*p)[4],intn);floatscore[3][4]={{65,67,70,60},{80,87,90,81},{90,99,100,98}};average(score,12);search(score,2);}voidaverage(float*p,intn){float*p_end;floatsum=0,aver;p_end=p+n-1;for(;p<=p_end;p++)sum=sum+(*p);aver=sum/n;printf("average=%5.2f\n",aver);}voidsearch(float(*p)[4],intn){inti;printf("ThescoreofNO.%dare:\n",n);for(i=0;i<4;i++)printf("%5.2f\t",*(*(p+n)+i));printf("\n");}例8.13在例8.12的基础上,查找有一门以上课程不及格的学生,输出他们的全部课程的成绩。#includeintmain(){voidsearch(float(*p)[4],intn);floatscore[3][4]={{65,57,70,60},{80,7,90,81},{90,99,100,98}};search(score,3);return0;}voidsearch(float(*p)[4],intn){inti,j,flag;for(j=0;j{flag=0;for(i=0;i<4;i++)if(*(*(p+j)+i)<60)flag=1;if(flag==1){printf("NO.%dfails,hisscoreare:\n",j+1);for(i=0;i<4;i++)printf("%5.1f\t",*(*(p+j)+i));printf("\n");}}}8.4通过指针引用字符串8.4.1字符串的表示形式(1)用字符数组存放一个字符串。例8.14定义一个字符数组,对它初始化,然后输出该字符串。#includeintmain(){charstring[]="Ilovexiaolei!";printf("%s\n",string);return0;}(2)用字符指针指向一个字符串#includeintmain(){charstring[]="Ilovexiaolei!";printf("%s\n",string);return0;}例8.16将字符串a复制为字符串b。#includeintmain(){chara[]="Ilovemiao!",b[20];inti;for(i=0;a[i]!='\0';i++)*(b+i)=*(a+i);*(b+i)='\0';printf("stringais:%s\n",a);printf("stringbis:");for(i=0;b[i]!='\0';i++)printf("%c",b[i]);printf("\n");}例8.17用指针变量来处理例8.16问题。#includeintmain(){chara[]="Ilovemiao!",b[20];inti;char*p1,*p2;p1=a;p2=b;for(;*p1!='\0';p1++,p2++)*p2=*p1;*p2='\0';printf("stringais:%s\n",a);printf("stringbis:");for(i=0;b[i]!='\0';i++)printf("%c",b[i]);printf("\n");}8.4.2字符指针作函数参数例8.18用函数调用实现字符串的复制。#includeintmain(){voidcopy_string(char*from,char*to);char*a="Iamateacher.";charb[]="Youareastudent!";char*p=b;printf("stringa=%s\nstringb=%s\n",a,p);printf("copystringatostringb:\n");copy_string(a,p);printf("stringa=%s\nstringb=%s\n",a,b);}voidcopy_string(char*from,char*to){for(;*from!='\0';from++,to++)*to=*from;*to='\0';}调用函数时实参与形参对应关系实参行参实参形参字符数组名字符数组名字符数组名字符指针变量字符指针变量字符指针变量字符指针变量字符数组名8.4.3对使用字符指针变量和字符数组的讨论(1)字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址,绝不是将字符串存放在字符指针变量中。(2)赋值方式。对字符数组只能对各个元素赋值。(3)数组可以再定义时整体赋初值,但不能再赋值语句中整体赋值。(4)如果定义一个字符数组,在编译时为它分配内存单元,它有确定的地址。(5)指针变量的值是可以改变的。例8.19改变指针变量的值。#includeintmain(){char*a="Ilovexiaolei!";a=a+7;printf("%s\n",a);return0;}8.5指向函数的指针8.5.1什么是函数指针?如果在程序中定义了一个函数,在编译时,编译系统为函数代码分配一段存储空间,这段代码的存储空间的起始地址(又称入口地址)称为这个函数的指针。8.5.2用函数指针变量调用函数例8.20用函数求a和b中的大者。(通过指针变量来访问它指向的函数)。#includeintmain(){intmax(int,int);int(*p)(int,int);inta,b,c;p=max;printf("pleaseentera,b\n:");scanf("%d,%d",&a,&b);c=(*p)(a,b);printf("a=%d,b=%d,max=%d\n",a,b,c);return0;}intmax(intx,inty){intz;if(x>y)z=x;elsez=y;returnz;}int(*p)(int,int);用来定义p是一个指向函数的指针变量,该函数有两个整型参数,函数值是整型。(1)指向函数的指针变量一般的定义形式是:数据类型(*指针变量名)(函数参数列表);(2)“int(*p)(int,int);”表示定义一个指向函数的指针变量p,它不是固定只指向某一个函数,而只是表示定义了这样一个类型的变量,它是专门用来存放函数的入口地址。(3)如果要用指针调用函数,必须先使指针变量指向该函数。(4)在给函数指针变量赋值时,只须给出函数名而不必给出参数。(5)用函数指针变量调用函数时,只须将(*p)代替函数名即可,在(*p)之后的括号内根据需要写上实参。(6)指向函数的指针变量,p+n,p++,p--等运算是无意义的。例8.21输入两个整数,然后让用户选择1或者2,选1时调用max函数,输出两者中的大数,选2时调用min函数,输出两者的小数。#include
for(j=i+1;jif(*(x+k)<*(x+j))k=j;if(k!=i){t=*(x+i);*(x+i)=*(x+k);*(x+k)=t;}}}8.3.5通过指针引用多维数组1多维数组元素的地址多维数组中*(a+i)只是a[i]的另一种表示形式。二维数组中,a+i指的不是一个数组元素的存储单元。在二维数组中,a+i,a[i],*(a+i),&a[i],&a[i][0]的值相等,即它们代表同一地址。2.指向多维数组元素的指针变量例8.10用指向元素的指针变量输出二维数组各元素的值。#includeintmain(){int*p,a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};for(p=a[0];p{if((p-a[0])%4==0)printf("\n");printf("%d\t",*p);}return0;}例8.11输出二维数组任一行任一列元素的值。#includeintmain(){inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12},i,j;int(*p)[4];p=a;scanf("%d,%d",&i,&j);printf("a[%d][%d]=%d",i,j,*(*(p+i)+j));return0;}int(*p)[4]表示p是一个指针变量,它指向包含4个整型元素的一维数组。p是指向一维数组的指针。p不能指向一位数组中的某一元素。3.用指向数组的指针作函数参数例8.12有一个班,3个学生,各学4门课。计算总平均分数以及第n个学生的成绩。#includeintmain(){voidaverage(float*p,intn);voidsearch(float(*p)[4],intn);floatscore[3][4]={{65,67,70,60},{80,87,90,81},{90,99,100,98}};average(score,12);search(score,2);}voidaverage(float*p,intn){float*p_end;floatsum=0,aver;p_end=p+n-1;for(;p<=p_end;p++)sum=sum+(*p);aver=sum/n;printf("average=%5.2f\n",aver);}voidsearch(float(*p)[4],intn){inti;printf("ThescoreofNO.%dare:\n",n);for(i=0;i<4;i++)printf("%5.2f\t",*(*(p+n)+i));printf("\n");}例8.13在例8.12的基础上,查找有一门以上课程不及格的学生,输出他们的全部课程的成绩。#includeintmain(){voidsearch(float(*p)[4],intn);floatscore[3][4]={{65,57,70,60},{80,7,90,81},{90,99,100,98}};search(score,3);return0;}voidsearch(float(*p)[4],intn){inti,j,flag;for(j=0;j{flag=0;for(i=0;i<4;i++)if(*(*(p+j)+i)<60)flag=1;if(flag==1){printf("NO.%dfails,hisscoreare:\n",j+1);for(i=0;i<4;i++)printf("%5.1f\t",*(*(p+j)+i));printf("\n");}}}8.4通过指针引用字符串8.4.1字符串的表示形式(1)用字符数组存放一个字符串。例8.14定义一个字符数组,对它初始化,然后输出该字符串。#includeintmain(){charstring[]="Ilovexiaolei!";printf("%s\n",string);return0;}(2)用字符指针指向一个字符串#includeintmain(){charstring[]="Ilovexiaolei!";printf("%s\n",string);return0;}例8.16将字符串a复制为字符串b。#includeintmain(){chara[]="Ilovemiao!",b[20];inti;for(i=0;a[i]!='\0';i++)*(b+i)=*(a+i);*(b+i)='\0';printf("stringais:%s\n",a);printf("stringbis:");for(i=0;b[i]!='\0';i++)printf("%c",b[i]);printf("\n");}例8.17用指针变量来处理例8.16问题。#includeintmain(){chara[]="Ilovemiao!",b[20];inti;char*p1,*p2;p1=a;p2=b;for(;*p1!='\0';p1++,p2++)*p2=*p1;*p2='\0';printf("stringais:%s\n",a);printf("stringbis:");for(i=0;b[i]!='\0';i++)printf("%c",b[i]);printf("\n");}8.4.2字符指针作函数参数例8.18用函数调用实现字符串的复制。#includeintmain(){voidcopy_string(char*from,char*to);char*a="Iamateacher.";charb[]="Youareastudent!";char*p=b;printf("stringa=%s\nstringb=%s\n",a,p);printf("copystringatostringb:\n");copy_string(a,p);printf("stringa=%s\nstringb=%s\n",a,b);}voidcopy_string(char*from,char*to){for(;*from!='\0';from++,to++)*to=*from;*to='\0';}调用函数时实参与形参对应关系实参行参实参形参字符数组名字符数组名字符数组名字符指针变量字符指针变量字符指针变量字符指针变量字符数组名8.4.3对使用字符指针变量和字符数组的讨论(1)字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址,绝不是将字符串存放在字符指针变量中。(2)赋值方式。对字符数组只能对各个元素赋值。(3)数组可以再定义时整体赋初值,但不能再赋值语句中整体赋值。(4)如果定义一个字符数组,在编译时为它分配内存单元,它有确定的地址。(5)指针变量的值是可以改变的。例8.19改变指针变量的值。#includeintmain(){char*a="Ilovexiaolei!";a=a+7;printf("%s\n",a);return0;}8.5指向函数的指针8.5.1什么是函数指针?如果在程序中定义了一个函数,在编译时,编译系统为函数代码分配一段存储空间,这段代码的存储空间的起始地址(又称入口地址)称为这个函数的指针。8.5.2用函数指针变量调用函数例8.20用函数求a和b中的大者。(通过指针变量来访问它指向的函数)。#includeintmain(){intmax(int,int);int(*p)(int,int);inta,b,c;p=max;printf("pleaseentera,b\n:");scanf("%d,%d",&a,&b);c=(*p)(a,b);printf("a=%d,b=%d,max=%d\n",a,b,c);return0;}intmax(intx,inty){intz;if(x>y)z=x;elsez=y;returnz;}int(*p)(int,int);用来定义p是一个指向函数的指针变量,该函数有两个整型参数,函数值是整型。(1)指向函数的指针变量一般的定义形式是:数据类型(*指针变量名)(函数参数列表);(2)“int(*p)(int,int);”表示定义一个指向函数的指针变量p,它不是固定只指向某一个函数,而只是表示定义了这样一个类型的变量,它是专门用来存放函数的入口地址。(3)如果要用指针调用函数,必须先使指针变量指向该函数。(4)在给函数指针变量赋值时,只须给出函数名而不必给出参数。(5)用函数指针变量调用函数时,只须将(*p)代替函数名即可,在(*p)之后的括号内根据需要写上实参。(6)指向函数的指针变量,p+n,p++,p--等运算是无意义的。例8.21输入两个整数,然后让用户选择1或者2,选1时调用max函数,输出两者中的大数,选2时调用min函数,输出两者的小数。#include
if(*(x+k)<*(x+j))
t=*(x+i);
*(x+i)=*(x+k);
*(x+k)=t;
8.3.5通过指针引用多维数组
1多维数组元素的地址
多维数组中*(a+i)只是a[i]的另一种表示形式。
二维数组中,a+i指的不是一个数组元素的存储单元。
在二维数组中,a+i,a[i],*(a+i),&a[i],&a[i][0]的值相等,即它们代表同一地址。
2.指向多维数组元素的指针变量
例8.10用指向元素的指针变量输出二维数组各元素的值。
int*p,a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
for(p=a[0];p{if((p-a[0])%4==0)printf("\n");printf("%d\t",*p);}return0;}例8.11输出二维数组任一行任一列元素的值。#includeintmain(){inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12},i,j;int(*p)[4];p=a;scanf("%d,%d",&i,&j);printf("a[%d][%d]=%d",i,j,*(*(p+i)+j));return0;}int(*p)[4]表示p是一个指针变量,它指向包含4个整型元素的一维数组。p是指向一维数组的指针。p不能指向一位数组中的某一元素。3.用指向数组的指针作函数参数例8.12有一个班,3个学生,各学4门课。计算总平均分数以及第n个学生的成绩。#includeintmain(){voidaverage(float*p,intn);voidsearch(float(*p)[4],intn);floatscore[3][4]={{65,67,70,60},{80,87,90,81},{90,99,100,98}};average(score,12);search(score,2);}voidaverage(float*p,intn){float*p_end;floatsum=0,aver;p_end=p+n-1;for(;p<=p_end;p++)sum=sum+(*p);aver=sum/n;printf("average=%5.2f\n",aver);}voidsearch(float(*p)[4],intn){inti;printf("ThescoreofNO.%dare:\n",n);for(i=0;i<4;i++)printf("%5.2f\t",*(*(p+n)+i));printf("\n");}例8.13在例8.12的基础上,查找有一门以上课程不及格的学生,输出他们的全部课程的成绩。#includeintmain(){voidsearch(float(*p)[4],intn);floatscore[3][4]={{65,57,70,60},{80,7,90,81},{90,99,100,98}};search(score,3);return0;}voidsearch(float(*p)[4],intn){inti,j,flag;for(j=0;j{flag=0;for(i=0;i<4;i++)if(*(*(p+j)+i)<60)flag=1;if(flag==1){printf("NO.%dfails,hisscoreare:\n",j+1);for(i=0;i<4;i++)printf("%5.1f\t",*(*(p+j)+i));printf("\n");}}}8.4通过指针引用字符串8.4.1字符串的表示形式(1)用字符数组存放一个字符串。例8.14定义一个字符数组,对它初始化,然后输出该字符串。#includeintmain(){charstring[]="Ilovexiaolei!";printf("%s\n",string);return0;}(2)用字符指针指向一个字符串#includeintmain(){charstring[]="Ilovexiaolei!";printf("%s\n",string);return0;}例8.16将字符串a复制为字符串b。#includeintmain(){chara[]="Ilovemiao!",b[20];inti;for(i=0;a[i]!='\0';i++)*(b+i)=*(a+i);*(b+i)='\0';printf("stringais:%s\n",a);printf("stringbis:");for(i=0;b[i]!='\0';i++)printf("%c",b[i]);printf("\n");}例8.17用指针变量来处理例8.16问题。#includeintmain(){chara[]="Ilovemiao!",b[20];inti;char*p1,*p2;p1=a;p2=b;for(;*p1!='\0';p1++,p2++)*p2=*p1;*p2='\0';printf("stringais:%s\n",a);printf("stringbis:");for(i=0;b[i]!='\0';i++)printf("%c",b[i]);printf("\n");}8.4.2字符指针作函数参数例8.18用函数调用实现字符串的复制。#includeintmain(){voidcopy_string(char*from,char*to);char*a="Iamateacher.";charb[]="Youareastudent!";char*p=b;printf("stringa=%s\nstringb=%s\n",a,p);printf("copystringatostringb:\n");copy_string(a,p);printf("stringa=%s\nstringb=%s\n",a,b);}voidcopy_string(char*from,char*to){for(;*from!='\0';from++,to++)*to=*from;*to='\0';}调用函数时实参与形参对应关系实参行参实参形参字符数组名字符数组名字符数组名字符指针变量字符指针变量字符指针变量字符指针变量字符数组名8.4.3对使用字符指针变量和字符数组的讨论(1)字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址,绝不是将字符串存放在字符指针变量中。(2)赋值方式。对字符数组只能对各个元素赋值。(3)数组可以再定义时整体赋初值,但不能再赋值语句中整体赋值。(4)如果定义一个字符数组,在编译时为它分配内存单元,它有确定的地址。(5)指针变量的值是可以改变的。例8.19改变指针变量的值。#includeintmain(){char*a="Ilovexiaolei!";a=a+7;printf("%s\n",a);return0;}8.5指向函数的指针8.5.1什么是函数指针?如果在程序中定义了一个函数,在编译时,编译系统为函数代码分配一段存储空间,这段代码的存储空间的起始地址(又称入口地址)称为这个函数的指针。8.5.2用函数指针变量调用函数例8.20用函数求a和b中的大者。(通过指针变量来访问它指向的函数)。#includeintmain(){intmax(int,int);int(*p)(int,int);inta,b,c;p=max;printf("pleaseentera,b\n:");scanf("%d,%d",&a,&b);c=(*p)(a,b);printf("a=%d,b=%d,max=%d\n",a,b,c);return0;}intmax(intx,inty){intz;if(x>y)z=x;elsez=y;returnz;}int(*p)(int,int);用来定义p是一个指向函数的指针变量,该函数有两个整型参数,函数值是整型。(1)指向函数的指针变量一般的定义形式是:数据类型(*指针变量名)(函数参数列表);(2)“int(*p)(int,int);”表示定义一个指向函数的指针变量p,它不是固定只指向某一个函数,而只是表示定义了这样一个类型的变量,它是专门用来存放函数的入口地址。(3)如果要用指针调用函数,必须先使指针变量指向该函数。(4)在给函数指针变量赋值时,只须给出函数名而不必给出参数。(5)用函数指针变量调用函数时,只须将(*p)代替函数名即可,在(*p)之后的括号内根据需要写上实参。(6)指向函数的指针变量,p+n,p++,p--等运算是无意义的。例8.21输入两个整数,然后让用户选择1或者2,选1时调用max函数,输出两者中的大数,选2时调用min函数,输出两者的小数。#include
if((p-a[0])%4==0)
例8.11输出二维数组任一行任一列元素的值。
inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12},i,j;
int(*p)[4];
scanf("%d,%d",&i,&j);
printf("a[%d][%d]=%d",i,j,*(*(p+i)+j));
int(*p)[4]表示p是一个指针变量,它指向包含4个整型元素的一维数组。
p是指向一维数组的指针。
p不能指向一位数组中的某一元素。
3.用指向数组的指针作函数参数
例8.12有一个班,3个学生,各学4门课。
计算总平均分数以及第n个学生的成绩。
voidaverage(float*p,intn);
voidsearch(float(*p)[4],intn);
floatscore[3][4]={{65,67,70,60},{80,87,90,81},{90,99,100,98}};
average(score,12);
search(score,2);
voidaverage(float*p,intn)
float*p_end;
floatsum=0,aver;
p_end=p+n-1;
for(;p<=p_end;p++)
sum=sum+(*p);
aver=sum/n;
printf("average=%5.2f\n",aver);
voidsearch(float(*p)[4],intn)
printf("ThescoreofNO.%dare:
\n",n);
for(i=0;i<4;i++)
printf("%5.2f\t",*(*(p+n)+i));
例8.13在例8.12的基础上,查找有一门以上课程不及格的学生,输出他们的全部课程的成绩。
floatscore[3][4]={{65,57,70,60},{80,7,90,81},{90,99,100,98}};
search(score,3);
inti,j,flag;
for(j=0;j{flag=0;for(i=0;i<4;i++)if(*(*(p+j)+i)<60)flag=1;if(flag==1){printf("NO.%dfails,hisscoreare:\n",j+1);for(i=0;i<4;i++)printf("%5.1f\t",*(*(p+j)+i));printf("\n");}}}8.4通过指针引用字符串8.4.1字符串的表示形式(1)用字符数组存放一个字符串。例8.14定义一个字符数组,对它初始化,然后输出该字符串。#includeintmain(){charstring[]="Ilovexiaolei!";printf("%s\n",string);return0;}(2)用字符指针指向一个字符串#includeintmain(){charstring[]="Ilovexiaolei!";printf("%s\n",string);return0;}例8.16将字符串a复制为字符串b。#includeintmain(){chara[]="Ilovemiao!",b[20];inti;for(i=0;a[i]!='\0';i++)*(b+i)=*(a+i);*(b+i)='\0';printf("stringais:%s\n",a);printf("stringbis:");for(i=0;b[i]!='\0';i++)printf("%c",b[i]);printf("\n");}例8.17用指针变量来处理例8.16问题。#includeintmain(){chara[]="Ilovemiao!",b[20];inti;char*p1,*p2;p1=a;p2=b;for(;*p1!='\0';p1++,p2++)*p2=*p1;*p2='\0';printf("stringais:%s\n",a);printf("stringbis:");for(i=0;b[i]!='\0';i++)printf("%c",b[i]);printf("\n");}8.4.2字符指针作函数参数例8.18用函数调用实现字符串的复制。#includeintmain(){voidcopy_string(char*from,char*to);char*a="Iamateacher.";charb[]="Youareastudent!";char*p=b;printf("stringa=%s\nstringb=%s\n",a,p);printf("copystringatostringb:\n");copy_string(a,p);printf("stringa=%s\nstringb=%s\n",a,b);}voidcopy_string(char*from,char*to){for(;*from!='\0';from++,to++)*to=*from;*to='\0';}调用函数时实参与形参对应关系实参行参实参形参字符数组名字符数组名字符数组名字符指针变量字符指针变量字符指针变量字符指针变量字符数组名8.4.3对使用字符指针变量和字符数组的讨论(1)字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址,绝不是将字符串存放在字符指针变量中。(2)赋值方式。对字符数组只能对各个元素赋值。(3)数组可以再定义时整体赋初值,但不能再赋值语句中整体赋值。(4)如果定义一个字符数组,在编译时为它分配内存单元,它有确定的地址。(5)指针变量的值是可以改变的。例8.19改变指针变量的值。#includeintmain(){char*a="Ilovexiaolei!";a=a+7;printf("%s\n",a);return0;}8.5指向函数的指针8.5.1什么是函数指针?如果在程序中定义了一个函数,在编译时,编译系统为函数代码分配一段存储空间,这段代码的存储空间的起始地址(又称入口地址)称为这个函数的指针。8.5.2用函数指针变量调用函数例8.20用函数求a和b中的大者。(通过指针变量来访问它指向的函数)。#includeintmain(){intmax(int,int);int(*p)(int,int);inta,b,c;p=max;printf("pleaseentera,b\n:");scanf("%d,%d",&a,&b);c=(*p)(a,b);printf("a=%d,b=%d,max=%d\n",a,b,c);return0;}intmax(intx,inty){intz;if(x>y)z=x;elsez=y;returnz;}int(*p)(int,int);用来定义p是一个指向函数的指针变量,该函数有两个整型参数,函数值是整型。(1)指向函数的指针变量一般的定义形式是:数据类型(*指针变量名)(函数参数列表);(2)“int(*p)(int,int);”表示定义一个指向函数的指针变量p,它不是固定只指向某一个函数,而只是表示定义了这样一个类型的变量,它是专门用来存放函数的入口地址。(3)如果要用指针调用函数,必须先使指针变量指向该函数。(4)在给函数指针变量赋值时,只须给出函数名而不必给出参数。(5)用函数指针变量调用函数时,只须将(*p)代替函数名即可,在(*p)之后的括号内根据需要写上实参。(6)指向函数的指针变量,p+n,p++,p--等运算是无意义的。例8.21输入两个整数,然后让用户选择1或者2,选1时调用max函数,输出两者中的大数,选2时调用min函数,输出两者的小数。#include
flag=0;
if(*(*(p+j)+i)<60)
flag=1;
if(flag==1)
printf("NO.%dfails,hisscoreare:
\n",j+1);
printf("%5.1f\t",*(*(p+j)+i));
8.4通过指针引用字符串
8.4.1字符串的表示形式
(1)用字符数组存放一个字符串。
例8.14定义一个字符数组,对它初始化,然后输出该字符串。
charstring[]="Ilovexiaolei!
";
printf("%s\n",string);
(2)用字符指针指向一个字符串
例8.16将字符串a复制为字符串b。
chara[]="Ilovemiao!
",b[20];
for(i=0;a[i]!
='\0';i++)
*(b+i)=*(a+i);
*(b+i)='\0';
printf("stringais:
%s\n",a);
printf("stringbis:
");
for(i=0;b[i]!
printf("%c",b[i]);
例8.17用指针变量来处理例8.16问题。
char*p1,*p2;
p1=a;
p2=b;
for(;*p1!
='\0';p1++,p2++)
*p2=*p1;
*p2='\0';
8.4.2字符指针作函数参数
例8.18用函数调用实现字符串的复制。
voidcopy_string(char*from,char*to);
char*a="Iamateacher.";
charb[]="Youareastudent!
char*p=b;
printf("stringa=%s\nstringb=%s\n",a,p);
printf("copystringatostringb:
copy_string(a,p);
printf("stringa=%s\nstringb=%s\n",a,b);
voidcopy_string(char*from,char*to)
for(;*from!
='\0';from++,to++)
*to=*from;
*to='\0';
调用函数时实参与形参对应关系
实参
行参
形参
字符数组名
字符指针变量
8.4.3对使用字符指针变量和字符数组的讨论
(1)字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址,绝不是将字符串存放在字符指针变量中。
(2)赋值方式。
对字符数组只能对各个元素赋值。
(3)数组可以再定义时整体赋初值,但不能再赋值语句中整体赋值。
(4)如果定义一个字符数组,在编译时为它分配内存单元,它有确定的地址。
(5)指针变量的值是可以改变的。
例8.19改变指针变量的值。
char*a="Ilovexiaolei!
a=a+7;
printf("%s\n",a);
8.5指向函数的指针
8.5.1什么是函数指针?
如果在程序中定义了一个函数,在编译时,编译系统为函数代码分配一段存储空间,这段代码的存储空间的起始地址(又称入口地址)称为这个函数的指针。
8.5.2用函数指针变量调用函数
例8.20用函数求a和b中的大者。
(通过指针变量来访问它指向的函数)。
intmax(int,int);
int(*p)(int,int);
p=max;
printf("pleaseentera,b\n:
c=(*p)(a,b);
printf("a=%d,b=%d,max=%d\n",a,b,c);
intmax(intx,inty)
intz;
if(x>y)
z=x;
else
z=y;
returnz;
int(*p)(int,int);用来定义p是一个指向函数的指针变量,该函数有两个整型参数,函数值是整型。
(1)指向函数的指针变量一般的定义形式是:
数据类型(*指针变量名)(函数参数列表);
(2)“int(*p)(int,int);”表示定义一个指向函数的指针变量p,它不是固定只指向某一个函数,而只是表示定义了这样一个类型的变量,它是专门用来存放函数的入口地址。
(3)如果要用指针调用函数,必须先使指针变量指向该函数。
(4)在给函数指针变量赋值时,只须给出函数名而不必给出参数。
(5)用函数指针变量调用函数时,只须将(*p)代替函数名即可,在(*p)之后的括号内根据需要写上实参。
(6)指向函数的指针变量,p+n,p++,p--等运算是无意义的。
例8.21输入两个整数,然后让用户选择1或者2,选1时调用max函数,输出两者中的大数,选2时调用min函数,输出两者的小数。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1