谭浩强c语言程序设计教程学习笔记第8章.docx

上传人:b****8 文档编号:23856313 上传时间:2023-05-21 格式:DOCX 页数:38 大小:27.72KB
下载 相关 举报
谭浩强c语言程序设计教程学习笔记第8章.docx_第1页
第1页 / 共38页
谭浩强c语言程序设计教程学习笔记第8章.docx_第2页
第2页 / 共38页
谭浩强c语言程序设计教程学习笔记第8章.docx_第3页
第3页 / 共38页
谭浩强c语言程序设计教程学习笔记第8章.docx_第4页
第4页 / 共38页
谭浩强c语言程序设计教程学习笔记第8章.docx_第5页
第5页 / 共38页
点击查看更多>>
下载资源
资源描述

谭浩强c语言程序设计教程学习笔记第8章.docx

《谭浩强c语言程序设计教程学习笔记第8章.docx》由会员分享,可在线阅读,更多相关《谭浩强c语言程序设计教程学习笔记第8章.docx(38页珍藏版)》请在冰豆网上搜索。

谭浩强c语言程序设计教程学习笔记第8章.docx

谭浩强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。

#include

intmain()

{

int*p,*p1,*p2;

inta,b;

printf("pleaseentera,b:

\n");

scanf("%d,%d",&a,&b);

p1=&a;

p2=&b;

if(a

{

p=p1;

p1=p2;

p2=p;

}

printf("a=%d,b=%d\n",a,b);

printf("max=%d,min=%d\n",*p1,*p2);

return0;

}

8.2.3指针变量作为函数参数

指针变量作函数参数的作用是将一个变量的地址传到另一个函数中。

例8.3输入a,b连个整数,按先大后小的顺序输出a,b。

用指针变量作函数参数。

#include

intmain()

{

voidswap(int*,int*);

int*p1,*p2;

inta,b;

printf("pleaseentera,b:

\n");

scanf("%d,%d",&a,&b);

p1=&a;

p2=&b;

if(a

swap(p1,p2);

printf("a=%d,b=%d\n",a,b);

printf("max=%d,min=%d\n",*p1,*p2);

return0;

}

voidswap(int*p1,int*p2)

{

inttemp;

temp=*p1;

*p1=*p2;

*p2=temp;

}

不可能通过执行调用函数来改变实参指针变量的值,但是却可以改变实参指针变量所指变量的值。

例8.4输入3个整数a,b,c,要求按大小顺序将它们输出。

用函数实现改变这3个变量的值。

#include

intmain()

{

voidexchange(int*,int*,int*);

int*p3,*p1,*p2;

inta,b,c;

printf("pleaseentera,b,c:

\n");

scanf("%d,%d,%d",&a,&b,&c);

p1=&a;

p2=&b;

p3=&c;

exchange(p1,p2,p3);

printf("%d,%d,%d\n",a,b,c);

return0;

}

voidexchange(int*q1,int*q2,int*q3)

{

voidswap(int*,int*);

if(*q1<*q2)

swap(q1,q2);

if(*q1<*q3)

swap(q1,q3);

if(*q2,*q3)

swap(q2,q3);

}

voidswap(int*p1,int*p2)

{

inttemp;

temp=*p1;

*p1=*p2;

*p2=temp;

}

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)下标法

#include

intmain()

{

inta[10];

inti;

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

scanf("%d",&a[i]);

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

printf("%d\t",a[i]);

printf("\n");

}

(2)通过数组名计算数组元素地址,找出元素的值。

#include

intmain()

{

inta[10];

inti;

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

scanf("%d",&a[i]);

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

printf("%d\t",*(a+i));

printf("\n");

}

(3)用指针变量指向数组元素

#include

intmain()

{

inta[10];

inti,*p;

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

scanf("%d",&a[i]);

for(p=a;p<(a+10);p++)

printf("%d\t",*p);

printf("\n");

}

例8.6通过指针变量输出a数组的10个元素。

#include

intmain()

{

int*p,i,a[10];

p=a;

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

scanf("%d",p++);

p=a;

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

printf("%d\t",*p);

printf("\n");

}

8.3.4用数组名作函数参数

表以变量名和数组名作为函数参数的比较

实参类型

变量名

数组名

要求形参的类型

变量名

数组名或指针变量

传递的信息

变量的值

实参数组首元素的地址

通过函数调用能否改变实参的值

不能

能改变是参数组元素的值

用变量名作为函数参数传递的是变量的值,当用数组名作为函数参数时,由于数组名代表的是数组首元素地址,因此传递的值是地址,所以要求形参是指针变量。

例8.7将数组a中n个整数按相反顺序存放。

#include

intmain()

{

voidinv(intx[],intn);

inta[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");

inv(a,10);

printf("Thearrayhasbeenreversed:

\n");

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

printf("%d\t",a[i]);

return0;

}

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.

#include

intmain()

{

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;p

printf("%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用选择法对十个整数按由大到小排序。

#include

intmain()

{

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;j

if(x[k]

k=j;

if(k!

=i)

{

t=x[i];

x[i]=x[k];

x[k]=t;

}

}

}

用指针变量作函数形参:

#include

intmain()

{

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;j

if(*(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用指向元素的指针变量输出二维数组各元素的值。

#include

intmain()

{

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输出二维数组任一行任一列元素的值。

#include

intmain()

{

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个学生的成绩。

#include

intmain()

{

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的基础上,查找有一门以上课程不及格的学生,输出他们的全部课程的成绩。

#include

intmain()

{

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定义一个字符数组,对它初始化,然后输出该字符串。

#include

intmain()

{

charstring[]="Ilovexiaolei!

";

printf("%s\n",string);

return0;

}

(2)用字符指针指向一个字符串

#include

intmain()

{

charstring[]="Ilovexiaolei!

";

printf("%s\n",string);

return0;

}

例8.16将字符串a复制为字符串b。

#include

intmain()

{

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问题。

#include

intmain()

{

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用函数调用实现字符串的复制。

#include

intmain()

{

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改变指针变量的值。

#include

intmain()

{

char*a="Ilovexiaolei!

";

a=a+7;

printf("%s\n",a);

return0;

}

8.5指向函数的指针

8.5.1什么是函数指针?

如果在程序中定义了一个函数,在编译时,编译系统为函数代码分配一段存储空间,这段代码的存储空间的起始地址(又称入口地址)称为这个函数的指针。

8.5.2用函数指针变量调用函数

例8.20用函数求a和b中的大者。

(通过指针变量来访问它指向的函数)。

#include

intmain()

{

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;

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函数,输出两者的小数。

#include

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 职业教育 > 职业技术培训

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1