5.2.2 指针变量的定义及赋值

指针变量是专门用来存放变量地址的变量,是一种指针类型变量。指针变量可以指向任何类型的变量,包括指针变量本身。除此以外,指针变量还可以指向数组、函数等数据结构。下面就分别介绍指针变量的定义和赋值。

1.指针变量的定义

指针变量的定义与整型、字符型等一般变量的定义方法相似,指针变量定义的一般形式如下所示。


类型标识符指针名1,指针名2,……;


其中,“类型标识符”表示该指针变量的类型,同时也是该指针变量所指向的变量的类型。指针变量的声明示例如下。


int*ip;//ip是指向整型变量的整型指针变量

char*name;//name是指向字符变量的字符型指针变量

float*f1;//f1是指向浮点变量的浮点型指针变量


在定义指针变量时,指针名前的“”不能省略,例如上例中“name”前的“”不写,就变成定义字符型变量name了。但在表示该指针变量本身时,只用“”后的指针名表示即可,而不需要带“*”。例如,上例中ip、name、f1分别是整型指针、字符型指针、浮点型指针。

注意同一个指针变量只能指向同一类型的变量,例如,不能定义一个指针变量既指向整型变量又指向浮点型变量。

2.指针变量赋值

指针变量值是变量的地址。在C51语言中,变量的首地址是由编译系统自动分配,因此用户不知道变量在内存中的具体地址。为了获得变量的地址,C51语言中提供了地址运算符“&”,用其可以获取变量的首地址,一般形式如下。


&变量名


其中,“&”为取地址运算符,变量名为定义的变量。

例如,&a的值是变量a的首地址,&b的值是变量b的首地址。取地址运算符“&”是单目运算符,符合自右至左的结合性。

在C51语言中,指针变量的赋值有以下几种情况。

❑初始化赋值

初始化赋值即在定义指针变量时就进行初始化赋值。例如,定义整型指针变量ip,使指针ip指向整型变量i,即把整型变量i的地址赋值给指针变量ip,可以采用初始化赋值,示例如下。


int i;//定义整型变量i

int*ip=&i;//定义指针变量ip并初始化赋值指向变量i,其中&i表示取变量i的首地址


注意不允许把一个数初始化赋值给指针变量,例如,int*p=100的赋值语句是错误的。

❑取地址赋值

取地址赋值即将变量的地址直接赋值给指针变量。例如,定义指向整型指针变量p和整型变量x,使指针变量p指向变量x,即将整型变量x的地址赋值给p,可以采用取地址赋值,示例如下。


int x;//定义整型变量x

int*p;///定义指针变量p

p=&x;//利用取地址运算&x获得变量x的首地址,然后赋值给指针p


在对指针变量进行取地址赋值时,要注意被赋值的指针变量前没有加“”取值运算符,例如,p=&x一般来说是错误的表示方法。但是这种表示方法只有在指针变量初始化赋值时是正确的,如下所示。


int x,*p=&x;//正确的表示


本例中,定义了整型变量x和指针变量p,并用&x对指针变量p初始化赋值,而不是对*p赋值。

注意不允许把一个数取地址赋值给指针变量,例如,int*p;p=100的赋值语句是错误的。

❑指针变量间相互赋值

指针变量间相互赋值,即把一个指针变量的值直接赋给指向相同类型变量的另一个指针变量。在C51语言中,相同类型的指针变量之间可以进行互相赋值,示例如下。


int x=10,y=5;//定义整型变量并初始化

intp1=&x,p2=&y;//定义整型指针变量并初始化

p2=p1;//将x的地址赋给指针变量p2

p2=p1;//把p1指向的内容赋给p2所指的区域


本例中,由于指针变量p1、p2均指向整型变量,因此它们之间可以互相赋值。p2=p1与p2=p1看似相同,实际进行了不同的操作。其赋值操作时的指针指向如图5.3和图5.4所示。

由上图可以看出,p2=p1使得p2、p1同指向变量x。而p2=p1将p1所指向的变量x的内容10赋给了p2所指向的变量y,即相当于y=x,这样变量y的值由5变成了10。

❑数组型指针变量的赋值

数组型指针变量,即指向数组的指针变量。对数组型指针变量赋值,就是把数组的首地址赋予指向数组的指针变量,示例如下。


int str[10],*ip;//定义数组str及指针变量ip

ip=str;//赋值指向数组的指针变量,数组名即表示数组的首地址


5.2.2 指针变量的定义及赋值 - 图1

图 5.3 p2=p1的情况

5.2.2 指针变量的定义及赋值 - 图2

图 5.4 p2=p1的情况

要注意的是,上例中数组名str前并没有地址运算符“&”,因为数组名即可表示数组的首地址。除了以上表示方法外,还可写成如下形式。


ip=&str[0];//数组第一个元素的地址也是整个数组的首地址


数组在内存中是连续存放的,因此数组中第一个元素str[0]的地址,即为数组的首地址。若采取初始化赋值的方法为数组型指针变量赋值,示例如下。


int str[10],*ip=str;//定义数组及指针变量并进行初始化赋值


❑指向字符串的指针变量的赋值

字符型指针变量可以指向字符串,即把字符串的首地址赋值给指向字符串的字符型指针变量。示例如下。


char*ps;//定义字符型指针变量

ps=“This is a string”;//把字符串的首地址赋值给字符型指针变量


要注意的是,上例中字符串前并没有地址运算符“&”,因为该字符串可以视为直接使用字符串常量来定义的字符数组,由于字符串在数组中是顺序存放的,字符串名即为其首地址。若采用初始化赋值的方法,可以写成如下形式。


char*ps=“This is a string”;


该语句并不是把整个字符串的内容赋值给指针变量,而是把存放该字符串的字符数组的首地址赋值给指针变量。

❑指向函数的指针变量的赋值

指针变量除了指向整型、字符型、浮点型、数组结构等变量外,还可以指向函数。因为函数在内存中是连续存放的,对指向函数的指针变量赋值,就是把函数的入口首地址赋予指向函数的指针变量。示例如下。


int(*pf)();//定义整型指针变量

pf=fun;//fun为已定义的函数


上例中,定义了指向函数的整型指针变量pf,要注意其表示方法两对括号都不能省。fun()为已定义的函数,对指针变量pf赋值时,函数名fun前没有地址运算符“&”,因为函数名fun即可表示该函数的首地址。关于函数的内容将在后面的相关章节中作详细介绍。

这里需要强调的是,未经赋值的指针变量不能在程序中使用,否则将会发生由指针指向错误,而导致的整个程序的混乱。另外,只能将地址赋值给指针变量,不能赋予其他任何数据赋值给指针变量,否则将会发生无法预测的错误。