2第二讲 指针文档格式.docx

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

2第二讲 指针文档格式.docx

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

2第二讲 指针文档格式.docx

func(inta[],intn);

等同于func(int*a,intn);

◆函数声明的几种变通形式。

◆所以指针a在函数中值可以改变,如*a++,不同于函数内定义的数组如:

intb[5];

这里b是指针常量。

8.指针与字符串:

char*p,s[50]=“fdjfjdfj”;

p=s;

◆可用p间接访问字符串,如指针法:

for(;

*p!

=‘\0’;

p++)

或下标法:

for(i=0;

p[i]!

i++)

9.指针形参在函数间传递字符串:

voidcopy(char*s1,char*s2){while(*s1++=*s2++);

}

◆调用时用字符数组名或指向某字符串的指针做实参,

char*p=“sdgygkh”;

charss[50];

func(ss,p);

◆函数调用的灵活形式:

func(ss+2,p)或func(ss,p+2)

◆注意:

输入字符串常用gets函数,但参数应是字符数组名,或已指向某字符数组的指针,如:

chars[50],*p;

gets(s);

是正确的,而gets(p)是错误的,因为p没被赋地址值,无任何指向。

改正:

p=s;

gets(p);

10.数组指针与多维数组:

inta[3][4];

int(*p)[4];

p=a;

◆p指向a的一整行,此时*p就代表a[0];

如果执行p++,则p指向下一行,即*p代表a[1],p跳过单元数为2*4=8个字节。

◆引用元素的两种形式:

p[i][j]或(*p)[j]

◆几个等价关系式:

由x[i]等价于*(x+i)和&

x[i]等价于x+i得出:

a[i][j]等价(*(a+i))[j]等价*(a[i]+j)等价*(*(a+i)+j)

a[i][j]等价*(a+i)+j等价a[i]+j

◆指针形参在函数间传递多维数组:

intfunc(int(*b)[4],intn);

等价于intfunc(intb[][4],intn);

◆调用时用二维数组名做实参,如:

func(a,3);

11.指针数组:

char*s[3];

表示数组s有3个元素,每一个元素都是一个指针变量,都可以指向一个字符串。

◆赋初值:

char*s[3]={“sdgg”,”ww”,”q”};

或单独赋值:

s[0]=“sdgg”;

s[1]=“ww”;

s[2]=“q”;

◆用于指向多个字符串。

◆也可用字符数组存储多个字符串,只是占用内存空间大。

11.指向指针的指针:

二级指针,char**p;

◆用于访问指针数组,或在函数间传递指针数组,通常就是传递多个字符串。

12.char*s[3]={“sdgg”,”ww”,”q”};

char**p;

◆p指向数组s的首地址,此时*p代表s[0],即指向第0个字符串,*p和s[0]都是第0个字符串的首地址,

◆可用gets(*p)或gets(p[i])来输入字符串,用puts(*p)或puts(p[i])来输出字符串。

◆在函数间传递多个字符串的参数形式:

func(char**s,intn)或func(char*s[],intn)或func(chars[][],intn)

◆总结:

1、通常在主调函数中定义指针数组指向多个字符串。

2、函数:

func(char**s,intn)或func(char*s[],intn)传递多个字符串首地址;

3、在函数内的使用形式:

s[i]或*(s+i),都代表第i个串首地址,或*s++;

4、一般都是整串操作,循环一般使用字符串个数进行控制,如:

i<

n;

i++){s[i]……}

◆字符串操作函数:

strlen()、strcpy()、strcmp()

13.返回指针值的函数:

char*func(char*s,charch)

◆切记:

返回的是地址,在主调函数中应使用指针类型变量接收函数返回值,

char*p,a[]=“asdgg”;

p=func(a,’d’);

14.动态内存分配:

掌握malloc函数的使用方法。

知识点详解及习题

一、

指针概念

1、指针

⏹指针:

一个变量的地址。

⏹指针变量:

是一个变量,存放另一个变量的地址。

⏹任何变量都在计算机内存中占有一块内存区域,变量的值就存放在这块内存区域之中

⏹一个变量的访问(访问是指取出其值或向它赋值)

