一个看似简单的数组地址问题
2014-03-06 16:30
375 查看
首先我们放出题目:
关于int a[10];
问下面哪些不可以表示a[1] 的地址?
A. a+sizeof(int)
B. &a[0]+1
C. (int*)&a+1
D. (int*)((char*)&a+sizeof(int))
博主是不喜欢凭空臆想的人,所以一般看到这种问题,我一般会通过代码来观察。然后我就简单的写了一个测试程序
编译运行之后结果是这样的:
其实这是个很容易让人产生混淆的情况,杜对于指针来说,a+1才是a[1],而a+sizeof(int)偏移了sizeof(int)【注1,根据系统架构不同,int所占字节数会不同】个地址。
分析了这个之后,让我们来看看剩下的三个。
B:&a[0]+1
对数组第一个元素取地址之后,然后加上一个偏移量。符合!
C:(int*)&a+1
对数组a取首地址,然后强制转换成int *类型,刚好数组a定义就是int型的,所以指针类型是匹配的,1个单位的偏移量相同,符合!
D:(int*)((char*)&a+sizeof(int))
这个稍微有点复杂,我们分开来看
(char *)&a,对数组a取首地址之后,强制转换成为char *类型,注意,此时指针变量变成了char *,一个偏移量就只有一个字节了。
(char *)&a+sizeof(int),此时我们忽略注1的内容,就把int当做4个字节来对待,此时的地址刚好相对于数组首地址偏移4个字节,而不是4个偏移量!!!这里要注意
(int*)((char*)&a+sizeof(int)), 最后将后面那一块的地址强制转换成int *,刚好指向相对数组首地址4个字节的位置,也就是a[1]的位置。
分析完了,感觉面对这种带有很多转换的情况,我们需要拆开来看,这样可能会比较容易明白。
关于int a[10];
问下面哪些不可以表示a[1] 的地址?
A. a+sizeof(int)
B. &a[0]+1
C. (int*)&a+1
D. (int*)((char*)&a+sizeof(int))
博主是不喜欢凭空臆想的人,所以一般看到这种问题,我一般会通过代码来观察。然后我就简单的写了一个测试程序
#include <stdio.h> int main(){ int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; printf("a[1]'s address is %d\n", a + 1); printf("%d\n", a + sizeof(int)); printf("%d\n", &a[0] + 1); printf("%d\n", (int *)&a + 1); printf("%d\n", (int *)((char *)&a + sizeof(int))); return 0; }
编译运行之后结果是这样的:
[root@Alston c]# ./findA1 a[1]'s address is 1280393332 1280393344 1280393332 1280393332 1280393332很明显的可以看出A选项的问题了,使用sizeof之后,其实是相对数组首地址有了4个偏移量,而每一个偏移量的值是4字节。
其实这是个很容易让人产生混淆的情况,杜对于指针来说,a+1才是a[1],而a+sizeof(int)偏移了sizeof(int)【注1,根据系统架构不同,int所占字节数会不同】个地址。
分析了这个之后,让我们来看看剩下的三个。
B:&a[0]+1
对数组第一个元素取地址之后,然后加上一个偏移量。符合!
C:(int*)&a+1
对数组a取首地址,然后强制转换成int *类型,刚好数组a定义就是int型的,所以指针类型是匹配的,1个单位的偏移量相同,符合!
D:(int*)((char*)&a+sizeof(int))
这个稍微有点复杂,我们分开来看
(char *)&a,对数组a取首地址之后,强制转换成为char *类型,注意,此时指针变量变成了char *,一个偏移量就只有一个字节了。
(char *)&a+sizeof(int),此时我们忽略注1的内容,就把int当做4个字节来对待,此时的地址刚好相对于数组首地址偏移4个字节,而不是4个偏移量!!!这里要注意
(int*)((char*)&a+sizeof(int)), 最后将后面那一块的地址强制转换成int *,刚好指向相对数组首地址4个字节的位置,也就是a[1]的位置。
分析完了,感觉面对这种带有很多转换的情况,我们需要拆开来看,这样可能会比较容易明白。
相关文章推荐
- 一个看似简单的数字交换问题
- C语言用数组1. 简单约瑟夫环问题: N个人,编号从1~N围成一圈,输入一个数T,从1号开始报数,报到T的人出圈;下一人又从1开始报数,下一个报到T的人出圈,输出出圈顺序。 考虑问实现约瑟夫环问题
- i++不是原子操作,看似简单,实则巨坑的一个线程同步的问题。synchronized 和 volatile
- 分布式消息队列RocketMQ&Kafka -- 消息的“顺序消费”-- 一个看似简单的复杂问题
- 分布式消息队列RocketMQ&Kafka -- 消息的“顺序消费”-- 一个看似简单的复杂问题
- 三维数组A和一个简单c问题
- [睡前灵感and发散思维]由一个简单的数组比较问题而想到的
- VC++下一个看似简单实则很有“内涵”的C/C++字符数组初始化问题
- 分布式消息队列RocketMQ&Kafka -- 消息的“顺序消费”-- 一个看似简单的复杂问题
- 分布式消息队列RocketMQ&Kafka -- 消息的“顺序消费”-- 一个看似简单的复杂问题
- 一个看似简单的问题(#if与#ifdef的区别)
- boj 1347 简单数组问题 在一个二维数组中 a[i][j]=a[i][j]+a[i-1][j]+a[i][j-1]-a[i-1][j-1] 则a[i][j]为i j位置左上侧所有元素之和
- 数组名及数组名的地址(还有一个小问题没解决)
- java:一个看似简单的问题,判断double是否为整数
- 分布式消息队列RocketMQ&Kafka -- 消息的“顺序消费”-- 一个看似简单的复杂问题
- 一个看似简单却复杂的问题:求两个字符串的 左向右匹配 所有的 最长连续的 公共子字符串( 在每个字符串中先后次序相同的) 序列
- HashMap与Hashtable的区别是面试中经常遇到的一个问题。这个问题看似简单,但如果深究进去,也能了解到不少知识。本文对两者从来源、特性、算法等多个方面进行对比总结。力争多角度、全方位的展示二者的不同,做到此问题的终结版。
- 发一个非常简单的效果,是在浏览器里面上下左右都居中的问题
- 一个简单HashTable实现,哈希函数求模取余,链地址解决冲突
- 关于S5PV210的启动问题和u-boot分析并自己实现一个简单的boot(一)