【问题标题】:Change pointer to an array to get a specific array element更改指向数组的指针以获取特定的数组元素
【发布时间】:2010-09-11 13:26:47
【问题描述】:

我了解指针和引用的整体含义(或者至少我认为我了解),我也了解当我使用 new 时,我是在动态分配内存。

我的问题如下:

如果我使用cout << &p,它将显示p 的“虚拟内存位置”。 有没有办法可以操纵这个“虚拟内存位置”?

例如,下面的代码显示了一个ints 的数组。

如果我想显示p[1] 的值并且我知道p 的“虚拟内存位置”,我能否以某种方式执行“&p + 1”并通过cout << *p 获得p[1] 的值,哪个现在将指向数组中的第二个元素?

int *p;
p = new int[3];

p[0] = 13;
p[1] = 54;
p[2] = 42;

【问题讨论】:

    标签: c++ pointers


    【解决方案1】:

    当然,您可以操作指针来访问数组中的不同元素,但是您需要操作指针的内容(即 p 所指向的地址),而不是指针本身的地址.

    int *p = new int[3];
    p[0] = 13;
    p[1] = 54;
    p[2] = 42;
    
    cout << *p << ' ' << *(p+1) << ' ' << *(p+2);
    

    每次加法(或减法)表示数组中的后续(前一个)元素。如果 p 指向地址为 12345 的 4 字节变量(例如,典型 32 位 PC 上的 int),则 p+1 将指向 12349,而不是 12346。请注意,您要更改p 在取消引用它以访问它所指向的内容之前包含什么。

    【讨论】:

    • 只是想指出一个 int 的地址将是 4 字节对齐的,所以它不会有地址 12345。:-)
    • 它没有。您只是不想处理变量未正确对齐时出现的所有问题。 :D 理论上,编译器可以忽略对齐,只发出代码来处理访问不正确对齐的变量。
    【解决方案2】:

    不完全是。 &amp;p 是指针p 的地址&amp;p+1 将指代一个地址,该地址是一个int*。你想做的是

    p=p+1; /* or ++p or p++ */
    

    当你这样做时

    cout << *p;
    

    你会得到 54。不同的是,p 包含 int 数组的开始地址,而&amp;pp 的地址 .要移动一个项目,您需要进一步指向 int 数组,而不是进一步指向堆栈,这是 p 所在的位置。

    如果您只有&amp;p,那么您需要执行以下操作:

    int **q = &p; /* q now points to p */
    *q = *q+1;
    cout << *p;
    

    如果我没记错的话,那也会输出 54。

    【讨论】:

    • 如果你的意思是“cout
    • Hrm,我不知道我为什么要 cout
    • 对不起,你是对的。我觉得你得到了 q 很奇怪,开始通过 q 操作它,然后回到使用 p 访问这个东西。
    • 啊,我只是想回答这个问题 :-) 问题是如果他有 &p,他可以访问 p[1]。接受的答案实际上并没有回答问题:P
    【解决方案3】:

    自从我使用指针以来已经有一段时间(很多年)了,但我知道如果 p 指向数组的开头(即 p[0])并且你递增它(即 p++)那么 p 现在将是指向 p[1]。

    我认为您必须取消引用 p 才能获得该值。您可以通过在指针前面放一个 * 来取消引用它。

    所以 *p = 33 将 p[0] 更改为 33。

    我猜要获得第二个元素,你会使用 *(p+1) 所以你需要的语法是:

    cout << *(p+1)
    

    cout << *(++p)
    

    【讨论】:

      【解决方案4】:

      我喜欢这样做:

      &p[1]
      

      对我来说它看起来更整洁。

      【讨论】:

        【解决方案5】:

        将 C 和 C++ 中的“指针类型”想象为在 CPU 内存空间中的字节上叠加一长条逻辑单元行,从字节 0 开始。宽度每个单元格的字节数取决于指针的“类型”。每种指针类型都放置具有不同单元格宽度的行。 "int *" 指针放置一行 4 字节单元,因为 int 的存储宽度为 4 字节。 "double *" 为每个单元格设置一个 8 字节的行; "struct foo *" 指针放置一行,每个单元格的宽度与单个 "struct foo" 相同,不管是什么。任何“事物”的“地址”是保存“事物”的行中单元格的字节偏移量,从 0 开始。

        指针算法基于行中的单元格,而不是*(p+10)”是对“p”之后的第 10 个单元格的引用,其中单元格的大小由 p 的类型决定。如果“p”的类型是“int”,则“p+10”的地址是p后40字节;如果 p 是指向 1000 字节长的结构的指针,“p+10”是 p 之后的 10,000 字节。 (请注意,编译器可以为可能比您想象的更大的结构选择最佳大小;这是由于“填充”和“对齐”。讨论的 1000 字节结构实际上可能每个单元占用 1024 个字节,例如,“p+10”实际上是 p 之后的 10,240 个字节。)

        【讨论】:

          猜你喜欢
          • 2018-12-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多