(1)直接访问,通过变量名访问,如通过变量名i直接访问。

(2)间接访问,通过该的变量指针来访问,如通过i_pointer访问变量i。

2、指针变量

●指针变量定义的一般形式:

类型标识符*标识符

如:

int*pointer_1,*pointer_2;

(1)该指针变量指向的变量的类型。

如i_pointer指向的变量i是整型。

(2)该指针变量指向哪一个变量,即该指针变量的值是多少。

如i_pointer的值是2000。

例1

inti,j;

/*定义两个整型变量*/

int*pointer_1,*pointer_2;

float*pointer_3;

char*pointer_4;

void*pointer_5;

指针变量的赋值:

pointer_1=&

i;

pointer_2=&

j;

pointer_3=&

(?

⏹为什么在定义指针时要指定基类型?

⏹注意,指针变量中只能存放地址,不能将一个非地址类型的数据(如常数等)赋给一个指针变量,如:

pointer_1=100;

⏹也可以在定义指针变量的同时指定其初值,

inta;

int*p=&

a;

3指针变量的引用

有两个运算符可以引用指针变量:

(1)&

取地址运算符。

如pointer_1=&

(2)*:

指针运算符。

用于访问指针变量所指向的变量。

(取其指向的内容)

例;

i=3;

直接访问

ptr=&

*ptr=3;

间接访问

(3)*和&

是互逆运算如*&

i,i,*ptr三者表示内容相同,都是3

说明:

●指针变量必须定义且赋值后,才能用*运算符访问所指向的变量。

int*p;

(未规定指向哪个变量)

*p=100;

这种错误称为访问悬挂指针(suspededpointer)。

正确的引用:

p=&

(规定指向a)

●区分:

*运算符在不同场合的作用,编译器能够根据上下文环境判别*的作用。

inta,b,c;

int*p;

(*表示定义指针)

(*表示指针运算符)

c=a*b;

(*表示乘法运算符)

例2输入a和b两个整数,按先大后小的顺序输出a和b。

#include<

stdio.h>

main()

{

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

scanf("

%d,%d"

&

a,&

b);

p1=&

p2=&

b;

if(a<

b)

{p=p1;

p1=p2;

p2=p;

}/*p1指向较大值,p2指向较小值.(交换的是ab地址)*/

printf("

a=%d,b=%d\n"

a,b);

max=%d,min=%d\n"

*p1,*p2);

4指针变量作为函数的参数

作用:

将一个变量的地址传递到另一个函数中(常用方法)

例3题目要求输入a和b两个整数,按先大后小的顺序输出a和b。

voidswap(int*p1,int*p2)

{intp;

 

p=*p1;

/*是否可以定义int*p;

*p=*p1;

为什么?

*/

*p1=*p2;

*p2=p;

{inta,b;

scanf("

pointer_2=&

if(a<

b)

swap(pointer_1,pointer_2);

/*另一种调用swap()的形式是:

b)swap(&

*/

printf("

\n%d,%d\n"

例4输入a、b、c三个整数,按大小顺序输出。

intswap(int*pt1,int*pt2)

p=*pt1;

*pt1=*pt2;

*pt2=p;

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

{if(*q1<

*q2)swap(q1,q2);

if(*q1<

*q3)swap(q1,q3);

if(*q2<

*q3)swap(q2,q3);

{inta,b,c,*p1,*p2,*p3;

%d,%d,%d"

&

a,&

b,&

c);

p1=&

p3=&

c;

exchange(p1,p2,p3);

\n%d,%d,%d\n"

a,b,c);

5数组的指针和指向数组的指针变量

指针可以指向数组和数组元素,当一个指针指向数组后,对数组元素的访问,既可以使用数组下标,也可以使用指针。

并且,用指针访问数组元素,程序的效率更高。

●指向数组元素的指针变量

指向数组元素的指针变量,其类型应与数组元素相同。

inta[10];

/*元素为整型*/

floatb[10];

/*元素为实型*/

/*可以指向数组a的元素*/

float*pf;

/*可以指向数组b的元素*/

为了让指针p指向数组a,应把数组a的地址赋给指针变量p。

或p=&

a[0];

或int*p=a;

●通过指针引用数组元素

当使指针p指向数组a后,可以用指针p访问数组的各个元素。

如果指针p指向数组a(指向数组的第一个元素a[0]),则:

p+1指向下一个元素a[1],注意不是将p值简单加1。

(前面提到的为什么定义指针时需要指定类型)

•如果数组元素是整型,p+1表示p的地址加2;

•如果数组元素是实型,p+1表示p的地址加4;

•如果数组元素是字符型,p+1表示p的地址加1。

p+i指向元素a[i]。

可以使用*(p+i)访问元素a[i]。

另外:

1、p+i也可以记作a+i,指向元素a[i]。

2、指向数组的指针变量也可以带下标,如,p[i]与*(p+i)等价,表示元素a[i]。

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

p=a;

*(p+3)+=2;

printf(“%d,%d\n”,*p,*(p+3));

A0,5B1,5

C0,6D1,6

例5输出数组的全部元素。

(设10个元素,整型)。

●下标法(常用,很直观)

{inta[10];

inti;

for(i=0;

10;

i++) 

 

%d"

a[i]);

\n"

);

for(i=0;

i++) 

%d"

a[i]);

●用数组名计算数组元素的地址。

(效率与下标法相同,不常用,why?

{inta[10];

inti;

*(a+i));

●用指针访问各元素。

(常用,效率高)main()

int*p,i;

scanf(“%d”,&

printf(“\n”);

for(p=a;

p<

(a+10);

p++) 

/*a++?

?

*/

*p);

⏹若指针p指向数组a,虽然p+i与a+i、*(p+i)与*(a+i)意义相同,但仍应注意p与a的区别,a是地址常量,而p是指针变量。

例、

a<

(p+10);

a++)

a代表数组的首地址,是不变的,a++不合法

⏹指针变量可以指向数组中的任何元素,注意指针变量的当前值。

例5输出数组a的10个元素。

(检查代码,判断输出?

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

p=a;

p++);

i++,p++) 

正确代码

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

i++,p++) 

⏹使用指针时,应特别注意避免指针访问越界。

在上例中,第二次for循环,p已经越过数组的范围,但编译器不能发现该问题。

⏹指针使用的几个细节。

设指针p指向数组a(p=a),则:

①p++(或p+=1),p指向下一个元素。

②*p++,相当于*(p++)。

因为,*和++同优先级,++是右结合运算符。

③*(p++)与*(++p)的作用不同。

*(p++):

先取*p,再使p加1。

*(++p):

先使p加1,再取*p。

④(*p)++表示,p指向的元素值加1。

⑤如果p当前指向数组a的第i个元素,则:

*(p--)相当于a[i--],先取*p,再使p减1。

*(++p)相当于a[++i],先使p加1,再取*p。

*(--p)相当于a[--i],先使p减1,再取*p。

6数组名作函数参数

数组名代表数组首地址,因此,它作实参在函数调用时,是把数组首地址传送给形参。

这样,实参数组和形参数组共占同一段内存区域。

从而在函数调用后,实参数组的元素值可能会发生变化。

例7将数组a中n个元素按相反顺序存放。

算法:

a[0]与a[n-1]交换,a[1]与a[n-2]交换,.....,a[(n-1)/2]与a[n-int((n-1)/2)]交换。

实现:

用i,j作元素位置变量,开始i=0,j=n-1。

将a[i]与a[j]交换,然后i加1,j减1,直到i=(n-1)/2。

voidinv(intx[],intn)

{intt,i,j,m=(n-1)/2;

i<

=m;

i++) 

{j=n-1-i;

t=x[i];

x[i]=x[j];

x[j]=t;

return;

{staticinti,a[10]={3,7,9,11,0,6,7,5,4,2};

theoriginalarray:

a[i]);

inv(a,10);

thearrayhansbeeninverted:

i++)

函数inv()可以用指针作形参,运行情况与用数组作形参相同。

voidinv(int*x,intn)

{int*p,t,*i,*j,m=(n-1)/2;

i=x;

j=x+n-1;

p=x+m;

for(;

=p;

i++,j--)

{t=*i;

*i=*j;

*j=t;

}

return;

例8从10个数中找出其中最大值和最小值。

只找出其中最大值和最小值,不能改变元素的排列顺序)。

方法1、实参和形参均用数组变量。

方法2、形参和实参均使用指针变量。

小结:

数组作函数的参数,实参和形参之间传送数组的首地址,首地址可以用指针表示,也可以用数组名表示,因此,实参和形参有以下四种组合情况。

若有以下调用语句,则不正确的fun函数的首部是

A)voidfun(intm,intx[])

