【问题标题】:The increment of a pointer does not work. It's quite hard for me to understand what's what指针的增量不起作用。我很难理解什么是什么
【发布时间】:2021-05-30 21:18:02
【问题描述】:

我最近学习了一些 C++ 指针的基础知识。所以我知道数组的名称只是一个默认设置为数组第一个位置的指针。而且我真的不明白为什么第一个代码可以正常工作,而第二个代码显示错误:tab = tab+1;

你能解释一下为什么它如此模棱两可吗?

#include <iostream>
int main()
{
    int *tab;
    tab = new int[5] {0, 1, 2, 3, 4};

    for(int i=0; i<5; i++)
    {
        std::cout << *tab << std::endl;
        tab++;
    }

    delete []tab;
}
#include <iostream>
int main()
{
    int tab[5] = {0, 1, 2, 3, 4};

    for(int i=0; i<5; i++)
    {
        std::cout << *tab << std::endl;
        tab = tab+1; // ERROR
    }
}

【问题讨论】:

  • “我知道数组的名字只是一个指针”。这是错误的。
  • 数组不是指针,指针也不是数组。例如,当传递给函数时,数组确实会衰减到指向第一个元素的指针,但 tab 是一个数组
  • 我实际上讨厌“衰减到指针”的措辞 - 我相信说朴素的数组实际上衰减到 address - 第一个元素的地址更准确。并且 address 不是左值 - 地址不是可以放入值的内存块 - 地址 is 是一个值。至于“数组是指针” - 再次,不。数组是实际内存的块,具有一个有效的地址 - 数组存在。指针是保存地址的变量 - 指针中保存的地址可能有效也可能无效。
  • @AndrewHenle 好吧,标准将其称为“指针衰减”(12)。通常我看到“地址”被用来指代指针对象的值,就像“数字”是算术类型的对象的值一样。所以“衰减到指针”在我的书中是可以的,如果你记住所说的指针是一个纯右值。 “指针是变量” 有了这样的措辞,int *x[5]; 就不是一个“指针”数组,因为元素不是变量,而仅仅是对象。
  • @HolyBlackCat 是的,但我试图简化解释。 ;-)

标签: c++ pointers types increment


【解决方案1】:

第一个代码“有效”,因为tab 被声明为实际指针,您可以为它分配另一个指针。但是代码也失败了,因为当delete[] 被调用时,由于tab 不再指向new[] 返回的原始内存,它具有未定义的行为。

第二个代码不起作用,因为tab 被声明为数组,而不是指针。它在需要时衰减为指针,但不能将指针分配给数组。

【讨论】:

    【解决方案2】:

    所以我知道数组的名称只是一个默认设置为它的第一个位置的指针。

    没有。那是错的。数组不是指针,指针也不是数组。

    因为数组可以衰减到它的第一个元素的地址,你可以写int* tab_ptr = tab; 来获得指向第一个元素的指针:

    #include <iostream>
    
    int main()
    {
        int tab[5] = {0, 1, 2, 3, 4};
        int* tab_ptr = tab;
        for(int i=0; i<5; i++)
        {
            std::cout << *tab_ptr << std::endl;
            tab_ptr = tab_ptr+1;
        }
    }
    

    而且由于数组在传递给函数时会衰减到其第一个元素的地址,因此您也可以这样做:

    #include <iostream>
    
    void foo(int t[]){
        for(int i=0; i<5; i++)
        {
            std::cout << *t << std::endl;
            t = t+1;
        }
    }
    
    int main()
    {
        int tab[5] = {0, 1, 2, 3, 4};
        foo(tab);
    }
    

    当你写 tab = tab+1 时,你会得到错误:

    <source>:23:13: error: incompatible types in assignment of 'int*' to 'int [5]'
       23 |         tab = tab+1;
          |         ~~~~^~~~~~~
    

    因为数组确实衰减到tab+1 中的地址,而tab+1 是一个指针,但您不能将生成的指针分配给数组tab

    第一个版本没有这个问题,因为那里tab确实是一个指向动态数组的指针。

    【讨论】:

    • 好吧,谢谢所有回答,但我对第二个代码有不同的问题。如果我写 *(tab+i) 为什么会起作用?
    • @Quarol 因为tab+i 是指向第 i 个元素的指针。 *(tab+i)tab[i] 相同
    猜你喜欢
    • 2018-08-01
    • 2021-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-19
    • 2013-05-01
    • 1970-01-01
    相关资源
    最近更新 更多