为什么可以对数组名进行 * 和 & 操作
2014-03-31 18:58
661 查看
当一个数组名出现在一个表达式中时,它会被转换为指向该数组第一个元素的指针常量,既然是常量,那么对它进行 & 操作,似乎会有问题。
编译,运行,一切都很正常。我们都知道,& 操作符的操作对象必须是左值,为什么可以对一个常量进行 & 操作呢?
可以通过下面这段代码,验证 ary 是一个常量
编译报错:error C2105: '++' needs l-value
可以看到,ary 确实是一个常量,可它确实能进行 & 操作,这是怎么回事呢?正向退不出来,我们可以试一下反向推导。
观察运行结果,ary = *ary, * 号是取指针内容,这个地址存放的内容是 1 ,怎么会相等呢?难道不是取地址内容的意思吗?
PS:* 号有三种含义,1、乘法;2、定义指针;3、取指针内容
那其他两种用法就更不靠谱了,难道是一种新的用法?
在观察,可以发现,sizeof(ary) != sizeof(*ary),他们分别是24和12,我们似乎发现了什么,24 = 2*3*4,12 = 3*4。
结论:当 * 号作用于数组名的时候,类型改变,而值不变,* 号表示解除引用的意思。有加法必有减法,同理,可以对数组名做 * 操作,那么就可以对数组名做 & 操作,表示改变地址的类型。这就可以解释,为什么可以对数组名这个常量进行 & 操作,值不变,类型发生变化。
总结:对数组名的 & 和 * 操作,值不变,指针升级或降级。
void main () { int ary[5] = {1, 2, 3, 4, 5}; printf("%p\r\n", ary); printf("%p\r\n", &ary); }
编译,运行,一切都很正常。我们都知道,& 操作符的操作对象必须是左值,为什么可以对一个常量进行 & 操作呢?
可以通过下面这段代码,验证 ary 是一个常量
void main () { int ary[5] = {1, 2, 3, 4, 5}; printf("%p\r\n", ary); ary++; }
编译报错:error C2105: '++' needs l-value
可以看到,ary 确实是一个常量,可它确实能进行 & 操作,这是怎么回事呢?正向退不出来,我们可以试一下反向推导。
void main () { int ary[2][3] = { 1, 2, 3, 4, 5, 6 }; printf("sizeof(ary) = %d\r\n", sizeof(ary)); printf("ary = %d\r\n", ary); printf("sizeof(*ary) = %d\r\n", sizeof(*ary)); printf("*ary = %d\r\n", *ary); }
观察运行结果,ary = *ary, * 号是取指针内容,这个地址存放的内容是 1 ,怎么会相等呢?难道不是取地址内容的意思吗?
PS:* 号有三种含义,1、乘法;2、定义指针;3、取指针内容
那其他两种用法就更不靠谱了,难道是一种新的用法?
在观察,可以发现,sizeof(ary) != sizeof(*ary),他们分别是24和12,我们似乎发现了什么,24 = 2*3*4,12 = 3*4。
结论:当 * 号作用于数组名的时候,类型改变,而值不变,* 号表示解除引用的意思。有加法必有减法,同理,可以对数组名做 * 操作,那么就可以对数组名做 & 操作,表示改变地址的类型。这就可以解释,为什么可以对数组名这个常量进行 & 操作,值不变,类型发生变化。
总结:对数组名的 & 和 * 操作,值不变,指针升级或降级。
相关文章推荐
- Command不是也可以对数据库进行insert,update,delete操作吗,为什么还需要DataAdapter。我知道DataAdapter可以用来想AataSet中填充数据,Command不可以吗?
- Iterator为什么不能对容器的进行添加或修改操作(可以删除)
- 一个封装好的C++比特数组BitArray,可以对位进行直接操作
- 为什么数组可以不加“&”取它的地址,而普通变量必须要加“& ”才可以呢?
- C语言 为什么数组名(数组首地址)不能进行加减操作?
- C语言问题:为什么可以留着数组中第一维的参数不进行说明,但是其他维数必须说明呢?
- c语言 数组名&&结构体名 为什么不能用数组名给数组赋值,结构体却可以
- 为什么数组可以不加“&”取它的地址,而普通变量必须要加“& ”才可以呢?
- java类中用类的数组作为函数参数传给类,为什么不能直接对类的数组进行操作?
- C++友元friend --c++利用friend修饰符,可以让一些你设定的函数能够对这些保护数据进行操作
- JavaScript当离开页面时可以进行的操作
- 调用webservice时提示对操作的回复消息正文进行反序列化时出错&&Web service 超过了最大请求长度
- php用explode,可以提供多个字符作为分割符来进行分割数组吗?
- 指针在任何情况下都可以进行>,=,<=, ==运算
- ORCL数据库中进行一些相应的操作 基本上就满足的了一般的需求 ,以下是详细步骤>>
- Chapter 3 | Stacks and Queues--实现数据结构模拟一个栈由几个子栈组成,并可以在指定子栈上进行出栈操作
- 利用函数调用,对数组进行初始化,更改,清零,逆置等操作
- 为什么要对对象进行序列化操作?
- (非常好的Word操作封装类)VC中进行office编程的-操作word,可以设置文字的样式,新建表格
- 堆的数据结构能够使得堆顶总是维持最大(对于大根堆)或最小(对于小根堆),给定一个数组,对这个数组进行建堆,则平均复杂度是多少?如果只是用堆的 push 操作,则一个大根堆依次输入 3,7,2,4,1,5,8 后,得到的堆的结构示意图是下述图表中的哪个?