数组名就是指针?

在学习C/C++的过程中相信有很多同学都听过这句话,“数组名本质上就是指针”,可是你仔细想想不觉得奇怪吗?用一个概念去指另一个概念,那我为什么还需要引入这两个概念?

一、让我门来分析一下为什么会有人这样认为

#include 
int main()
{
    int arr[5]={0};
    std::cout<<"arr's addr is"<

输出结果:arr's addr is0xffffc7cb7928
                  &arr's addr is0xffffc7cb7928

如果你只看输出的内容,你发现地址是一模一样的,所以你就认为数组名就是指针了。我们接着看下面的代码:

#include 
#include 
int main()
{
    int arr[5]={0};
    using T=decltype(arr);
    std::cout<<"T's type is "<

输出结果是:T's type is A5_i

注:A5_i 的含义

        在 GCC 及 Clang 的 typeid().name() 编码中:

        • A5 表示数组(A 表示 array,5 表示长度)。

        • _i 表示元素类型是 int(i 代表 int)。

        • 组合起来:A5_i 就是 int[5]

通过输出结果我们可以看到使用decltype推到出来arr的类型是 int[5],不是指针类型!!!

二、arr和&arr的区别是什么?

我们现在已明确数组名不是指针,那么&arr和arr的本质到底是什么?

#include 
#include 

int main()
{
    int arr[5]={0};
    std::cout<::value<::value<::value<::value<::value<

输出结果: 0
                   1
                   0
                   0
                   1

注:std::is_same 是一个用于比较两种类型是否相同的类型特征(type trait),value 是一个常量表达式,T 和 U 是待比较的类型,如果 T 和 U 相同,返回 true,否则返回 false。

由此可见:arr的类型是一个int[5],而&arr的类型是int(*)[5]。我们已经证实arr确实不是一个指针,但有些时候(比如函数间的参数传递)致数组名确实会退化成指针。

#include 
#include 

template 
void arr_type(T1 t1,T2 t2)
{
    std::cout<<"in arr_type:"<::value<::value<::value<::value<::value<::value<::value<::value<::value<::value<

输出结果:

0
1
0
0
1
in arr_type:1
in arr_type:0
in arr_type:0
in arr_type:0
in arr_type:1

比较一下在main函数和arr_type函数中你就会发现,arr的类型从int[5]变成了int*,证明在函数传递过程中发生了隐式转换,数组名退化成指针。

三、总结

通过以上验证你应该明白了造成大家困惑的原因,数组名就是数组名,它很像指针,但它不是,只是在有时候会隐式转换成指针。你可以这样问自己,如果它是指针那它是什么类型的指针,是int吗?如果是int类型他还是指针吗?如果它是int*,那我用decltype能定义一个int*类型的指针吗?

#include 
#include 


int main()
{
    int arr[5]={0};
    int *tmp=nullptr;
    int a=100;

    using T1=decltype(tmp);
    using T2=decltype(arr);

    T1 ptr1=&a;
    T2 ptr2=&a;//显然T2不是int*,如果是则ptr2可以像ptr1成功被定义

    return 0;
}

你可能感兴趣的:(c++,开发语言,c语言)