Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1271345
  • 博文数量: 482
  • 博客积分: 13297
  • 博客等级: 上将
  • 技术积分: 2890
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-12 16:25
文章分类

全部博文(482)

文章存档

2012年(9)

2011年(407)

2010年(66)

分类: 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也是首地址

没啥特殊的,就是这样规定的。

----------------------------------------------------------------------------------------------

数组名在编译时会转化为指向数组第一个元素的指针

----------------------------------------------------------------------------------------------

指向块首的嵌入型常量指针

----------------------------------------------------------------------------------------------

数组名,一般的变量名,指针变量名,函数名,本质上都是汇编语言中的符号地址

----------------------------------------------------------------------------------------------

引用 19 楼 proghua 的回复:

数组名在编译时会转化为指向数组第一个元素的指针


1、数组名不是指针
2、数组名神似指针

  (1)数组名的内涵在于其指代实体是一种数据结构,这种数据结构就是数组;

  (2)数组名的外延在于其可以转换为指向其指代实体的指针,而且是一个指针常量;

  (3)指向数组的指针则是另外一种变量类型(在WIN32平台下,长度为4),仅仅意味着数组的存放地址!

----------------------------------------------------------------------------------------------

变量名是什么?,,还不就是一个符号吗,,用来标志一个变量的,,数组名也就是一个符号,,用来标识数组的,,数组的“值”(请允许这么说)与数组首元素的地址相等(是相等,不是相同),,&a取数组的存放地址(前提a是数组),,数组的存放地址当然与数组的首元素地址相等了(这里还是值相等,不是相同)

数组名就是代指数组的一个符号,,这就好比变量名,,变量是变量,可变量名是变量吗?变量名是常量吗?,个人觉得,它只是一个符号,,代指变量的符号,,数组名也就是代指数组的符号。

----------------------------------------------------------------------------------------------

数组名的值是数组的地址,数组名的地址也是数组的地址.
变量名的值是变量的值,变量名的地址是变量的地址.

大家看出不同来了吗?

假如数组名要和变量名相同,那么数组名的值应该是数组的值,也就是第一个元素的值,但是它的值却是数组的地址,真叫人不可理解,这样看来,数组名也不能理解为一个符号常量,也不能理解为指向数组的常量指针,那么它到底是个什么东西呢?

----------------------------------------------------------------------------------------------

我就是想知道这个数组名是怎么实现的,假如它是常量,那么应该放在常量区,用&是取不到地址的,而它可以取到地址,说明是作为变量放到栈里去的,但是和变量不同,它的值是不能修改的,同时它似乎也不占用内存,因为它是个地址常量,晕,又转回来了,一个有地址的地址常量,我靠,互相打架的,不清楚数组名是咋生产出来的.

----------------------------------------------------------------------------------------------

常量和常量区没什么关系,能娶到地址的也不一定在栈,函数名也能取地址

数组名在不同的地方实现也不同,你去看一下汇编代码

----------------------------------------------------------------------------------------------

引用 55 楼 motiandalou 的回复:
我就是想知道这个数组名是怎么实现的,假如它是常量,那么应该放在常量区,用&是取不到地址的,而它可以取到地址,说明是作为变量放到栈里去的,但是和变量不同,它的值是不能修改的,同时它似乎也不占用内存,因为它是个地址常量,晕,又转回来了,一个有地址的地址常量,我靠,互相打架的,不清楚数组名是咋生产出来的.



你这些问题,在C/C++标准中都有相关的规定,我在blog的第一章和第二章根据标准的条款作出了解答。

还有什么理解不了的,尽管问,可以一个个条款地帮你解释。

----------------------------------------------------------------------------------------------

呵呵,感觉跟着这个问题的人中,也有不少是传说中的"高手"吧,,,可是,很多人是不是犯了个"基本错误"呢,,
楼主问的是"数组名是什么",,这里的的主语是"数组名",,,如果你给一个没学编程的人说,数组名是什么??我想,很大一部分人一下就能反应过来,,,答案应该很简单,,数组名,就是数组的名字嘛....
我想说,无论你在C编程或者其它什么语言编程时怎么去用数组名,或者数组名有什么用途这都无所谓,都不与数组名是数组的名字的基本概念冲突..
名字,说到底就是一个助记符号而已,有什么可纠结的,,,,数组名,就是给数组变量(或者叫变量数组,当然也有党量的)取的一个名字而已,,
也许有人要问了"为什么用数组名输出时是个地址呢?这不说明数组名是个党量吗?",,,呵呵,,,如果我告诉你,如果你要用一个数组做printf的参数来输出值的话,它就是一个地址,,,,,如果你的编译器支持"复合文字",你可以试一下这个语句

