1

第一个问题:

很多时候,我们使用指针通过函数调用将一个对象的引用传递给另一个对象。例如:

int num =25;
int *num1Ptr=#
int *num2Ptr=NULL;

void assinNum (int *numPtr){

    num2Ptr = numPtr; ////we copy the value (address) of the num1Ptr pointer to num2Ptr
}

我的问题是:如果这样的方法被非常频繁地调用,我们可以预期指针复制的显着开销吗?

第二个问题:

在下面的场景中,是否意味着我们将传递的 numPtr 指向的内存地址中的值复制到 num2Ptr 指向的内存地址?如果是,那么它是否与按值传递相同?

int num =25;
int *num1Ptr=#
int *num2Ptr=NULL;

void assinNum (int *numPtr){

    *num2Ptr = *numPtr; ////num2Ptr points to the same value in the memory pointed by numPtr argument. 
}

第一个问题的更新:

指向大对象(不是原语)的指针有什么后果?

4

4 回答 4

3

如果这样的方法被非常频繁地调用,我们可以预期指针复制的显着开销吗?

指针通常只是一个 32 位或 64 位的数量。所以复制指针只涉及复制一个 32 位或 64 位的数量,这在大多数平台上都非常便宜。但是,直接复制一个int也很便宜,所以在这种情况下,使用指针可能不会给您带来太多好处。

还值得指出的是,在很多情况下,编译器会通过内联来优化这个函数。

这是否意味着我们将传递的 numPtr 指向的内存地址中的值复制到 num2Ptr 指向的内存地址?

理论上,是的。但是,,num2Ptr = NULL所以你的代码很可能会导致分段错误。

那么它与按值传递相同吗?

我不确定你指的是什么,所以很难知道如何回答这个问题!

于 2013-01-18T20:30:38.437 回答
2

如果这样的方法被非常频繁地调用,我们可以预期指针复制的显着开销吗?

“开销”意味着您正在将一些可选的或虚假的工作量与实际需要完成的工作量进行比较,以实现特定的预期效果。总工作量与最低所需工作量之间的差异是开销。在这种情况下,不清楚您的基线是什么。您认为开销是多少?将一个指针复制到另一个指针的操作非常小——它只是一个 32 位或 64 位分配,具体取决于您的目标平台。这样的操作不是免费的,但速度非常快。

传递的 numPtr 指向的内存地址到 num2Ptr 指向的内存地址?

是的,您显示的代码将引用的内存中的值复制到引用numPtr的内存中numPtr2。当然,在您的示例中,指针分别引用地址 0x00000019 和 0x00000000,因此除非您知道那里有可读内存,否则在读取源值时会崩溃;除非您知道那里也有可写的内存(而且您可能没有),否则在写入时会崩溃。请注意,您的评论 ( ////num2Ptr points to the same value in the memory pointed by numPtr argument.) 不正确。

如果是,那么它是否与按值传递相同?

传递指针不像按值传递。指针是对数据的引用,而不是数据的值。(当然,指针本身是按值传递的,但您应该取消引用它。)由于指针是可写的,您可以对其进行写入,调用者将在其返回时看到这种写入的效果。

于 2013-01-18T20:38:03.703 回答
1

我的问题是:如果这样的方法被非常频繁地调用,我们可以预期指针复制的显着开销吗?

用于复制sizeof(int*)?不可以。但是,对于函数调用,可能会有很大的开销,尤其是如果调用是通过 PLT 执行的。在多线程环境中,这会间接引入其他开销。

在下面的场景中,是否意味着我们将传递的 numPtr 指向的内存地址中的值复制到 num2Ptr 指向的内存地址中?

是的。

如果是,那么和传值一样吗?

不。按值传递整数更快,主要是因为按值传递不涉及读取内存,而是通过寄存器完成。

于 2013-01-18T20:33:04.457 回答
1

指针复制成本非常低,但对于指针大小与存储数据一样大或更大的原始数据类型几乎没有意义。

对于您的第二个问题,您正在应对价值,并且与按价值应对相同。

于 2013-01-18T20:33:18.030 回答