分类: WINDOWS
2011-09-25 22:29:06
int a[3]={1,2,3};
数组名a到底是什么?假如说它是个地址常量,那么为什么还能获取到它的地址?一般来说常量存放在常量区,是不能获得常量的地址的,假如不是地址常量,那么为什么它的值和地址都是相同的,指针常量的值和地址都是不同的,那么数组名到底是什么?
----------------------------------------------------------------------------------------------
int a[3]={1,2,3};
相当于
int *const a
所以说数组名是个常量,不能改变
----------------------------------------------------------------------------------------------
就是地址常量
----------------------------------------------------------------------------------------------
不学汇编就学c容易出这种问题
----------------------------------------------------------------------------------------------
其实就是一个地址值~~~
----------------------------------------------------------------------------------------------
在不同的地方是不同的意思。
int a[3]={1,2,3};
sizeof(a) 表示数组的大小,
&a 是一个指向数组a的指针,
其它表达式里就是指向 a[0] 的指针。
----------------------------------------------------------------------------------------------
就是一个机器字长大小的常地址,只不过在对指针赋值和函数调用时,会隐式转换成指针.
个人理解,轻拍!
----------------------------------------------------------------------------------------------
其实数组名可以看成是指向这个数组首地址的指针,不过是当一个地址常量在用,但是数组名还可以表示这个数组的长度。
----------------------------------------------------------------------------------------------
a 代表数组第一个元素的地址即&a[0];
&a代表整个数组的首地址(恰好也==&a[0]);
数组名标志一个数组,可以理解为一个符号常量!!
----------------------------------------------------------------------------------------------
数组名就是数组名
&a 得到 数组的首地址 , a也是首地址
没啥特殊的,就是这样规定的。
----------------------------------------------------------------------------------------------
数组名在编译时会转化为指向数组第一个元素的指针
----------------------------------------------------------------------------------------------
指向块首的嵌入型常量指针
----------------------------------------------------------------------------------------------
数组名,一般的变量名,指针变量名,函数名,本质上都是汇编语言中的符号地址
----------------------------------------------------------------------------------------------
1、数组名不是指针
2、数组名神似指针
(1)数组名的内涵在于其指代实体是一种数据结构,这种数据结构就是数组;
(2)数组名的外延在于其可以转换为指向其指代实体的指针,而且是一个指针常量;
(3)指向数组的指针则是另外一种变量类型(在WIN32平台下,长度为4),仅仅意味着数组的存放地址!
----------------------------------------------------------------------------------------------
变量名是什么?,,还不就是一个符号吗,,用来标志一个变量的,,数组名也就是一个符号,,用来标识数组的,,数组的“值”(请允许这么说)与数组首元素的地址相等(是相等,不是相同),,&a取数组的存放地址(前提a是数组),,数组的存放地址当然与数组的首元素地址相等了(这里还是值相等,不是相同)
数组名就是代指数组的一个符号,,这就好比变量名,,变量是变量,可变量名是变量吗?变量名是常量吗?,个人觉得,它只是一个符号,,代指变量的符号,,数组名也就是代指数组的符号。
----------------------------------------------------------------------------------------------
数组名的值是数组的地址,数组名的地址也是数组的地址.
变量名的值是变量的值,变量名的地址是变量的地址.
大家看出不同来了吗?
假如数组名要和变量名相同,那么数组名的值应该是数组的值,也就是第一个元素的值,但是它的值却是数组的地址,真叫人不可理解,这样看来,数组名也不能理解为一个符号常量,也不能理解为指向数组的常量指针,那么它到底是个什么东西呢?
----------------------------------------------------------------------------------------------
我就是想知道这个数组名是怎么实现的,假如它是常量,那么应该放在常量区,用&是取不到地址的,而它可以取到地址,说明是作为变量放到栈里去的,但是和变量不同,它的值是不能修改的,同时它似乎也不占用内存,因为它是个地址常量,晕,又转回来了,一个有地址的地址常量,我靠,互相打架的,不清楚数组名是咋生产出来的.
----------------------------------------------------------------------------------------------
常量和常量区没什么关系,能娶到地址的也不一定在栈,函数名也能取地址
数组名在不同的地方实现也不同,你去看一下汇编代码
----------------------------------------------------------------------------------------------
你这些问题,在C/C++标准中都有相关的规定,我在blog的第一章和第二章根据标准的条款作出了解答。
还有什么理解不了的,尽管问,可以一个个条款地帮你解释。
----------------------------------------------------------------------------------------------
呵呵,感觉跟着这个问题的人中,也有不少是传说中的"高手"吧,,,可是,很多人是不是犯了个"基本错误"呢,,
楼主问的是"数组名是什么",,这里的的主语是"数组名",,,如果你给一个没学编程的人说,数组名是什么??我想,很大一部分人一下就能反应过来,,,答案应该很简单,,数组名,就是数组的名字嘛....
我想说,无论你在C编程或者其它什么语言编程时怎么去用数组名,或者数组名有什么用途这都无所谓,都不与数组名是数组的名字的基本概念冲突..
名字,说到底就是一个助记符号而已,有什么可纠结的,,,,数组名,就是给数组变量(或者叫变量数组,当然也有党量的)取的一个名字而已,,
也许有人要问了"为什么用数组名输出时是个地址呢?这不说明数组名是个党量吗?",,,呵呵,,,如果我告诉你,如果你要用一个数组做printf的参数来输出值的话,它就是一个地址,,,,,如果你的编译器支持"复合文字",你可以试一下这个语句
不用怀疑,这是正确的语句,如果你同样用上面的"复合文字"做一个函数的参数,那么你在函数中就可以当一个数组去使用了,,和你事先定义去初始化一个数组后用数组名去调用函数的结果相同,
当然,你用"复合文字",也可以去定义一个没有名字的数组,把它的地址赋给一个指针(数组或者复合文字这东西,在C中都是表达式,而C的表达式是有个值的,数组和表达式的"值"就是它的存放地址)
说的有点乱,不知道各位有没有理解,,,
数组名,只是一个助记符号而已,,,不是什么常量,,也不是什么指针,,也不是什么地址(可以说数组表达式的值是个地址)数组名,只是一个助记符号而已,,,不是什么常量,,也不是什么指针,,也不是什么地址(可以说数组表达式的值是个地址)
用助记符这个名称勉强可以,但尚不够准确,准确地说是标识符(identifier),虽然标准没有使用助记符这个名称及其语义,但从其语义上讲,助记符接近于标准中的token,而token是外延比identifier大得多的概念。
讲数组名是一个标识符,这是从词法的角度来阐述的,当然也可以从另外的角度去描述。从对象模型的角度描述,数组名是一个对象指示符(object designator),从内存模型的角度去描述,数组名是一个变量名。
----------------------------------------------------------------------------------------------
问题是变量名的值是个数值,而变量名的地址是数值的地址。
假如数组名和变量名相同,那么数组名的值应该是数组中第一个元素的值,而不是地址。
----------------------------------------------------------------------------------------------
形参中的a[]是指针变量,不是数组
C也好,C++也好,说白了就是跟编译器打交道,编译器说白了就是一个翻译官,所以去看一下C被翻译后对应的反汇编代码,你就会发现他们里面对应的规则。当然就能更好的把握C语言了
----------------------------------------------------------------------------------------------
例如:
int a[3]={1,2,3};
//a数组的地址,是以数组的单元进行变化,加1后是a[0]的地址
cout<
//a数组的首地址,是一整个数组为单位变化
cout<<&a<
//a数组第一个元素的地址
cout<<&a[0]<
cout<
cout<<&a+1<
运行结果:
0012FF58
0012FF58
0012FF58
0012FF5C
0012FF64
分析:
定义a数组后,系统为数组分配3个单元,每个单元4个字节
第一个单元的4个字节:
0012FF58
0012FF59
0012FF5A
0012FF5B
第二个单元的4个字节:
0012FF5C
0012FF5D
0012FF5E
0012FF5F
第三个单元的4个字节:
0012FF60
0012FF61
0012FF62
0012FF63
a就是数组的地址,和&a[0]的值相等都是:0012FF58 ,当a+1后地址就变成了0012FF5C,说明它是以数组元素为单位变化的 ,而&a则不然,虽然它的值和a、&a[0]相等,
但它是数组的首地址,他的变化是以整个数组为单位的,可以看出当它加1后的地址变为:0012FF64,已经超出了这个数组的地址范围指向下一个数组单元,
所以说他们的本质还是有区别的,归根结底就是他们的类型不一样。
----------------------------------------------------------------------------------------------
====