C++ 无法从';int*';至';int[]和#x27;?

C++ 无法从';int*';至';int[]和#x27;?,c++,c,pointers,C++,C,Pointers,我知道这可能是一个常见的问题,但我已经尝试过搜索,但仍然找不到明确的答案 我有以下代码: int* f() { int a[] = {1,2,3}; return a; } int main() { int a[] = f(); // Error here getch(); return 0; } 此代码生成错误消息:“无法从'int*'转换为'int[]”” 我发现这很奇怪,因为我读到指针和数组是相似的。例如,我们可以使用[i]代替*(a+i)。

我知道这可能是一个常见的问题,但我已经尝试过搜索,但仍然找不到明确的答案

我有以下代码:

int* f() {
    int a[] = {1,2,3};
    return a;
}

int main() {

    int a[] = f(); // Error here

    getch();
    return 0;
}
此代码生成错误消息:“
无法从'int*'转换为'int[]”

我发现这很奇怪,因为我读到指针和数组是相似的。例如,我们可以使用[i]代替*(a+i)。
有人能给我一个清楚的解释吗?

int*和int[]相似但不同。
int*是一个实指针,而int[]是一个数组引用(一种指向数据开头的“常量指针”),不能修改。因此,int*可以像int[]一样受到威胁,但不能像int[]那样受到威胁。

这段代码中实际上有两个错误

首先,您要返回一个临时数组(f中的int数组)的地址,因此在函数返回后,它的内容是未定义的。任何访问返回指针指向的内存的尝试都将导致未定义的行为

第二,C++中指针的数组类型没有隐式转换。它们相似,但不完全相同。数组可以衰减为指针,但它不能反过来工作,因为信息会在过程中丢失—指针只表示内存地址,而数组表示连续区域的地址,通常具有特定的大小。此外,您也不能分配给数组

例如,我们可以使用[i]代替*(a+i)


然而,这与数组和指针之间的差异关系不大,它只是指针类型的语法规则。当数组衰减为指针时,它也适用于数组。

类型
int[]
实际上并不存在

定义和初始化数组时,如

int a[] = {1,2,3};
编译器对初始值设定项中的元素进行计数,并创建大小合适的数组;在这种情况下,它神奇地变成:

int a[3] = {1,2,3};
int[]
用作函数的参数,它只是普通的
int*
,即指向数组第一个元素的指针。没有携带任何其他信息,特别是关于尺寸的信息没有保留。当您返回指针时,情况也是如此

请注意,数组不是指针:指针可以更改为指向其他内容,而数组总是指向同一内存;指针不知道它指向的内存空间有多大,而数组的大小总是在编译时知道的。在许多情况下,数组会衰减为指向其第一个元素的指针,而将其传递给函数/从函数返回则是其中的一些情况,这一事实导致了混淆

那么,为什么你的代码不起作用呢?有两大错误:

  • 您正在尝试用指针初始化数组。我们说过,
    int*
    不包含任何关于数组大小的信息。它只是指向第一个元素的指针。因此,编译器无法知道应该使
    a
    多大,以容纳
    f()
    返回的内容

  • f
    中,返回指向该函数本地变量的指针。这是错误的,因为指针实际上并不存储数据,它只指向存储数据的位置,即在您的情况下指向
    a
    local to
    f
    。由于该数组是函数的本地数组,因此当函数退出时(即在
    返回时
    ),该数组将不再存在

    这意味着你返回的指针指向不再存在的东西;考虑代码:

    int * a = f();
    
    此初始化有效,您可以稍后在函数中尝试使用
    a
    ,但
    a
    将指向不再存在的
    f
    数组;在最好的情况下,你的程序会崩溃(你会立即注意到你做错了什么),在最坏的情况下,它会运行一段时间,然后开始给出奇怪的结果


  • 您可以互换使用
    a[b]
    *(a+b)
    ,因为当
    a
    b
    中的一个是指针,而另一个是整数或枚举类型时,
    a[b]
    就是这样定义的


    注意:这也意味着像
    42[a]
    这样的表达完全合法。人类读者可能会强烈反对,但编译器不会对此视而不见

    “a[i]而不是*(a+i)”对于不是char的数组,这是不正确的。可能
    *(a+sizeof(a[0])*i)
    。不确定是否在所有情况下都正确。@hexa:
    a[i]=*(a+i)
    是一个始终为真的标识,除非
    a
    的类型不完整或
    void*
    。数组不是指针,指针不是数组。我建议您阅读本手册第6节。提示:选择“一次一节”。@hexa:该标识即使对于
    char
    以外的类型也是正确的;您没有考虑指针算法是如何工作的。这里没有人提到,但您可能希望使用
    向量
    返回值。
    int[]
    不是常量指针。我建议您阅读本手册第6节。@pmg:我试图修改我的答案。请看一下。有时候我用英语写作还是有一些问题。现在好多了。。。如果不是因为那里有“引用”,LOL,但我认为那是C++的东西: