关于c ++和c ++内存模型中基本指针使用的几个简单问题

时间:2011-08-31 06:09:39

标签: c++ pointers dereference

我一直在学习iTunes U上的斯坦福大学课程,并且在C ++方面有所提高。我想我理解指针是如何工作的,但我只想检查如何做一些简单的事情。假设我想创建一个动态数组:

    double *array;

此时堆栈中有一个名为“array”的变量,堆中没有任何内容。第一个问题 - 此时存储在“数组”中的是什么?指向一些无意义内存的指针?

然后我使用“new”分配内存:

    array = new double[10];

第二个问题 - 此时,存储在“数组”中的是什么?指向一些足以容纳10个双打的连续记忆的指针? (抱歉这些简单的问题,但我真的想确保理解)

我将double 2.0分配给数组中的每个元素:

    for(int i=0; i<array.length(); i++) array[i]=2.0;

第三个问题 - 这与使用取消引用运算符分配有什么不同? (即*array[i]=2.0)。然后我将数组传递给其他函数:

    myFunc(double array[]){
        for(int i=1; i<array.length(); i++){
            array[i]=array[i]*array[i-1];
        }
    }

第四个问题 - 关于传递给myFunc,因为数组是指向双精度的指针数组,而不是双精度数组,它通过引用传递而没有“&amp;”,对吧?这意味着我的循环中的操作正在影响存储在“数组”中的实际数据。如果我想通过值传递,那么我就不会触及“数组”中的数据了?我会用

吗?
    myFunc(double *array[]){...}?

最后一个问题 - 如果我出于某种原因想要操作“数组”内容的内存地址怎么办?我可以用

吗?
    someVar = &array[5];

将array [5]的十六进制地址赋给someVar?

我已经阅读了阅读器中有关指针的部分,并观看了Binky视频十几次,但仍然没有意义。任何帮助将不胜感激。

编辑:非常感谢到目前为止回答的所有人。如果你不介意我还有一个问题。在声明double *array;中,“array”被声明为指向double的指针,但是一旦我使用“new”来指定它,“array”就不再是指向double的指针,而是成为double的数组,正确?

3 个答案:

答案 0 :(得分:4)

  1. array包含垃圾数据 - 在array存在之前该内存位置中的任何内容仍然存在。如果你尝试使用它,你就会用脚射击自己,这就是你需要将它分配到有效的记忆位置的原因(因此随后调用new[])。
  2. 是的,array现在包含一个指针(内存地址)到一些连续的内存,足以容纳10个双打。
  3. *array[i]=2.0实际上不会编译。 array [i]产生double,你不能在双引号上使用dereference运算符。
  4. 您传递的是该数组中第一个元素的地址。因此,您通过值传递指针,并通过引用传递数组(因为指针是对数组的引用。)要按值传递数组本身,您必须为每个条目都有一个参数。您也可以复制数组并发送副本,但副本本身也会通过引用传递。
  5. double* someVar = &array[5];将返回指向数组的6 th 元素的指针。 array[5]为您提供了双精度数,并取其地址(使用&)将为您提供该双精度的内存地址(指针)。

答案 1 :(得分:2)

  1. 是的,这就是发生的事情
  2. 绝对是。更具体地说,指向连续内存的开头的指针。
  3. 不是这种情况; *(用于取消引用)是一元运算符,但你已经传递了两个参数。你可以确定它是执行的乘法(或它的重载版本) - 还有,array[i](*array[i-1])是什么意思?你不能取消引用不是指针的东西(或者没有一元*运算符重载)
  4. 您只是按值传递指针而不是数据。如果你想按值传递数据(在函数外部保持不变),你必须先复制它,然后传递(或者只使用vector
  5. 是的,您只是获取连续内存的一部分地址,并且您可以存储地址并在其他地方修改解除引用的值,也可以修改数组
  6. 另外,当你在堆上分配时,你必须要删除内存。在这种情况下,您将使用delete[] array;

答案 2 :(得分:1)

声明后,array变量包含一个仲裁值。你不能用这个值做任何事情。在new之后,它包含一个指向连续内存范围的指针,该内存大小足以容纳10个双精度数。 *array[i]=2.0是一个错误(这意味着该数组是指针的数组加倍)。索引运算符[]只是*(array+i)=2.0的语法糖。

第四个问题:说什么?你没有在该代码中任何地方加倍的指针数组。在函数中,void f(double *x)void f(double x[])是相同的东西:指向double的指针。如果传递给f数组,x将收到第一个元素的地址(这是数组的值)。

您无法按值传递数组。或者,它们总是按值传递(如C中的其他所有),但请注意,数组的VALUE是其第一个元素的地址。

你的最后一个问题:我不知道你想要达到的目的,但问题清楚地表明你很困惑。地址是一个地址,没有“十六进制地址”这样的东西。