(十三)指针 -- 2 C语言的指针操作

2. C语言的指针操作

2.1 在C语言中声明指针变量

和C语言中其他变量一样,使用指针变量前必须先对它们进行声明。

为了声明一个指针变量,需要使用以下声明句法:

虽然指向整型的指针和指向字符型的指针在计算机内部都是以地址形式表示的,但两者在C语言中还是有区别的。

要使用该地址中的数据,编译程序必须知道如何解释地址里的数据,因此就要求显式地说明指针所指向的数据的类型。

  • 指针的基本类型(basetype) :指针指向的值的类型。

因此,指向整型的指针的基本类型为int。

若使用同一个声明语句来声明两个同类型的指针,必须给每个变量都加上星号标志,如:

int *p1, *p2;

而声明

int *p1, p2;

则表示声明p1为指向整型的指针,而p2是整型变量。



2. 基本的指针操作

C语言定义了两种操作指针值的运算符:
(1) & 取地址。
(2) * 取指向的值。

  • 间接引用(dereferencing):* 运算符取任意指针类型的值,返回其指向的左值,该操作称为对指针间接引用(dereferencing) 。

注:* 操作产生一个左值,说明可以赋一个值给一个间接引用的指针。


为了更好地说明,考虑以下声明:

int x,y;
int *p1, *p2;

这些声明为四个字分配了内存空间,两个字是int类型,另外两个字是指向整型的指针。

假设这些值在机器中存放的地址,如下图 a) 所示:


可以用赋值语句给x和y赋值,如:

x = -42;
y = 163;

产生如上图 b) 所示的内存状态。


为了初始化指针变量p1和p2,需要将那些表示整型对象的地址的值赋给它们。
即,用&把x和y的地址分别赋给p1和p2:

p1 = &x;
p2 = &y;

上述赋值操作将内存变成了上图 c) 所示的状态。


p1和p2中的指针值再一次具有了指向它们所引用的变量的直观效果,可以用箭头将该关系用上图 d) 表示。



从指针转向它所指向的值,可使用*运算符。
如,表达式

*p1

指出了p1指向的内存位置里所存放的值。


由于p1被声明为指向整数的指针,所以编译器知道表达式 *p1一定指一个整数。
因此,假设内存结构如上图所示,那么,*p1就是变量x的另外一个名字。
和简单变量x一样,表达式*p1是一个左值,而且可以给它赋新值。
如,执行赋值语句

*p1 = 17;

会改变变量x的值,因为p1指向变量x。


赋值后,内存结构如下图所示:

由此可见,p1的值本身没有因赋值而受到影响,
其值仍然为1000,所以仍然指向变量x。


同样可以给指针变量本身赋新值。如

p1 = p2;

令计算机取出变量p2的值并将该值复制给变量p1。
p2的值是指针值1004。由此,p1和p2就会同时指向变量y,如下图所示:



注意:区分指针赋值和值赋值是很重要的。形如

p1 = p2;

的指针赋值,使p1和p2指向同一位置。

而语句

*p1 = *p2;

的值赋值,是把以p2为地址的内存位置里的值复制到以p1为地址的内存位置里去。



3. 特殊指针NULL

C语言定义了一个特殊的常量NULL。常量NULL可以赋给任何指针变量, 在机器内部表示为地址值0。

NULL值的目的是表示指针不指向有效数据,所以想要找出和NULL指针有关的数据是没有意义的。

常见错误:
不要间接引用没有初始化或值为NULL的指针,这样会引用不属于本程序的内存空间,很可能使程序崩溃。



参考

《C语言的科学和艺术》 —— 13 指针

猜你喜欢

转载自blog.csdn.net/m0_38111466/article/details/108504574