C/C++ code
printf("%p", (int []){1,2,3,4,5,6});

不用怀疑,这是正确的语句,如果你同样用上面的"复合文字"做一个函数的参数,那么你在函数中就可以当一个数组去使用了,,和你事先定义去初始化一个数组后用数组名去调用函数的结果相同,
当然,你用"复合文字",也可以去定义一个没有名字的数组,把它的地址赋给一个指针(数组或者复合文字这东西,在C中都是表达式,而C的表达式是有个值的,数组和表达式的"值"就是它的存放地址)
说的有点乱,不知道各位有没有理解,,,
数组名,只是一个助记符号而已,,,不是什么常量,,也不是什么指针,,也不是什么地址(可以说数组表达式的值是个地址)数组名,只是一个助记符号而已,,,不是什么常量,,也不是什么指针,,也不是什么地址(可以说数组表达式的值是个地址)

----------------------------------------------------------------------------------------------

引用 65 楼 zouyuncheng 的回复:
呵呵,感觉跟着这个问题的人中,也有不少是传说中的"高手"吧,,,可是,很多人是不是犯了个"基本错误"呢,,
楼主问的是"数组名是什么",,这里的的主语是"数组名",,,如果你给一个没学编程的人说,数组名是什么??我想,很大一部分人一下就能反应过来,,,答案应该很简单,,数组名,就是数组的名字嘛....
我想说,无论你在C编程或者其它什么语言编程时怎么去用数组名,或者数组名有什么用途这都无所谓,……


用助记符这个名称勉强可以,但尚不够准确,准确地说是标识符(identifier),虽然标准没有使用助记符这个名称及其语义,但从其语义上讲,助记符接近于标准中的token,而token是外延比identifier大得多的概念。

讲数组名是一个标识符,这是从词法的角度来阐述的,当然也可以从另外的角度去描述。从对象模型的角度描述,数组名是一个对象指示符(object designator),从内存模型的角度去描述,数组名是一个变量名。

----------------------------------------------------------------------------------------------

引用 71 楼 zjq9931 的回复:
楼主相搞明白数组名,需要先搞明白变量名。
变量名,跟数组名是一样的。
变量可以看作是只有一个元素的数组。



问题是变量名的值是个数值,而变量名的地址是数值的地址。
假如数组名和变量名相同,那么数组名的值应该是数组中第一个元素的值,而不是地址。

----------------------------------------------------------------------------------------------


#include
<stdio.h> int main() { int var=1; int array[3]={2,3,4}; int arrayx[1]={5}; printf("%d\n%d\n%d\n", var, array[0], arrayx[0]);//常用的输出方式 puts(""); printf("%d\n%d\n%d\n", var, *array, *arrayx); //数组名是数组的第一个元素的首地址 puts(""); printf("%d\n%d\n%d\n", &var, array, arrayx); //数组名是数组变量的首地址 puts(""); printf("%d\n%d\n%d\n", &var, &array, &arrayx); //对数组名取地址 int *ip; ip=arrayx; puts(""); printf("%d\n%d\n%d\n%d\n", var, array, arrayx, ip); //数组名与指针 puts(""); printf("%d\n%d\n%d\n%d\n", var, array, arrayx, &ip); //数组名与指针地址 return 0; }


 

----------------------------------------------------------------------------------------------

引用 78 楼 gracedida 的回复:

void f(char a[])
{
printf("%p,%p,%p",a,&a,&a[0]);
}

int main(){
char a[3];
f(a);
return 0;
}

请问为什么在这个程序中 a和 &a值 不一样?
若写在主程序中 输出a和&a是一样的。
谢谢


形参中的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,已经超出了这个数组的地址范围指向下一个数组单元,
所以说他们的本质还是有区别的,归根结底就是他们的类型不一样。

----------------------------------------------------------------------------------------------

====

阅读(1612) | 评论(4) | 转发(0) |
给主人留下些什么吧!~~

Alan05212011-10-12 21:10:45

记得以前书上说 数组名代表首地址,觉得不管代表什么都是编译器说了算,很多时候是没有道理的

Alan05212011-09-30 09:39:54

对于结构体struct str1{char c; int a}s1;
sizeof(s1)=8
s1=0
s1+1非法
&s1=22ff48
&s1 + 1 = 22ff50

Alan05212011-09-26 11:05:07

我还是倾向于把数组名,变量名,函数名等看作一样的。都是只是地址,只是符号。不过他们之间是有区别的。
int a[3]={0,1,2};
a, &a, &a[0]都是首地址,但是类型不同。
a, &a[0]为int类型地址,&a为数组类型地址。