C++数组指针!

学习C++数组的时候,对数组的了解不是很深。也不知道,为什么声明一个数组,int a[10],为什么a就是数组的地址。

你可以这样理解,将a理解为指向数组头的一个指针,这样就好理解了。理解了之后确实好像豁然开朗的样子。这样a[5]就等于*(a+5),也就相当于将数组头指针向后推5个位置,然后取到该位置的数据了。仿佛一切都很完美。

可是当我对C++使用的越多的时候,就会发现这个理解越来越多纰漏。

我们知道,如果我们有一个int数组a[10],sizeof(a)会求出40。相信不少人都会写过以下的代码吧

int arraySize(int a[]) {

    return sizeof(a)/sizeof(int);

}

我们想要求一个数组的长度,但是当我们用这个函数来求数组的长度的时候,会发现要么输出1要么输出2。为什么会这样呢?

我们在C++面试的时候会遇到这样的题目

int a[5] = {1,2,3,4,5};

int* p1 = (int*)(&a+1);

int* p2 = (int*)(a+1);

cout << *(p1-1) << " " << *(p2-1) << endl;

问输出什么?

大家都知道输出时5和1,那大家有没有尝试去理解一下为什么是这样呢?

为了解决这个问题,我写了一段代码进行测试:

#include<iostream>

#include <typeinfo>

using namespace std;

#define type(a) typeid(a).name()

int main() {

int a[10] = {1,2,3,4,5,6,7,8,9,10};

cout << "a=" << a << " &a=" << &a << endl;

int* p1 = (int*)(&a+1);

int* p2 = (int*)(a+1);

cout << "*(p1-1)=" << *(p1-1) << " *(p2-1)=" << *(p2-1) << endl;

cout << "sizeof(a)=" << sizeof(a) << " sizeof(&a)=" << sizeof(&a) << endl;

cout << "TypeOf(a)=" << type(a) << " TypeOf(&a)=" << type(&a) << endl;

}

运行结果如下:

我们可以看到,一个数组a[10],a的值和&a输出的值是一样的。

但是对a+1和对&a+1却会得到不同的结果。

对他们分别用sizeof函数取大小,发现a占用了40个字节,&a占用了8个字节。

最后我们查看a和&a的类别,发现a是A10_i类型的,而&a是PA10_i类型的。

这说明了什么?

说明了数组名a并不是一个int型的指针,而是一个新的数据类型,是一个A10_i类型,代表大小为10的int型的数组。而A10_i这个数据类型是会在内存中连续占用10个int型的空间,所以sizeof(a)会返回一个10*4的结果。而&a是一个PA10_i类型,就是指向A10_i数据类型的一个指针,一个指针的大小当然为8了。(根据系统的位数不同而不同)。

那为什么a和&a的输出值相等呢?这是因为a是一个A10_i的数据类型,输出的时候会把里面的数组的头地址输出出来。而&a时指向A10_i的一个指针,A10_i的地址就等同于他里面包含数组的头地址,所以两者会相等。

而&a+1与a+1得到的结果不相等,是因为a相当于一个指向int元素的指针,a+1会加上sizeof(int)的大小。而&a是一个指向A10_i的指针,&a+1会加上sizeof(A10_i)的大小,而sizeof(A10_i)=40,所以就可以解释为什么两者不同了。

至于为什么我们想写一个函数来求数组的长度的时候会失败,原因是我们的函数接收参数是一个真真正正的int型指针,在传入参数时会进行类型转换,将PA_i类型转化为int型指针,对int指针进行sizeof当然求得指针本身的大小。只有对数组名这个数据类型进行sizeof求大小才能够求得数组本身的大小。

说到底,就是数组名并不等同于一个指针。数组名是一个我们平常不能显式声明的数据类型,只不过里面包含了一个指针,指向数组的头部。

“我是一名从事了10年的老程序员,最近我花了一个月整理了一份最适合2020年学习的c/c++项目实战以及基础教程干货,送给每一位编程小伙伴,这里是小白聚集地,欢迎初学和进阶中的小伙伴。工作需要、感兴趣、为了入行、转行需要学习C/C++的伙伴可以跟我一起学习,技术大牛、学习资料助你早日成为一名优秀的程序员,想要学习更多知识可以关注我哦!
官方企鹅群:720168573

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值