关于C++数组名和指针的一些思考

在学习指针数组与数组指针一节时,了解到数组名其实是指向数组收个元素的指针。如下面代码所示

int main() {

    int a[5] = {1, 2, 3, 4, 5};
	cout << "*a:" << *a << endl;
	cout << "*(a + 1):" << *(a + 1) << endl;
	cout << "*(a + 2):" << *(a + 2) << endl;
    
}

在这里插入图片描述

对于int类型的数组a,如果定义一个int* 类型的指针p,可以使用如下语句为指针p赋值

int main() {
    
    ...
        
    int* p = &a[0];
	cout << "*(p + 1): " << *(p + 1) << endl;
	cout << "*(&a[0] + 1): " << *(&a[0] + 1) << endl;
	cout << "&a[0] == p: " << (&a[0] == p ? "true" : "false") << endl;

	p = a;
	cout << "*(p + 1): " << *(p + 1) << endl;
	cout << "*(a + 1): " << *(a + 1) << endl;
	cout << "a == p: " << (a == p ? "true" : "false") << endl;

	cout << "a == &a[0]: " << (a == &a[0] ? "true" : "false") << endl;
    
}

在这里插入图片描述

可以用&a[0]给p指针赋值,也可以用a给指针p赋值,指针p和a都可以进行加法运算,结果也相同;并且a、&a[0]和p做比较都相同。看样子a本质上是一个指向a[0]的int*的指针。但真的是这样吗?看看以下代码

int main() {
    
    ...
        
    cout << "p:" << p << endl;
	cout << "&p:" << &p << endl;
	cout << "a:" << a << endl;
	cout << "&a:" << &a << endl;
	cout << "&a[0]:" << &a[0] << endl;
    
}

在这里插入图片描述

发现p、a、&a的值都是一样的;但是&p与p不相同。因为p是指针变量,&p为变量p的地址,即二级指针。但是a和&a的值是一样的,该怎么理解呢?如果a是int*的指针,那么&a和&p应该是相同的。但结果并不如此,事实上&a被编译器解释为int (*) [5]类型,并且不能通过&a来定义一个int**二级指针。说明不能把a简单的当做一个int*的指针

在这里插入图片描述

我的理解是,指针的本质就是内存地址+数据类型,在解引用时,会根据数据类型来决定读取多大的内存空间,从而生成指定类型的对象。

因此a还是一个int类型的数组,只是在对数组名a操作的时候,某些情况可以隐式数据类型转换为int*的指针。例如在对p赋值时,右值a隐式转化为左值p;并且定义了重载的运算符+/-,使数组a可以像指针一样进行运算。

而a可以看做指向数组首个元素的指针,a的值是数组首个元素的首地址。&a表示指向整个数组的指针,&a的值是指向整个数组的首地址。二者是相同的。因此也解释了a和&相同的情况。

虽然强行解释通了,但总感觉哪里不对。为什么数组名a可以像int*的指针进行操作,而本身并不是一个int*

看了其他同学的理解,感觉很有道理,但还是不清楚C++底层究竟是如何设计的。数组名和指针的深入理解(C++)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值