文档库 最新最全的文档下载
当前位置:文档库 › C语言第八章 地址和指针

C语言第八章 地址和指针

C语言第八章 地址和指针
C语言第八章 地址和指针

第八章 地址和指针

第一节 变量的地址和指针

1、计算机的内存是以字节为单位的一片连续的存储空间,每一个字节都有一个编号,这个编号就成为内存地址。

2、程序中定义了一个变量,c 编译系统就会根据定义中变量的类型,为其分配一定字节数的内存空间: Short int 2 Int float 4 Double 8 char 1 指针 4

图8.1 变量在内存中所占字节的地址示意图 每个变量的地址就是指该变量所占存储单元的第一个字节的地址。

3、直接存取:程序中我们对变量进行存取操作,实际上也

a 2001

p

3001

a

b

x

1012 1013 1015 1016 1201 1202 1203 1204

就是对某个地址的存储单元进行操作。这种直接按变量的地址存取变量值的方式。

4、在c 语言中,还可以定义一种特殊的变量,这种变量只是用来存放内存地址的。

图8.2 存放地址的指针变量示意图

通过变量p 间接得到变量a 的地址,然后再存取变量a 的值的方式称为“间接存取”方式,通常变量p 指向了变量a ,变量a 是变量p 所指向的对象。

5、用来存放指针地址的变量就称作“指针变量”。

6、“变量p 指向变量a ”的含义就是指针变量p 中存放了变量a 的地址。

7、在某些场合,指针是使运算得以进行的唯一途径。 第二节 指针的定义赋值

一、 指针变量的定义和指针变量的基本类型 1、 定义指针变量的一般形式如下: 类型名 *指针变量名1,*指针变量名2…… 说明:1)类型名是基本类型。

2)*是说明符。(而在调用的时候,代表的是存储单元中的值)

3)指针变量名是用户标识符。

2002

2002

1012 1013

p

a

p

例:1)int *pi,*pj; pi pj只能存放整型变量的地址int I,*pi;double *pj;

2)p为一个指向指针的指针变量

int **p,*s,k=20;

s=&k;p=&s;

*p代表存储单元s,*s代表存储单元k,因此**p 也代表存储单元k

2、为什么指针变量要有“基类型”呢?

一个指针变量中存放的是一个存储单元的地址值,一个存储单元的中的“一”所代表的字节数是不同的:int float

二、给指针变量的赋值

1、通过求地址运算符(&)获得地址值

1)&用来求出运算对象地址,用求地址运算可以把

一个变量的地址赋给指针变量

2)把变量k的地址赋予q,这时可以说:q指向了变

量k。

3)求地址运算符只能应用于变量和数组元素,不可

用于表达式、常量或被说明为register的变量。

&必须放在运算对象左边,且运算对象类型必须与指针变量的基类型相同。

4)调用scanf函数时,若q=&k 则scanf(“%d”,

&k)和scanf(“%d”,q)是等价的。

2、通过指针变量获得地址值

可以通过赋值运算,把一个指针变量中的地址赋给另外一个指针变量,从而使这两个指针指向同一地址。

p=q

注意:赋值号两边的指针变量的基类型必须相同。

3、通过标准函数获得地址值

可以通过调用库函数malloc和calloc在内存中开辟动态存储单元,并把开辟的动态存储单元的地址赋给指针变量。

4、给指针变量赋“空”值

p=NULL;

NULL代码值为0,当执行了以上的赋值语句后,称p 为空指针。以上语句等价于:

p=’\0’p=0

企图通过一个空指针去访问一个存储单元时,将会出错。

三、对指针变量的操作

1、通过指针来引用一个存储单元

1)c语言中提供了一个称作“间接访问运算符”的单目运算符“*”。当指针变量中存放了一个确切的地址值时,就可以用*p来引用该地址的存储单元。

int *p,i=10,j;

p=&i

j=*&i

j=*p+1 指针变量p所指存储单元中的内容加1后赋予j 2)int *p,k=0;

p=&k;

*p=100 把100存放在变量k中

*p=*p+1 p所指存储单元中的值加1后,再放入p所指存储单元中,即:k变为101

*p出现在赋值号左边时,代表的是指针所指的存储单元;当*p出现在赋值号右边时,代表的是指针所指的存储单元的内容。

*p+=1 ++*p (*p)++括号不能少

2、移动指针

a[0] a[1] a[2] a[3] a[4]

p q

q=p+2; /*使指针q指向存储单元a【2】*/

q++; /*q向高地址移动指针,指向a【3】*/

q++; /*q向高地址移动指针,指向a【4】*/

q--; /*q向低地址移动指针,指向a【3】*/

p++; /*p向高地址移动指针,指向a【1】*/

q-p=2

1)所谓移动指针就是对指针变量加上或减去一个整数,或

通过赋值运算,使指针变量指向相邻的存储单元。因此只有当指针指向一串连续的存储单元时,指针的移动才有意义。2)当指针指向一串连续的存储单元时,可以对指针变量进行加上或减去一个整数的运算,也可以对指向同一串连续存储单元的两个指针进行相减运算。

3)在对指针进行加、减运算中,数字1不代表整数1,而是指一个存储单元长度,至于一个长度占多少个字节的存储空间,则视指针的基类型而定。

4)当移动指针时,基类型为int的指针只能用来指向int变量,不能用以指向其他类型的变量。

3、指针的比较

在关系表达式中可以对两个指针进行比较。

通常两个或多个指针指向同一目标(如同一串连续的存储单元)时比较才有意义。

四、函数之间地址值的传递

1、形参为指针变量时实参和形参之间的数据传递

若函数的形参为指针类型,调用该函数时,对应的实参必须是基类型相同的地址值或者是已指向某个存储单元的指针变量。

例:编写函数myadd(int *a,int *b),函数中把指针a和b 所指存储单元中的两个值相加,然后将和值作为函数值返回。

程序如下:

#include

myadd(int *a, int *b)

{ int sum;

sum=*a+*b;

return sum;

}

main()

{ int x,y,z;

printf("input x,y:\n");

scanf("%d%d",&x,&y);

z=myadd(&x,&y);

printf("%d+%d=%d\n",x,y,z);

}

2、通过传送地址值在被调用函数中直接改变调用函数中

的变量的值

例:调用swap函数,交换主函数中变量x和y中的数据。#include

void swap(int *a, int *b)

{

int t;

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

t=*a;*a=*b;*b=t;

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

}

main()

{

int x=30,y=20;

printf("1) x=%d,y=%d\n",x,y);

swap(&x,&y);

printf("4) x=%d,y=%d\n",x,y);

}

在c程序中可以通过传送地址的方式在被调用函数中直接改变调用函数中的变量的值,从而达到函数之间的数据传递。

3、函数返回地址值

函数值的类型不仅可以是简单的数据类型,而且可以是指针类型。

例:编写程序,把主函数中变量i和j中存放较大数的那个地址作为函数值传回。

#include

int *fun(int *,int *);

main()

{

int *p,i,j;

printf("input two number:\n");

scanf("%d%d",&i,&j);

p=fun(&i,&j);

printf("i=%d,j=%d,*p=%d\n",i,j,*p); }

int *fun(int *a,int *b)

{

if(*a>*b) return a;

return b;

}

相关文档