C语言中数组地址强制类型转换为何导致增量结果不同
为什么强制转换数组地址后,&thing+1只加1?
这事儿的核心是指针算术规则和类型转换时机在搞鬼,我给你一步步掰扯清楚:
先搞懂thing和&thing的本质区别
thing是数组名,在绝大多数表达式里会自动「退化」成指向数组第一个元素的指针,类型是int*。&thing是取整个数组的地址,它的类型是int (*)[8]——也就是「指向包含8个int的数组的指针」。
这俩在数值上完全一样(都指向数组的起始位置),但类型天差地别,这就是后面所有差异的根源!
指针算术的核心规则:类型决定增量
当你对指针做+n操作时,编译器不是直接给地址加n,而是会自动计算:n × sizeof(指针指向的类型)。举个例子:
thing+1:thing是int*,指向的类型是int,所以加1会跳sizeof(int)字节(通常是4字节)。&thing+1:&thing是int (*)[8],指向的类型是整个int[8]数组,所以加1会跳sizeof(int[8])字节(也就是8×sizeof(int),通常是32字节)。你看到的输出里差8,大概率是环境特殊或者printf格式符不匹配导致的,但核心逻辑是指针类型决定了增量的步长。
强制转换的坑:时机错了,结果就错了
重点来了!当你写(unsigned long)&thing+1时,运算符优先级决定了执行顺序:
- 先把
&thing这个指针强制转换成unsigned long类型的整数; - 再对这个整数做普通的
+1运算——整数加1当然就是数值直接加1,和原来的指针类型半毛钱关系都没有了!
如果你的意图是先让指针跳一步,再转成整数,那得加括号:(unsigned long)(&thing+1),这样就会先执行指针加法(跳整个数组的大小),再转换成整数,结果就和你第二个分支里的&thing+1数值一致了。
额外提醒:别用%lu输出指针
用%lu输出指针是标准未定义行为,正确的做法是用%p格式符,并且把指针转换成void*,比如:
printf("%p %p\n", (void*)thing, (void*)&thing);
这样输出的指针格式才是符合标准的。
内容的提问来源于stack exchange,提问作者mrigendra
相关产品推荐
相关产品推荐

