首页 理论教育C语言指针变量定义与引用

C语言指针变量定义与引用

【摘要】:图5.3指针变量指针变量本身也是变量,所以指针变量在使用之前也需要定义。为指针变量赋值的方法有两种:一种是定义后,使用赋值语句的方式;另外一种是定义的同时进行初始化方式。

程序运行过程中,任何数据对象一旦被使用,就会对应计算机系统内存中的一个地址。由于系统内存储器是按字节编址的,一个数据对象有可能占用一至若干个字节的存储单元,程序设计语言中一般将数据对象所占用存储单元的首地址称为该对象地址。在计算机系统中,内存单元的地址是用有序整数进行编址的,所以存储系统的地址序号本质上就是无符号的整型数据。

C语言中,一些数据对象如函数、数组等的名字直接与其所占存储单元首地址对应,即它们的名字本身就直接表示地址;而一般意义下的变量名字则直接对应的是它们的内容(值),需要使用特定的表示方法才能表示出它们所对应的地址。C语言通过使用指针的概念来表示数据对象的首地址,在C语言中数据对象的地址和数据对象的指针是一个相同的概念,即指针就是地址。

1.指针变量的定义

C语言中,为了能够操作地址类数据,就有必要构造一种变量来存储它们,这种变量称为“指针变量”。当把一个变量的地址赋给一个指针变量后,称这个指针变量指向这个变量,如图5.3所示。

图5.3 指针变量

指针变量本身也是变量,所以指针变量在使用之前也需要定义。定义指针变量时,除了需要为其命名外,还必须指定能被指向数据对象的数据类型,定义指针变量的一般形式为:

数据类型名*指针变量名1,*指针变量名2,…;

其中,数据类型名是指针变量所指向目标数据对象的数据类型,可以是基本数据类型、也可以是以后要讨论到的构造数据类型;指针变量名由程序员命名,命名规则与普通变量相同;在指针变量名之前的星号(*)只是一个标志,表示其后紧跟的变量是一个指针变量而不是一个普通变量。

例如:int*p,*y; /* 定义了两个整型的指针变量p和y,

注意指针变量是p和y,而不是*p和*y*/

如果有需要,指针变量也可以和同类型的普通变量混合定义。

例如:char ch1,ch2,*p; /*定义了两个字符变量ch1、ch2以及一个指针变量p*/

2.指针变量的赋值

虽然地址量本质上是一个无符号整型常量,但C语言规定除了符号常量NULL外不能直接将任何其他无符号整型常量赋值给指针变量。为指针变量赋值的方法有两种:一种是定义后,使用赋值语句的方式;另外一种是定义的同时进行初始化方式。无论使用哪种方式为指针变量赋值,都必须通过取地址的操作获取被指向变量的地址值。取地址操作需要使用C语言中提供的取地址运算符“&”,取出一个变量所对应的地址值的形式如为:

&<变量名>

例如,有变量x,则&x表示变量x所对应存储单元的地址。指针变量在定义时进行初始化的一般形式为:

数据类型符*指针变量名=初始化地址值;

定义指针变量后,对指针变量赋值的一般形式为:

指针变量名=地址值;

无论对指针变量使用上面的哪一种赋值方式,当把一个数据对象(变量)的地址赋给一个指针变量后,都称这个指针变量指向该数据对象。例如:

int x,*y=&x;  /*定义了变量x和指针变量y,并将x的首地址赋值给y*/

或int x,*y;/*定义变量x和指针变量y*/

y=&x;/*将变量x的首地址赋值给指针变量y*/

两种形式都表示y指向x,若假设变量x的值为100,变量x对应的存储单元首地址为25000,则指针变量y和被它指向的变量x之间的关系如图5.4所示。

图5.4 指针变量y与变量x的存储关系图

另外,可以用C系统已经定义好的符号常量NULL(空)对任何数据类型的指针变量进行初始化或赋值,例如:

float*p=NULL; /*定义实型指针变量p并将其初始化为常量NULL*/

float*p;/*定义实型指针变量p*/

p=NULL;/*将符号常量NULL赋值给指针变量p*/

在C程序设计中使用指针变量时,还应该特别注意以下几点:(www.chuimin.cn)

①在指针变量的定义形式中,星号(*)只是一个标志,表示其后面的变量是指针变量。例如,在指针变量定义语句int x,*y;中,y是指针变量。

②一个指针变量只能指向与它同类型的普通变量,即只有数据类型相同时普通变量才能将自己存储单元的首地址赋值给指针变量,其原因是不同类型的变量所占存储单元的字节数是不同的,当指针变量从指向一个对象改变到指向另外一个对象时,会随它指向对象的数据类型不同而移动不同的距离。例如,下列用法是错误的:

int x;

float*ptr;

ptr=&x;/*错误,指针变量没有指向合适的数据对象*/

指针变量赋值存在一个特例,可以将任何数据类型对象的存储首地址赋值给void类型(空类型)的指针变量,例如:

int x;

void*p=&x;  /*将整型变量x的存储首地址赋值给空类型指针变量p*/

③指针变量只能在有确定的指向后才能正常使用,也就是说,指针变量中必须要有确定的地址值内容。没有确定指向的指针称为“空指针”或称为“悬空指针”,使用这种指针变量有可能引起不可预知的错误。

④指针变量中只能存放地址值,不能把除NULL外的整型常数直接赋给指针变量。例如,下面的指针变量的赋值是错误的:

int*ptr;

ptr=100;/*错误,整型常数值直接赋给指针变量*/

3.指针变量的引用

C程序中需要使用指针运算符(*)来表示对指针变量的引用。指针运算符(*)又称为间接运算符,它是一个单目运算符,只能作用于各种类型的指针变量上,其作用是表示被指针变量所指向的数据对象。指针运算符使用形式如下:

*<指针变量名>例如有语句序列为:

int x,*y;

y=&x;

此时&x等价于y,而*y则等价于变量x。例如:

scanf("%d",&x);等价于   scanf("%d",y);

printf("%d\n",x);等价于printf("%d\n",*y);上面y和x两个变量之间的关系实际上也是任何类型指针变量与它所指向对象之间的关系。设有同类型的指针变量和数据对象,将数据对象的首地址值赋给指针变量后,指针变量就与对应数据对象的首地址建立了等价关系;当对指针变量施以指针运算时,表示的就是被指针变量指向的数据对象。这是指针变量与被其指向的数据对象之间的本质关系,无论指针变量的组织形式如何变化,无论被指向的数据对象形式如何变化,这种本质上的关系永远不变。

【例5.4】 取地址运算符(&)和指针运算符(*)的使用示例。

/*Name:ex0504.c*/

#include<stdio.h>

上面程序中,由于y是指向变量x的指针变量,所以执行语句*y=300;等价于执行语句x=300;。标准输出函数printf调用语句中的格式%u指定用无符号整数的形式输出指针变量y的值;用%d的格式输出变量x的值和表达式*y的值,程序执行的结果为:

1703740:300,300(注意变量y的在不同的机器上可能是不同的)。