第九讲 指 针.docx

上传人:b****7 文档编号:8801766 上传时间:2023-02-01 格式:DOCX 页数:26 大小:53.79KB
下载 相关 举报
第九讲 指 针.docx_第1页
第1页 / 共26页
第九讲 指 针.docx_第2页
第2页 / 共26页
第九讲 指 针.docx_第3页
第3页 / 共26页
第九讲 指 针.docx_第4页
第4页 / 共26页
第九讲 指 针.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

第九讲 指 针.docx

《第九讲 指 针.docx》由会员分享,可在线阅读,更多相关《第九讲 指 针.docx(26页珍藏版)》请在冰豆网上搜索。

第九讲 指 针.docx

第九讲指针

第九章指针

本章要点:

1.掌握指针与指针变量的概念;

2.掌握指针的定义;

3.掌握指针的运算;

4.掌握指向基本类型、数组、字符串、结构体的指针变量,了解函数指针变量;

5.掌握main()函数的命令行参数。

9.1指针概念

变量地址:

变量一定占用一个数据的存储空间,该存储空间的首地址称变量地址。

指针:

一个变量的地址称为该变量的指针。

指针变量:

若一个变量专用于存放另一个变量的地址(指针),则该变量称为指针变量。

若指针变量p的值等于变量x的地址,则说指针变量p指向变量x

直接访问:

按变量地址存取变量值的方式。

间接访问:

将变量i的地址存放在另一内存单元中。

如定义i_pointer为指针变量,i_pointer=&i;

(1)先找到存放i的地址的单元地址(3010,3011);

(2)取出i的地址(2000);

(3)到2000,2001中取出i的值3

9.2变量的指针和指向变量的

指针变量

9.2.1指针变量的定义

指针变量定义的形式:

类型标识符*标识符

例如:

float*pointer_x;

int*pointer_i;

作用:

定义某些变量为指针类型,使之专门用于存放地址。

注意:

(1)*用于定义指针变量,但指针变量名不带*

如int*point_i;

定义的指针变量为point_i,不是*point_i

(2)一个指针变量只能指向同一类型的变量

如int*point_i;

point_i只能用于指向整型变量。

9.2.2指针变量的引用

(1)取地址运算符&

(2)指针运算符*(取内容)

如:

若有变量定义:

inta,*pa;

a为变量;&a就是a的地址;

pa为指针变量;*pa就是pa指向的变量;

若pa=&a,则*pa实际就是a。

例如

main()

{inta,b;

int*pa,*pb;

a=100;b=10;

pa=&a;

pb=&b;

printf(“%d,%d\n”,a,b);

printf(“%d,%d\n”,*pa,*pb);

}

对*及&的说明:

(同级运算,由右向左)

例:

将两个整型数a,b按由大到小次序输出。

main()

{int*p1,*p2,*p,a,b;

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(“larger=%d,little=%d\n”,*p1,*p2);

}

运行情况:

5,9

a=5,b=9

larger=9,little=5

 

注意:

a和b并未交换,但p1和p2的值交换了

9.2.3指针变量作函数参数

作用:

将一个变量的地址传至另外一个函数中。

swap(p1,p2)

int*p1,*p2;

{intp;

p=*p1;

*p1=*p2;

*p2=p;

}

交换指针所指向的变量值

main()

