资料介绍
C语言的精髓——指针详解
朱有鹏
1.2、指针变量的类型作用
对于普通变量的来说,其类型的作用主要有这么几个方面:
(1)程序员写代码时识别用:不涉及强制转换时,知道该变量中应该存放什么类型的数值。
(2)空间大小的说明:比如int为4个字节空间
(3)存储结构说明:float和int虽然空间大小都是4字节,但是其存储结构完全不同
对于指针变量来说,其类型的作用与上面基本一致,只是其类型是由普通类型+*构成,*个数表明了指针变量的级数,指针变量用来存放地址。当不涉及强制转换时,其对应关系为:
某类型一级指针变量 = 该类型一级地址
某类型二级指针变量 = &(该类型一级指针变量)
n+1级指针变量 = &(n级指针变量)
所有普通变量的地址都是一级地址,所有一级指针变量的地址都是二级地址,类推n级指针变量的地址就是n+1级地址,但是我们这里必须强调一下,使用指针的目的就是为了更加方便的访问空间,但是如果级数超过3级以上,实际上不但降低了程序的可读性,也会降低对空间的访问速度,所以过高级数的指针变量没有太大的意义。
Int *p = &a;
p中只存放了a首字节地址,但是int说明了*p希望访问的空间有4个字节,所以从p所指a的第一个字节向后数3个字节空间,一共4个字节空间才是*p的实际希望访问到的完整空间。
1.3、为什么需要指针
不管多么高大上的程序,最终都是运行在硬件上的,所有对于硬件的设置和访问,全部都是通过对内存操作实现的,广义上的内存可以包括,寄存器、缓存、常说的内存等,这些内存空间都是由一个个的字节构成的,每个字节都有地址,对于这些空间的访问,大多都是通过地址实现的。
如果就站在c自身的角度,也可以看到指针的好处,举个例子的话,比如fun1函数有一个自动局部变量a,他的作用域被局限在了fun1函数内部,fun2函数是无法访问的,如果fun2想要访问fun1中a的话,我们可以将a的地址传递给fun2函数,当然前提是fun1的a没有被自动释放。
对于c语言有了解的都知道,函数也是有作用域的,跨文件的作用域又称为链接域,为了防止本文件的函数(比如名叫fun的函数)不被其它文件的同名函数干扰,同时也希望不去干扰别人,我们往往会在fun函数的前面加一个static标志,将其作用域固定为本文件,其它文件通过fun函数名是无法访问的。但是如果其它文件的function函数,又确实希望访问这个函数时,怎么办呢?我们只需要将fun函数的地址传递给function函数,就可以跨文件访问fun函数,并且不会受到static的影响。
所以在c语言中,地址还是扩大变量或者函数作用范围的有效手段,当然指针好处很多,这里不再赘述。
C++就不说了,里面保留了指针的使用,初学java,c#等高级语言的同学,都会因为里面没有指针而困惑,甚至在想,难道这些高级语言就不需要访问内存空间了吗?凡是有过java异常处理的同学,都会发现java中有一种空指针异常,大多是因为我们使用了没有实例化的对象名导致的,因为没有实例化就没有分配内存空间。
既然有空指针异常,就证明java是使用了指针的,只是全部都由类的底层封装好了,不需要我们关心,目的就是为了省去指针这一难点,使得java简单实用,但是由于不能直接操作指针,面对频繁使用指针的底层开发而言,java和c#多少会显得有心无力。
1.5、指针使用值三部曲
(1)定义(声明)
例: int *p=NULL; //初始化一下,防止野指针
(2)关联
例: int a= 10;
p = &a;//a空间的首地址给了p,所以p里面的地址常量指向了a空间,因此简称p-》a空间
(3)引用
(a)读空间:读值操作,前提是里面存有数据才行
例:int b = *p;//等价于 b = a;
(b)写空间:向空间写入新的值
例: int *p = 30;//等价于a = 30;
2、指针涉及到的一些符号的理解
2.1、*的理解
在c语言中,*的用途有两个,一个是用于表示乘号,第二个与指针有关,虽然这两种用途用都会用到*,但这两者没有任何关系。*在指针中的用途主要有两个方面,第一种是用在指针定义的时候,与前面的类型结合,用于表示被定义指针变量的类型,*个数表明了定义的指针变量的级数,例如:
int *p;int* p;
*靠前靠后都没关系,这时的*与p是两个不同的东西,星号表明p是一个一级指针变量,用于存放一个一级地址。但是需要注意下面的情况:
int *p1,*p2;//p1和p2都是int型的一级指针变量。
int *p1,p2;//p1是int型的一级指针变量,p2只是一个普通的int型变量。
第二种就是解引用,解引用时,*p表示的就是p所指向的空间,这时的*也称为取空间操作,找到p所指向的空间,必须强调的是,这时的*p是一个整体,不能割裂来看,比如:
int *p = &a;
*p = 10;//等价于a=10;但是写成* p = 10;就不对了
*作为解引用时(也就是取空间操作时),得到p所指向的空间后,我们的用途有两种,一个是读空间内容,还 有就是向空间写入新的内容。
2.2、取地址符&的理解
取地址符使用时,直接写在变量名称的前面,然后&和变量一起构成了一个新的符号,表示变量空间的首地址,准确讲是变量的首字节地址。比如int a;int *p = &a;这里必须注意,&a是一个完整的不可分割的整体,之所以用这种方式来表示空间的地址,是因为我们没有办法直接得到变量a的地址,只能是使用&a来表示,当编译时会将&a变成a空间的地址赋值给p;
2.3、指针变量的初始化和指针变量赋值之间的区别
首先必须强调,指针变量的初始化与普通变量的初始化没有任何区别,只是指针变量里面的存放的是一个特殊的值“地址”,这个值具有指向作用,可以用来访问它所指向的空间,如果你刨去它地址的含义,实际上变量中存放的不过就是一个普通值。
(1)指针变量的初始化
Int a=10;
Int *p=&a;
此时的*,只是说明p是一个一级指针变量,不能把这时的*当成了解引用。
(2)指针变量的赋值
Int a=10;
Int *p=NULL;
p=&a;//将a空间地址的赋值给p
不少同学可能一直觉得p=&a,应该写成*p=&a;这是错误的理解,这时的*是取空间操作,如果写成*p=&a,就表示将a的空间地址存放到p所指向的空间,p所指向的空间其实就是a,*p=&a的等价写法就是a=&a;相当于把地址给了a自己,显然是不对的。
(3)初始化和赋值注意点
从形式上看,我们已经知道了初始化和赋值的区别,同时要知道初始化只能有一次,但是赋值可以有多次。
2.4、左值与右值
(1)什么是左值和右值
比如:int a=10;等式的左边称为左值,右边称为右值。
(2)左值
在c语言中,左值指的都是变量空间。对左值执行的操作都是写空间操作。
(3)右值
在c中,右值有两种形态,一种是直接写一个数值,比如int a=10;就是典型的这种情况。那么另外的一种情况就是,右值可能也是一个变量,比如int b=10; int a=b;这个时候右值就是一个变量。当变量作为左值是,对变量实现的是写操作,如果变量作为右值时,对变量实现的是读操作,读出后赋给右值,这一点要了解。
2.5、定义指针后,需要会关心的一些内容
(1)例子1
Int a =10;
Int *p=&a;
合理我们必须了解与指针变量p相关的一些内容。
p:表示int*型的一级指针变量空间,里面存放的是变量a的地址。
*p:表示p所指向的空间,指的就是a的空间,只不过是通过地址找到的。
&p:表示指针变量p自己的空间地址,它需要是int **的二级指针变量来存放。
思考一下,**p=20可不可以?
回答:不可以,**p改写成等价形式*(*p),里面的*p等价于a,最后变成了*a,由于a的值等于10,*a就是*10,引用地址10所指向的空间,显然10这个地址指向的空间是不存在的,所以错误。
(2)例子2:
Int a =10;
Int *p=&a;
Int **p1=&p;
对于指针变量p,需要关心p、*p、&p,但是在上例中已经描述过了,不再赘述。
对于指针变量p1来说,需要如下几个方面的问题:
p1:一个int **型的二级指针变量空间,用于存放一个二级地址,恰好*p的地址就是二级地址。
*p1:引用取空间操作,找到p1所指向的空间,指的就是p的空间。
**p1:将其中的*p1替换成为p,**p1就变成了*p,指的就是a的空间。
&p1:指的是二级指针变量p1的空间地址,是一个三级地址。
只要大家理解前面的例子1和例子2,对于三级指针的情况,道理是类似的,但是我们前面就说过,构建三级以上的指针实际上没有太大的意义,除了某些极少数的情况外,并不会为我们的程序带来多少好处。
思考一下:***p1可不可以?
答:不可以,根据取空间操作,***p1最终变成了*10,显然也是错误的。
(3)多级指针链断线的问题
Int a =10;
Int *p;
Int **p1=&p;
Int b=**p1;
**p1,原是想通过**p1访问到a的空间,将a空间的内容赋给b,但是这里是不对的,因为中间的指针变量p并没有指向a,指针链断线了,所以我们在使用多级指针的时候,必须注意构建的指针链是否完整。当然这里因为是直接写的比较好理解,如果多级指针链是通过传参的方式来构建的话,很容易出现断链的情况,造成的影响就是,要么访问到是空指针,要么访问到了不该访问的地方,导致严重错误。
- 指针才是C语言的精髓
- 单片机C语言和汇编语言混合编程实例详解 224次下载
- C语言指针与指针变量的简介和运算实例程序免费下载 14次下载
- C语言指针的表达式实例程序说明 4次下载
- C语言指针的三个问题的详细资料说明
- 轻松理解C语言指针的实验和详细资料说明 10次下载
- C语言教程之指针的详细资料说明 9次下载
- C语言程序设计教程之指针使用的课件免费下载 15次下载
- C指针详解-经典-非常详细 79次下载
- C语言指针跨函数访问 1次下载
- 嵌入式linux-C语言的精髓——指针详解 0次下载
- 彻底搞定C语言指针详解完整版 0次下载
- C语言指针函数和函数指针详细介绍 5次下载
- C语言中指针的介绍非常详细 57次下载
- C语言指针电子教程 77次下载
- C语言函数指针六大应用场景详解 712次阅读
- 详解C语言指针底层基本原理 1112次阅读
- 什么是C语言(void*)类型 2691次阅读
- C语言中的悬空指针和野指针是什么意思? 944次阅读
- PLC指针类型与间接寻址详解 2267次阅读
- C语言中指针的命令行参数 1034次阅读
- C语言指针和数组的区别 1776次阅读
- C语言指针相关的概念、语法及使用场景 1866次阅读
- 应该如何学习C语言?给学习C语言的同学几点建议 2930次阅读
- C语言中的“二级指针”该如何理解 1.2w次阅读
- 指针和数组都是C语言的精髓所在 两者有何联系区别 3836次阅读
- 嵌入式开发之C语言的指针 3128次阅读
- 为什么C语言要引入指针_引入指针的好处是什么 2.2w次阅读
- C语言使用中指针和内存泄漏的问题和解决方案 4102次阅读
- 基于C语言中指针的基本用法解析 4700次阅读
下载排行
本周
- 1电子电路原理第七版PDF电子教材免费下载
- 0.00 MB | 1490次下载 | 免费
- 2单片机典型实例介绍
- 18.19 MB | 92次下载 | 1 积分
- 3S7-200PLC编程实例详细资料
- 1.17 MB | 27次下载 | 1 积分
- 4笔记本电脑主板的元件识别和讲解说明
- 4.28 MB | 18次下载 | 4 积分
- 5开关电源原理及各功能电路详解
- 0.38 MB | 10次下载 | 免费
- 6基于AT89C2051/4051单片机编程器的实验
- 0.11 MB | 4次下载 | 免费
- 7蓝牙设备在嵌入式领域的广泛应用
- 0.63 MB | 3次下载 | 免费
- 89天练会电子电路识图
- 5.91 MB | 3次下载 | 免费
本月
- 1OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB | 234313次下载 | 免费
- 2PADS 9.0 2009最新版 -下载
- 0.00 MB | 66304次下载 | 免费
- 3protel99下载protel99软件下载(中文版)
- 0.00 MB | 51209次下载 | 免费
- 4LabView 8.0 专业版下载 (3CD完整版)
- 0.00 MB | 51043次下载 | 免费
- 5555集成电路应用800例(新编版)
- 0.00 MB | 33562次下载 | 免费
- 6接口电路图大全
- 未知 | 30320次下载 | 免费
- 7Multisim 10下载Multisim 10 中文版
- 0.00 MB | 28588次下载 | 免费
- 8开关电源设计实例指南
- 未知 | 21539次下载 | 免费
总榜
- 1matlab软件下载入口
- 未知 | 935053次下载 | 免费
- 2protel99se软件下载(可英文版转中文版)
- 78.1 MB | 537791次下载 | 免费
- 3MATLAB 7.1 下载 (含软件介绍)
- 未知 | 420026次下载 | 免费
- 4OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB | 234313次下载 | 免费
- 5Altium DXP2002下载入口
- 未知 | 233045次下载 | 免费
- 6电路仿真软件multisim 10.0免费下载
- 340992 | 191183次下载 | 免费
- 7十天学会AVR单片机与C语言视频教程 下载
- 158M | 183277次下载 | 免费
- 8proe5.0野火版下载(中文版免费下载)
- 未知 | 138039次下载 | 免费
评论
查看更多