C++一些奇怪题目收集

一、数组名的问题

从网络上看到这样一道有意思的题目,是关于数组与指针的问题,描述如下:
main()
{
    int a[5]={1,2,3,4,5};
    int *ptr=(int *)(&a+1);       //a类型是指向一个元素,而&a类型是指向一行
    printf("%d,%d",*(a+1),*(ptr-1));
}
输出为:2,5
请解释以上代码的输出结果。

答案如下:
*(a+1)其实很简单就是指a[1],输出为2.
问题关键就在于第二个点,*(ptr-1)输出为多少?
解释如下,&a+1不是首地址+1,系统会认为加了一个整个a数组,偏移了整个数组a的大小(也就是5个int的大小)。所以int *ptr=(int *)(&a+1);其实ptr实际是&(a[5]),也就是a+5.

原因为何呢?
&a是数组指针,其类型为int(*)[5];

【注意,经过测试&a不是个左值了,是个右值了,也就是个常量了,所以上面说法不完全对,&a不是指针,只是个地址值,但任何数值也都是有类型的,比如5.0或1.234都是double型的。既然&a是个数组这种数据结构类型的一个值,那么它的算术运算也就按这种类型的要求计算了,所以+1就是加了整个数组的长度。】

【虽然a和&a这两个东西的值都是一样的,都等于数组第一个元素的首地址值,但这两个东西的类型不一样,甚至这两个东西一个是左值即变量,一个是右值是常量。其实,不仅是数组名,函数名也和这个类似。】

而指针加1要根据指针类型加上一定的值,不同类型的指针+1之后增加的大小不同,a是长度为5的int数组指针,所以要加5*sizeof(int),所以ptr实际是a[5],但是ptr与(&a+1)类型是不一样的,这点非常重要,所以ptr-1只会减去sizeof(int*),a,&a的地址是一样的,但意思就不一样了,a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5]。

【总结:以后不管那么多,只需记住:对于a,前面加个&符号也就是&a,则&a的类型比a的类型扩大(比如a指向一个元素,则&a则指向一行元素,对于二维数组若b指向一行元素,则&b指向多行元素);对于a,前面加个*符号也就是*a,则*a的类型比a的类型缩小。】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值