{inta,b;

int*pa,*pb;

scanf(“%d,%d”,&a,&b);

pa=&a;pb=&b;

if(a

printf(“%d,%d\n”,a,b);

}

 

运行情况:

5,9

9,5

函数调用过程如下图所示:

 

开始调用swap函数,实参pa、pb分别向形式参数p1、p2传递数据

执行函数语句,p1、p2所指向的变量的值相互交换

函数调用结束后,p1、p2所占用的内存单元被释放,

·单向传递,值传递问题

swap(x,y)

intx,y;

{intt;

t=x;

x=y;

y=t;

}

main()

{inta,b;

scanf(“%d,%d”,&a,&b);

if(a

printf(“%d,%d\n”,a,b);

}

形参值的改变无法传递给实参

改变指针形参的值,也不能使指针实参的值改变

swap(p1,p2)

int*p1,*p2;

{int*p;

p=p1;

p1=p2;

p2=p;

}

C语言中,实参和形参间的数据是单向值传递方式。

指针做函数参数也遵循该原则

main()

{inta,b;

int*pa,*pb;

scanf(“%d,%d”,&a,&b);

pa=&a;pb=&b;

if(a

printf(“%d,%d\n”,*pa,*pb);

}

如输入数据为:

5,9

结果为:

5,9

9.3数组的指针和指向数组的

指针变量

·数组的指针:

数组的起始地址。

·数组元素的指针:

数组元素的地址。

·数组名可视为地址常量。

9.3.1指向数组元素的指针变量的定义与赋值

例如:

inta[10];

int*pa;

pa=a;(或pa=&a[0])

表明指针pa指向数组a的首地址;此时,指针对象*pa为a[0];

pa+n表示数组第n个数据的地址

即pa+n=&a[n]

*(pa+n)是a[n]

 

9.3.2通过指针引用数组元素

引用数组中的元素可以用以下方法:

下标法如a[3]

指针法即通过指向数组元素的指针找到所需的元素.这种方法占内存少,运行速度快,因此说程序的质量高.

假设p已定义为指针变量,并已赋了一个地址,它指向某一个

数组元素.且有赋值语句p=&a[0];则:

•p+1表示数组中的下一个元素,

•a+i和p+i都是a[i]的地址,或者说它们指向a[i].

•*(a+i)或*(p+i)是a+i或p+i所指向的数组元素。

•指向数组的指针变量也可带有下标,如p[i]与*(p+i)等价。

例:

输出数组全部元素

•下标法:

main()

{inta[10],i;

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

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

printf(“\n”);

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

printf(“%5d”,a[i]);

}

•通过数组名计算数组元素地址,找出数组元素

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

printf(“%5d”,*(a+i));

•用指针变量指向数组元素

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

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

例:

用指针处理数据。

#include“stdio.h”

main()

{inta[10],*pa,i;

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

a[i]=i+1;

pa=a;

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

printf(“%d”,*pa);

printf(“\n”);}

例:

给定10个整数,求最大值。

#include“stdio.h”

#defineN10

main()

{inta[N]={5,7,3,6,2,1,8,9,4,0};

inti,*p,max;

p=a;

max=*p++;

for(i=1;i

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

printf(“max=%d\n“,max);

}

9.3.3数组名作为函数参数

当用数组名作为参数时,如果形参数组中个元素的值发生

变化,实参数组元素的值也随之变化,为什么?

若有一个实参数组,想在函数中改变此数组的元素的值,实参与形参的对应关系有以下4种情况:

•形参与实参都用数组名

•实参用数组名,形参用指针变量

•实参形参均用指针变量

•实参为指针变量,形参为数组名

例如:

用选择法对10个整数排序

main()

{int*p,i,a[10];

voidsort();

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”,*p++);

}

voidsort(x,n)

intx[],n;

{inti,j,t;

for(i=0;i

{for(j=i+1;j

if(x[i]>x[j])

{t=x[i];

x[i]=x[j];

x[j]=t;}

}

}

9.3.4指向多维数组的指针和指针变量

一、多维数组的地址

假设数组名为a,起始地址设为200

Statica[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};则:

•a代表整个二维数组的首地址,即第0行的首地址

•a+1是数组a第1行首地址(208)

•a[0],a[1],a[2]是二维数组中三个一维数组的名字(地址),是第0行,第1行,第2行的首地址,即:

a[0]=a+0、a[1]=a+1、a[2]=a+2

•a[i]+j是第i行j列的地址

•*(a[i]+j)是该地址存储的值,

即a[i][j]

考虑*(a[2]+3)=?

注意:

•a[i]和*(a+i)无条件等价

•a+i、a[i]、*(a+i)、&a[i][0]均表示第i行首地址;

•&a[i][j]、a[i]+j、*(a+i)+j都是第i行j列元素的地址;

•a[i][j]、*(a[i]+j)、*(*(a+i)+j)都是第i行j列元素的值;

二、指向数组的指针变量

定义格式:

类型说明符(*变量名)[常量表达式]

功能:

定义一个名为“变量名”的指针变量,这个指针变量所指的对象是一个有“常量表达式”个元素的一维数组

例如:

若有int(*pa)[4];

则:

被定义成一个指针变量,它所指对象是一个有4个整型元素的数组

例如:

输出二维数组任一行任一列元素的值

main()

{inta[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};

int(*p)[4],i,j;

p=a;

scanf(“%d%d”,&i,&j);

printf(“a[%d][%d]=%d\n”,i,j,*(*(p+i)+j));

}

例如:

有一个班,3个学生,各学4门课,计算总平均分,以及第n个学生的成绩

voidaverage(p,n)

float*p;intn;

{floatsum=0,aver;

for(;p

sum=sum+(*p);

aver=sum/n;

printf(“average=%6.2f\n”,aver);

}

voidsearch(p,n)

float(*p)[4];intn;

{inti;

printf(“thescoreofNo.%dare:

\n”,n);

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

printf(“%6.2f“,*(*(p+n)+i));}

main()

{floatscore[3][4]={{65,67,70,80},{80,90,78,91},

{70,79,75,89}};

average(score,12);

search(score,2);

}

9.4字符串的指针和指向字符串的指针变量

9.4.1字符串的表示形式

1用字符数组表示,如:

mian()

{staticcharstring[]=“IloveChina!

”;

printf(“%s\n”,string);

}

2用字符指针实现,如:

mian()

{char*string=“IloveChina!

”;

printf(“%s\n”,string);

}

运行结果:

IloveChina!

请编写函数intfun(char*str),它的功能是判别字符串str是否是"回文",若是,返回1,否则返回0.

例如,“13531”,“helleh”是回文,但“1353”,“Helleh”不是回文.

#include"stdio.h"

intflag=0;

intfun(char*str)

{intn=0,k;

char*p1=str;

flag=0;

while(*p1){n++;p1++;}

for(k=0;k

if(*(str+k)==*(str+n-k)flag=1;

returnflag;}

voidmain()

{chars[128];

printf("\nPleadeenterstring:

\n");

gets(s);

fun(s);

}

字符指针使用中的几点事项:

1.要注意一些常用的符号。

如串的结束符是‘\0’

它的数值为0;回车符的数值为13;换行符

的值为10;文件结束符的数值为27;

2.字符指针常用于文件操作。

3.前面讲过的指针使用中要注意的问题同样适用于字符指针。

字符指针变量与字符数组的比较:

·字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是字符串的首地址。

·赋值方式:

对数组的赋值方法有:

charstr[]=“Iamaboy!

或:

charstr[20];

scanf(“%s”,str);

对字符指针变量的赋值方法有三种:

(1)char*pa=“Iamaboy!

(2)

(2)char*pa;

pa=“Iamaboy!

(3)char*pa,str[20];

pa=str;

scanf(“%s”,pa);

9.5函数的指针和指向函数的指针变量

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

可以用指针变量指向一个函数。

一个函数在编译时被分配一个入口地址,这个入口地址称为函数的指针。

例:

求a和b中的大者。

main()

{intmax();

int(*p)();

inta,b,c;

p=max;

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

c=(*p)(a,b);

printf(“a=%d,b=%d,max=%d”,a,b,c);

}

说明:

1.指向函数的指针变量的一般定义形式是:

数据类型标识符(*指针变量名)();

2.函数的调用可以通过函数名调用,也可以通过函数指针调用;

3.在一个程序中,一个指针变量可以先后指向不同的函数;

例如:

int(*p)();

intmax();

intmin();

p=max;c=(*p)(a,b);

······

p=min;c=(*p)(a,b);

4.在给函数指针变量赋值时,只需给出函数名而不必给出参数;

5.用函数指针变量调用函数时,只需将(*p)代替函数名即可(p为指针变量名),(*p)后的括号中应加相应实参。

9.5.2把指向函数的指针变量作函数参数

指向函数的指针变量可以也作为参数,以便实现函数地址的传递,即将函数名传给形参。

9.6返回指针值的函数

即可带回指针值的函数,其一般定义形式为:

类型标识符*函数名(参数表);

如int*a(x,y);

例如:

有若干学生的成绩(每人四门),要求输入序号后,能输出该生全部成绩。

main()

{floatscore[][4]={{60,70,80,90},{57,89,46,78},{43,90,87,67}};

float*search();

float*p;

inti,m;

printf(“enterthenumberofstudent:

”);

scanf(“%d”,&m);

printf(“ThescoresofNo.%dare:

\n”,m);

p=search(score,m);

for(i=0;i<4;i++)printf(“%5.2f\t”,*(p+i));

}

float*search(pointer,n)

float(*pointer)[4];

intn;

{float*pt;

pt=*(pointer+n);

return(pt);

}

运行情况:

enterthenumberofstudent:

1

ThescoresofNo.1are:

57.00,89.00,46.00,78.00

9.7指针数组和指向指针的指针

9.7.1指针数组

指针数组:

由相同类型的指针变量排列而成的有序集合(每个元素都是指针变量)。

说明格式:

类型说明符*指针数组名[元素个数]

如int*p[5]注意与int(*p)[5]不同

一般用于指向若干个字符串,使字符处理更方便。

例如:

#include“stdio.h”

main()

{char*s[4]={“dog”,“cat”,“pig”,“allanimal”};

inti;

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

printf(“%s\n”,*(s+i));

}

9.7.2指向指针的指针(二级指针)

·指向指针的指针:

指向指针数据的指针变量。

通常用于指向字符型指针变量。

·说明格式:

类型说明符**指针变量名

例如:

char**p;

其含义是定义指针变量p,用于存储另一个指针变量的地址。

例如:

mian()

{char*s[]={“China”,“Japan”,“English”,”Franch”};

char**p;

inti;

p=s+2;/*p=*(s+2)=s[2]存放的是English的首地址*/

printf(“%s\n”,p);/*打印p指针内的内容,即指针指向的字符串*/

}

9.7.3main()函数的命令行参数

通常,main函数首行为main(),其实可带参数,如:

main(argc,argv)

intargc;

char*argv[];

{………

}

main函数的实参是和命令一同给出的,即在一个命令行中包括命令名和需要传给main函数的参数

命令行的一般形式为:

命令名参数1参数2…...参数n

假设目标文件名为“F”,需向函数传递的参数为字符串“X”和“Y”,则命令行可写为:

FXY

命令行及命令行参数提供了C程序与操作系统间的接口

若有一个函数,其所在文件名为“F”:

main(argc,argv)

intargc;

char*argv[];

{while(argc>1)

{++argv;

printf(“%s\n”,*argv);

--argc;}

}

若输入的命令行参数为

FABCDEF

则执行结果为

ABC

DEF

9.8有关指针的数据类型和指针运算小节

(一)有关指针的数据类型

·inti;……….定义整型变量i;

·int*p;……..p为指向整型数据的指针变量;

·inta[n];……定义整型数组a,它有n个元素;

·int*p[n];…..定义指针数组p,它由n个指向整型数据指针元素组成;

·int(*p)[n];…定义指向含n个元素的一维数组的指针变量p;

·intf();……..f为带回整型函数值的函数;

·int*p();…p为带回一个指针的函数,该指针指向整型数据;

·int(*p)();….p为指向函数的指针,该函数返回一个整型值;

·int**p;…….p是一个指针变量,它指向一个指向整型数据的指针变量。

(二)指针运算小结

1.赋值=

语法:

指针变量=指针表达式

若有变量定义:

int*p1,*p2,a,array[10];

·p1=&a;………….变量的地址。

·p2=array;…………数组的首地址。

·p2=&array[i];…….数组第i个元素的地址。

·p1=p2;…………..一个指针变量值赋给另一个指针变量。

2.取地址运算&

语法:

&变量

设有变量说明inta,b,*p,*q;

p=&a;把a的地址赋给p,即让p指向a

q=p;让q也指向a,现在p、q都指向a

p=&b;让p也指向b,现在q指向a,p指向b

其中&a表示a的地址值

3.取内容运算*

语法:

*指针表达式

设p是一个指针表达式,则:

(1)若*p出现在赋值号左边,表示给p所指变量赋值

(2)若*p不出现在赋值号左边,表示p所指变量的值

若有变量说明:

inta,*p;则:

p=&a;让p指向变量a

*p=10;*p出现在赋值号左边,等价于a=10

printf(“%d”,*p);*p不出现在赋值号左边,打印p所指变量的值

scanf(“%d”,&a);给变量a输入值

scanf(“%d”,p);同上

*p+25等价于a+25

4.指针表达式与整数相加减

形式:

p+n或p-n

其中:

p是任意一个指针表达式,n是任何一种整型表达式

计算规则:

表达式p+n的值=p的值+p所指类型长度*n

表达式p-n的值=p的值-p所指类型长度*n

说明:

只有当p和p+n或p-n都指向连续存放的同类型数据区域,例如数组时,指针加减才有实际意义。

C语言规定:

表达式p+n和p-n的类型与p相同。

例如:

设有变量定义:

inta[10],*p,*q;则

p=ap指向a[0]

q=a+6q指向a[6]

p=q-4p指向a[2]

5.自增自减运算

语法:

p++;p--;++p;--p;

例如:

设有变量定义:

inta[]={1,2,3,4,5},*p,*q;

p=q=&a[3];

*p++=100;a[?

]变成100

*++q=100;a[?

]变成100

p++与++p的区别:

表达式p++的值等于p的原来值;

表达式++p的值等于p的新值;

6.关系运算

只有同类指针进行比较才有意义

·==和!

=运算符,比较的是两个指针表达式是否指向同一个内存单元;

·<、<=、>、>=,比较的是两个指针所指内存区域的先后次序

·语法:

指针表达式关系运算符指针表达式

若有变量定义:

inta[10];int*p=a,*q=a+3;

试判断以下表达式的值

p==&a[0]p==&a[1]p==qp+4=q+2p

q>a+2p>q

可用以下语句给数

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

当前位置:首页 > 解决方案 > 商业计划

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

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