B)voidfun(ints,inth[41])

C)voidfun(intp,int*s)

D)voidfun(intn,inta)

main()

{…

inta[50],n;

fun(n,&

a[9]);

7多维数组的指针

●二维数组staticinta[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};

理解为:

有三个元素a[0]、a[1]、a[2],每一个元素代表一行,每一个元素是一个包含4个元素的数组

⏹数组名a代表:

整个二维数组的首地址,也是元素a[0][0]的地址,同时代表第一行元素的首地址。

⏹a+1表示第二行元素的首地址,也是元素a[1][0]的地址。

⏹a+2表示第三行元素的首地址,也是元素a[2][0]的地址。

设数组的首地址是2000,则有a等于2000。

第一行4个元素,占8字节,因此第二行的首地址是2008,即a+1等于2008。

第二行4个元素,占8字节,因此第三行的首地址是2016,即a+2等于2016。

由于把a[0]、a[1]、a[2]看成一维数组(一维数组名),它们代表各自数组的首地址,即:

a[0]~&

a[0][0]等价于*(a+0),

a[1]~&

a[1][0]等价于*(a+1)

a[2]~&

a[2][0]等价于*(a+2)

根据一维数组的表示方法,有

a[0]+1:

~&

a[0][1]一维数组中第二个元素的地址

a[0]+2:

~&

a[0][2]

a[1]+1:

a[1][1];

等价于*(a+1)

综上所述,二维数组a的地址用下图说明

已知某元素的指针后,可以用*运算符访问该元素。

例9

*(a[1]+2)=a[1][2]=13

二维数组元素a[i][j]的值可用以下方式表示:

*(a[i]+j),*(*(a+i)+j),a[i][j]

二维数组元素a[i][j]的地址可用以下方式表示:

a[i]+j,*(a+i)+j,&

a[i][j]

P243:

表10-2数组a的性质

练习:

若有以下定义和语句:

ints[4][5],(*ps)[5];

(一维数组的指针,数组有5个元素,区别指针数组,*ps[5],存放5个指针)

ps=s;

则对s数组元素的正确引用形式是()

A)ps+1

