再论C语言指针、地址、赋值的问题,又是一通“扯”
来自: ageratum(„Zu den Sachen selbst!“)
再论C语言指针、地址、赋值的问题,又是一通“扯” 按:在CSDN论坛上,有位坛友提到这个问题: ==================================== 先看一段代码: #include<stdio.h> void main() { int*p=10; printf("%d",p); } 看 看上述代码有什么问题没有?相信清楚指针概念的各位知道,int*p其实划分来看是(int*)p,他其实是一个指针,那么int*p=10;等价于 int*p;p=10;,大家都知道,指针就是地址,前面语句的意思是,把常量10的值赋给指针p,按照定义来说,这是不合法的,因为常量不能直接赋值给 指针,比如int a=10;int*p=&a;这才是合法的。但是我通过VC6.0编译器编译一下,文件名为al.C(注意了,非CPP后缀),结果编译器毫不报 错;输出结果为10。 ==================================== 看了这位坛友的帖子,实在令人担忧呀…… 首先,您(称呼这位坛友)说“按照定义来说,这是不合法的,因为常量不能直接赋值给指针”。 哪里有这个“定义”呀? 我慢慢说……到后来,您就会知道,您的这种“定义”是毫无意义的。 先说啥是指针。 您说“大家都知道,指针就是地址”。这种说法是错误的(且害人的)。用这种思路去理解指针,那说明您还没有体会到,关于指针的许多真实情况。 “地址”这个观念,是为了让那些需要向存储器中的某个或某些存储单元进行数据存取的主体(比如处理器)能够找到这些存储单元,而引入的。 显然地,在这些主体看来,那些存储单元的位置(即地址),也是数据。那么,这后一种数据,也要在存储器中被存储、被读写。(从C语言编程语境来看, 这后一种数据的符号,就是指针变量或指针常量的符号。) 而“指针”这个观念的引入,与“地址”的比起来,要复杂一些,或者说,前者的用途与意义更具多样性: (1)指针变量或指针常量的值,往往可以由一个取地址符(&)作用在一个变量或常量的符号上而获得。 如果您要说“指针的值,不能取常量的地址”的话,那您又错了。如下写法,就可以令指针取到常量的地址: int const a=12345; int const *pa=&a; 或 int const a=12345; int const *pa; pa=&a; 从这个角度看来,指针的用途和意义在于:获取程序中变量或常量符号实际对应于存储器的数据的位置。 那么,对于同一个指针量,可以随程序员的意愿,在任何时候,获取任何既有的符号所对应的数据的位置,作为它的值 —— 不过,这里有一个极不可忽略的条件,下面会讲。 地址,则没有上述的意义和用途。一个符号所对应的数据,在存储器中的位置,在符号被声明的当初,就任由老Boss来分配。这个分配过程,对于程序员来说,是透明的 —— 这是高级语言与低级语言之间的一个显著区分。但由于C语言里存在着“指针”这个机制,就使得它“高级得不那么彻底” —— 因为,程序员可以透过指针,来窥探到老Boss和他的存储器情人是怎么约会的。 (2)指针量的值,除了由上面第(1)点中所说的方式获得之外,还可以由第(1)点中的方式所获得的量,再加加减减,即进行所谓“指针运算”来被赋予。让函数返回一个“实用的”存储器中的位置值,通常就是属于这一类。 (3)在第(1)点的例子里,我们已经看到:在声明指针量符号的时候,必须必须同时给出某种数据类型。这个数据类型必须必须,跟这个指针将来要指向的符号在被声明时所设置的数据类型,完全一致! 如果差那么一点儿,但尚在老Boss的理解范围之内的话,那么,老Boss会骂一句(吐出一个Warning),然后他会心不服但手服地,为指针量赋值等号右边的东西,做一些强制的转换。 但是如果差得比较离谱了,老Boss就索性罢工了。 在这位坛友的例子中: int*p=10; 就是属于前一种的“差那么一点儿”的情况。这时候,虽然老Boss没有罢工(没有编译error),但是您不知道,他已经有一些怨气地在暗地里,为您做了一些事情。如果您打开Warning选项,就能听到他的骂声。(千万不要以为“编译通过,程序就是写得100%合乎标准的”!) 如果您把上面的代码,改写成这样: int *p=(int *)10; 那么,保证老Boss不会骂您、更不会罢工。 上面这样写是什么意思呢?原来您的写法,是把一个整数10赋予了指针量p。我们姑且认为这个10就是整数常量。其实,不管这个10是个啥量啥类型,只要前面顶上一个“(int *)”,它就会被老Boss强制转换为:符号p在声明时所设置的那个类型(即指向整数类型变量的指针)。 我为什么说“不管这个10是个啥量啥类型”呢? 您看: int *p=(int *)'a'; 就是如此,老Boss也不会骂人或罢工。 这里,“a”被括在单引号里,表达了一个字符常量,它依然可以100%合法地被赋予指针量p。 您就是写成: int *p=(int *)"I Love C/C++! Oh, Yeah!"; —— 这也是100%合法的!为什么?留给这位坛友自己思考。 这一切跟“变量还是常量”没有任何关系。起决定性因素的,是类型(指针所指向的数据的类型)! 所以,您所说的“按照定义来说……常量不能直接赋值给指针”,是完全没有意义的。 数据的类型,在C语言里,是如此的重要,以至于忽略了它,整个C语言的合理性和逻辑性,就会完全丧失。 “类型”这个机制,是程序员大脑中的数据(逻辑的),与计算机内部的数据(物理的),两者之所以能够沟通的最重要媒介。一旦忽视了它,两头之间,就只剩下混乱了。 顺便说一句,这又体现了:“地址”与“指针”的不同。前者没有“类型”属性,而后者,“类型”是它的内秉属性(与生俱来的、不可或缺的)。 以上又“扯”了一通,仅供参考! 有什么错误,希望各位大虾拍砖指正!谢谢!
-
逐梦的Ta 赞了这篇讨论 2022-08-12 19:01:49
-
小hh27 赞了这篇讨论 2019-05-21 10:08:32
-
[已注销] 赞了这篇讨论 2017-09-12 19:24:04
-
阿凡提 赞了这篇讨论 2016-12-24 15:11:03
-
astrotycoon 赞了这篇讨论 2016-03-03 15:26:35
-
水色 赞了这篇讨论 2015-08-16 23:51:45
-
半塘可乐 赞了这篇讨论 2015-08-14 23:09:04
-
流年伴夏t 赞了这篇讨论 2015-05-07 15:40:49
-
Qing77 赞了这篇讨论 2015-01-25 12:26:18
-
十六 赞了这篇讨论 2014-10-21 04:43:59
-
scoldfield 赞了这篇讨论 2014-09-24 01:41:12
-
Sam 赞了这篇讨论 2014-05-19 17:39:31
-
实沉 赞了这篇讨论 2014-05-15 03:50:24
-
[已注销] 赞了这篇讨论 2014-04-09 13:32:42
-
JV 赞了这篇讨论 2014-04-03 00:23:18
-
Mr_forever 赞了这篇讨论 2014-03-09 01:52:57
-
快乐男孩 赞了这篇讨论 2014-03-07 21:18:44
-
Rambo 赞了这篇讨论 2014-03-05 23:21:53
-
IntelDan 赞了这篇讨论 2014-03-05 18:20:00
-
宇晨 赞了这篇讨论 2014-02-27 16:12:52
-
最近有点烦 赞了这篇讨论 2014-02-18 21:59:11
-
momo 赞了这篇讨论 2014-02-16 05:35:49
-
[已注销] 赞了这篇讨论 2014-02-12 08:55:21
-
暗喻1994 赞了这篇讨论 2014-02-01 00:20:56
-
長生 赞了这篇讨论 2014-01-31 22:05:43
-
十一 赞了这篇讨论 2014-01-28 17:29:51
-
走在你身后 赞了这篇讨论 2014-01-26 19:52:14
-
嘎嘎是你哥 赞了这篇讨论 2014-01-26 17:38:49
-
Flynn 赞了这篇讨论 2014-01-19 18:13:58
-
时光刀客-Jam 赞了这篇讨论 2014-01-19 02:09:19
-
啊啊啊啊啊 赞了这篇讨论 2014-01-09 17:34:59
-
岁月安好 赞了这篇讨论 2014-01-08 16:08:06
-
nooneknowsmeli 赞了这篇讨论 2014-01-08 01:53:43
-
清源 赞了这篇讨论 2014-01-07 10:07:50
-
TAT two 赞了这篇讨论 2014-01-06 14:13:06
-
MJ、Y 赞了这篇讨论 2014-01-06 09:54:20
-
guardian 赞了这篇讨论 2014-01-05 09:51:26
-
慌张 赞了这篇讨论 2013-11-06 23:22:47
-
小邓在路上 赞了这篇讨论 2013-10-26 22:45:14
-
文艺的2B青年 赞了这篇讨论 2013-10-06 22:12:03
-
还能不能注销了 赞了这篇讨论 2013-09-30 15:39:26
-
猫之守护 赞了这篇讨论 2013-08-07 18:10:50
-
cool 赞了这篇讨论 2013-08-06 17:48:29
-
开门查水表 赞了这篇讨论 2013-08-04 13:03:25
-
鲁冰花 赞了这篇讨论 2013-07-30 15:02:53
-
Stallone 赞了这篇讨论 2013-07-30 14:43:19
-
大哥乔乔 赞了这篇讨论 2013-07-16 15:56:34
-
北鼻 赞了这篇讨论 2013-06-19 11:52:09
-
攀登 赞了这篇讨论 2013-06-02 19:02:16
-
YK 赞了这篇讨论 2013-06-02 05:01:43
-
简繁星 赞了这篇讨论 2013-05-21 16:00:04
-
Saudade 赞了这篇讨论 2013-05-18 11:35:19
-
DBking 赞了这篇讨论 2013-04-04 23:19:30
-
_晓望晴空 赞了这篇讨论 2013-03-08 03:02:25
-
ruii 赞了这篇讨论 2013-03-01 20:15:52
-
老鸭粉丝汤 赞了这篇讨论 2012-12-28 21:22:54
-
斩不断的风 赞了这篇讨论 2012-12-23 11:39:31
-
sycamoreeeeee 赞了这篇讨论 2012-12-13 12:50:22
-
cgoodc 赞了这篇讨论 2012-12-10 14:26:02
-
Stone_Ocean 赞了这篇讨论 2012-09-07 08:24:24
-
star 赞了这篇讨论 2012-08-27 22:28:48
-
Lespublica 赞了这篇讨论 2012-07-17 04:20:59
-
aguai 赞了这篇讨论 2012-07-17 03:51:11
最新讨论 ( 更多 )
- 不会还有江浙沪大二的同学找不到实习吧? (玖风)
- 挑战在暑假前帮大二er找到实习 (玖风)
- 【资料分享】 滴水2019逆向C++中级全套课程 (狂奔的懒猫)
- 招聘招聘,寻找会c语言,对金融交易有兴趣的合作者,报酬可观... (不温和的昏暗)
- 分享课程——C++大型流媒体项目-从底层到应用层千万级直播系... (单花红丝线)