C语言指针操作(十一)有关指针的小结

指针操作系列文章:

C语言指针操作(一)地址,指针,指针变量是什么

C语言指针操作(二)指针变量作为函数参数

C语言指针操作(三)通过指针引用数组

C语言指针操作(四)用数组名作函数参数

C语言指针操作(五)通过指针引用多维数组

C语言指针操作(六)通过指针引用字符串

C语言指针操作(七)指向函数的指针

C语言指针操作(八)返回指针值的函数

C语言指针操作(九)指针数组和多重指针

C语言指针操作(十)动态内存分配与指向它的指针变量

C语言指针操作(十一)有关指针的小结


由于指针的内容较多,指针的概念和应用比较复杂,不易掌握,本节对有关指针的知识和应用作简单的归纳小结。

目录

(1)首先要准确理解指针的含义。

(2)在 C 语言中,所有的数据都是有类型的。

(3)要区别指针和指针变量。

(4)什么叫 “ 指向 ” ?地址就意味着指向,因为通过地址能找到具有该地址的对象。

(5)要深入掌握在对数组的操作中正确地使用指针.搞清楚指针的指向。

(6)有关指针变量的归纳比较。

(7)指针运算。

(8)指针变量可以有空值,即该指针变量不指向任何变量。


(1)首先要准确理解指针的含义。

“ 指针 ”是 C 语言中一个形象化的名词,形象地表示 “指向” 的关系,其在物理上的实现是通过地址来完成的。正如高级语言中的 “变量”,在物理上是 “命名的存储单元”。Windows 中的 “文件夹” 实际上是 “目录”。离开地址就不可能弄清楚什么是指针。明确了 “指针就是地址”,就比较容易理解了,许多问题也迎办而解了。例如:

①&a是变量 a 的地址,也可称为变量 a 的指针。

②指针变量是存放地址的变量,也可以说,指针变量是存放指针的变量。

③指针变量的值是一个地址,也可以说,指针变量的值是一个指针。

④指针变量也可称为地址变量,它的值是地址。

⑤是取地址运算符,&a 是 a 的地址,也可以说,&是取指针运算符。&a 是变量 a 的指针(即指向变量 a 的指针)。

⑥数组名是一个地址,是数组首元素的地址,也可以说,数组名是一个指针,是数组首元素的指针。

⑦函数名是一个指针(指向函数代码区的首字节),也可以说函数名是一个地址(函数代码区首字节的地址)。

⑧函数的实参如果是数组名,传递给形参的是一个地址,也可以说,传递给形参的是一个指针。

(2)在 C 语言中,所有的数据都是有类型的。

例如常量 123 并不是数学中的常数123,数学中的 123 是没有类型的,123 和 123.0 是一样的,而在C语言中,所有数据都要存储在内存的存储单元中,若写成 123,则认为是整数,按整型的存储形式存放,如果写成 123.0,则认为是单精度实数,按单精度实型的存储形式存放。可以说,C语言中的数据都是 “ 有类型的数据 ”,或称 “ 带类型的数据 ” 。

对地址而言,也是同样的,它也有类型,首先,它不是一个数值型数据,不是按整型或浮点型方式存储,它是按指针型数据的存储方式存储的 ( 虽然在 VisualC++ 中也为指针变量分配 4 个字节,但不同于整型数据的存储形式)。指针型存储单元是专门用来存放地址的,指针型数据的存储形式就是地址的存储形式。

其次,它不是一个简单的纯地址,还有一个指向的问题,也就是说它指向的是哪种类型的数据。如果没有这个信息,是无法通过地址存取存储单元中的数据的。所以,一个地址型的数据实际上包含3个信息:

①表示内存编号的纯地址。

②它本身的类型,即指针类型。

③以它为标识的存储单元中存放的是什么类型的数据,即基类型。

例如:已知变量为 a为 int 型,&a 为 a 的地址,它就包括以上 3 个信息,它代表的是一个整型数据的地址,int 是 &a 的基类型(即它指向的是 int 型的存储单元)。可以把 ② 和 ③ 两项合成一项,如 “ 指向整型数据的指针类型 ” 或 “ 基类型为整型的指针类型 ”,其类型可以表示为 “ int* ”型。这样,对地址数据来说,也可以说包含两个要素:内存编号(纯地址)和类型(指针类型和基类型)。这样的地址是 “ 带类型的地址 ” 而不是纯地址。

(3)要区别指针和指针变量。

指针就是地址,而指针变量是用来存放地址的变量。有人认为指针是类型名,指针的值是地址。这是不对的。类型是没有值的,只有变量才有值,正确的说法是指针变量的值是一个地址。不要杜撰出“地址的值”这样莫须有的名词。地址本身就是一个值。

(4)什么叫 “ 指向 ” ?地址就意味着指向,因为通过地址能找到具有该地址的对象。

