【问题标题】:Changing values in an array from a pointer?从指针更改数组中的值?
【发布时间】:2014-01-07 16:35:01
【问题描述】:

我一直在使用指针来帮助更好地理解。我已将a 声明为指向长度为3 的整数数组的指针,并将b 声明为长度为3 的整数数组。然后我将a 指向b

int main()
{
    int (*a)[3];
    int b[3] { 2, 4, 6 };
    a = &b;
    a[0][0] = 8;
    // This prints out 8 and 8.
    std::cout << a[0][0] << "\t" << b[0];

    // This prints out 0x28fecc and 8.
    std::cout << a[0] << "\t" << b[0];

    return 0;
}

要通过指针a 访问b 的元素,我必须做a[0][0],就好像a 是一个数组数组一样。这与使用 new 关键字声明指向整数数组的指针相比,我可以在其中输出 c[0]

int* c = new int[3] { 2, 4, 6 };
std::cout << c[0];

这是为什么?

非常感谢, 乔治

【问题讨论】:

  • 啊,所以c指向的是数组的第一个元素(是整数),而不是数组的地址?我了解(在此示例中)该数组是内存中顺序的整数序列。数组本身是否有地址? (我假设数组的地址是它的第一个元素的内存地址)?
  • 是的,数组有地址,和第一个元素的地址是一样的。但是指向数组的指针与指向int(或其他)的指针的类型不同,因此您需要不同的语法来通过它访问数组元素。
  • 帮自己一个忙:下次你想写类似int (*a)[3];的东西时,离开键盘一会儿,重复“我在写 C++ 而不是 C,所以我不需要做那种丑陋的事情。”大约十几次,只有当你确信简单是好的时,才回来写你真正想要的东西(我很确定这会有所不同)。
  • 第一个元素的地址和数组相同。 c 是指向 int 的指针,因为它是这样说的:int* c,与初始化的 RHS 上的内容无关。 new 返回指向数组(或第一个元素)的指针,并且在许多情况下,数组本身衰减 为指向其第一个元素的指针。幸运的是,您不必在现代 C++ 中处理这类事情。
  • 查看cdecl.org 是否可以在您的手机上运行 :)

标签: c++ arrays pointers iostream


【解决方案1】:

我必须将 a[0][0] 当作 a 是一个数组数组。

确实,a 是一个指向数组的指针,所以数组本身就是*a,数组的第一个元素就是(*a)[0],或者等价的a[0][0]

您可能希望a 成为指向数组第一个元素的指针(就像c 是指向动态数组第一个元素的指针一样):

int * a = b;

现在a[i] 将是数组的元素i,正如预期的那样。

【讨论】:

  • @GeorgeRobinson:是的。 a[i] 等价于*(a+i),所以a[0] 等价于*a
【解决方案2】:

a 是一个指向单个数组的指针,所以你真的应该使用(*a)[0]。而当您执行a[0] 时,这与*a 相同,因此您将获得数组,该数组在输出中衰减为一个指针,这就是您看到打印地址的原因。

c 是一个指向整数的指针,并且已知指向数组的第一个元素,所以简单的数组表示法有效。

【讨论】:

    【解决方案3】:

    a 的正常声明是

    int *a;
    

    那么你可以使用

    a = b;
    std::cout << a[0];
    

    将打印

    8
    

    【讨论】:

    • 因此 a 被声明为一个指向整数的指针,该整数分配给数组 b 的索引 0 处的元素的地址。那么我们如何在指向整数的指针上使用 [0] 呢?编译器是否执行整数运算? std::cout
    【解决方案4】:

    这是因为你定义了另一种类型。再考虑一个语句

    int* c = new int[3] { 2, 4, 6 };
    

    在左边你使用 int *c。所以你可以为你的本地数组写同样的内容

    int *a;
    int b[3] { 2, 4, 6 };
    a = b;
    

    在这种情况下,您只需使用一个下标即可访问数组的每个元素:

    a[0] = 8;
    

    在这个表达式语句中

    a = b;
    

    数组 b 被隐式转换为指向其第一个元素的指针,即右侧的子表达式 b 的类型为 int *

    【讨论】:

      【解决方案5】:

      声明反映使用。

      b 被声明为int b[3];您以b[0] 访问(的第一个元素)。

      a 被声明为int (*a)[3];等效访问权限为(*a)[0]

      如果你分解那个“等效访问”,你可以看到它有两个操作。首先,它使用解引用运算符“一元星”——*a。记住,a 本身就是一个指针。取消引用 a 返回指向的值。所以一次a = &amp;b,然后*a == b

      那么a[0][0] 是怎么回事?好吧,数组访问运算符[] 实际上适用于一般指针(而且,更奇怪的是,数组“衰减”为指针)。 a[N] 在 C 中定义为与 *(a + N) 完全相同;所以a[0] 是我们已经讨论过的*a。基本上,在这种情况下使用a[0][0] 而不是(*a)[0] 是使用基于运算符[] 定义的双关语来隐藏应反映使用的声明。

      【讨论】:

        猜你喜欢
        • 2021-04-09
        • 1970-01-01
        • 2020-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多