B)*(ps+3)

C)ps[0][2]

D)*(ps+1)+3

●指向多维数组的指针变量

(1)指向数组元素的指针变量(用列指针对二维数组进行操作)。

例10用指针变量输出数组元素的值。

main()

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

for(p=a[0];

p<

a[0]+12;

p++) 

if((p-a[0])%4==0)printf("

%4d"

*p);

注意:

本例用指针顺序访问二维数组的元素。

若需访问二维数组a[n][m](n行m列)的某个元素a[i][j],计算该元素的相对位置公式为:

i*m+j(i,j=0,1,2,...)

这种方法相当于把二维数组转化为一维数组来使用。

(2)指向m个元素组成的一维数组的指针变量(用行指针对二维数组进行操作)

int(*p)[4];

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

{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);

(*p)[4]表示p为单独一个指针变量,行指针,指向含有4个元素的一维数组,即*p有4个元素,每个元素为整型。

*p[4]为指针数组,*p数组有4个元素,每个元素中存放的是地址,即每个元素都为指针变量。

●多维数组的指针作函数参数,两种情况:

(1)用指向变量的指针变量

(2)用指向一维数组的指针变量

8字符串的指针

●字符串的表现形式

C语言中,有两种方式可以实现字符串:

字符数组

字符指针

(1)字符数组

{staticcharstring[]="

IloveChina!

"

;

 printf("

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

当前位置:首页 > 总结汇报 > 学习总结

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

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