对于指针变量来说,把谁的地址存放在指针变量中,就说此指针变量指向谁。但应注意:并不是任何类型数据的地址都可以存放在同一个指针变量中的,只有与指针变量的基类型相同的数据的地址才能存放在相应的指针变量中。例如:

既然许多数据对象(如变量,数组、字符串和函数等 ) 都在内存中被分配存储空间,就有了地址,也就有了指针。可以定义一些指针变量,分别存放这些数据对象的地址,即指向这些对象。

void* 指针是一种特殊的指针,不指向任何类型的数据。如果需要用此地址指向某类型的数据,应先对地址进行类型转换。可以在程序中进行显式的类型转换,也可以由编译系统自动进行隐式转换。

(5)要深入掌握在对数组的操作中正确地使用指针.搞清楚指针的指向。

一维数组名代表数组首元素的地址,如:p 是指向 int 型类型的指针变量,显然,p 只能指向数组中的元素( int 型变量),而不是指向整个数组。在进行赋值时一定要先确定赋值号两侧的类型是否相同,是否允许赋值。

对 “ p = a ; ”,准确地说应该是:p 指向 a 数组的首元素,在不引起误解的情况下,有时也简称为:p 指向 a 数组,但读者对此应有准确的理解。同理,p指向字符串,也应理解为 p 指向字符串中的首字符。

(6)有关指针变量的归纳比较。

变量定义类型表示含   义
int i;int定义整型变量i
int* p;int*定义p为指向整型数据的指针变量
int a[5];int [5]定义整型数组a,它有5个元素
int* p[4];int* [4]定义整型数组p,它由4个指向整型数据的指针元素组成
int (*p)[4];int (*)[4]p为指向包含4个元素的一维数组的指针变量
int f();int ()f为返回整型函数值的函数
int* p();int* ()p为返回一个指针的函数,该指针指向整型数据
int (*p)();int (*)()p为指向函数的指针,该函数返回一个整型值
int** p;int**p是一个指针变量,它指向一个指向整型数据的指针变量
void* p;void*p是一个指针变量,基类型为void(空类型),不指向具体的对象

(7)指针运算。

①指针变量加(减)一个整数。

例如:p++,p--,p+i,p-i,p+=i,p-=i 等均是指针变量加(减)一个整数。

将该指针变量的原值(是一个地址)和它指向的变量所占用的存储单元的字节数相加(减)。

②指针变量赋值。

将一个变量地址赋给一个指针变量。例如:

p = &a;			//将变量a的地址赋给p
p = array;		//将数组array首元素地址赋给p
p = &array[i];	//将数组array 第i个元素的地址赋给p
p = max;		//max为已定义的函数﹐将max的入口地址赋给p
pl = p2;		//pl 和 p2是基类型相同指针变量, 将 p2 的值赋给 pl

③两个指针变量可以相减。

如果两个指针变量都指向同一个数组中的元素,则两个指针变量值之差是两个指针之间的元素个数。

④两个指针变量比较。

若两个指针指向同一个数组的元素,则可以进行比较。指向前面的元素的指针变量 “ 小于 ” 指向后面元素的指针变量。如果 p1 和 p2 不指向同一数组则比较无意义。

(8)指针变量可以有空值,即该指针变量不指向任何变量。

可以这样表示:

p = NULL;

其中,NULL是一个符号常量,代表整数 0。在stdio.h头文件中对NULL进行了定义:

#define NULL 0

它使 p 指向地址为0的单元。系统保证使该单元不作它用(不存放有效数据)。

应注意,p的值为 NULL 与未对 p 赋值是两个不同的概念。前者是有值的(值为 0 ),不指向任何变量,后者虽未对 p 赋值但并不等于 p 无值,只是它的值是一个无法预料的值,也就是 p 可能指向一个事先未指定的单元。这种情况是很危险的。因此,在引用指针变量之前应对它赋值。

任何指针变量或地址都可以与 NULL 作相等或不相等的比较,例如:

if( p == NULL)

本章介绍了指针的基本概念和初步应用。指针是C语言中很重要的概念,是C的一个重要特色。使用指针的优点:

①提高程序效率;

②在调用函数时当指针指向的变量的值改变时,这些值能够为主调函数使用,即可以从函数调用得到多个可改变的值;

③可以实现动态存储分配。

同时应该看到,指针使用实在太灵活,对熟练的程序人员来说,可以利用它编写出颇有特色,质量优良的程序,实现许多用其他高级语言难以实现的功能,但也十分容易出错,而且这种错误往往比较隐蔽。指针运用的错误可能会使整个程序遭受破坏,比如由于未对指针变量 p 赋值就向 *p赋值,就可能破坏了有用的单元的内容。如果使用指针不当,会出现隐蔽的、难以发现和排除的故障。因此,使用指针要十分小心谨慎,要多上机调试程序,以弄清一些细节,并积累经验。

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

juechen333

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值