繁体   English   中英

这是在C中不是通过引用进行调用的有效示例吗?

[英]Is this a valid example of call by reference not being true in C?

#include <stdio.h>


void changePtr(int* ptr) {

printf("Value of ptr is %d, address is %d \n" , *ptr,&ptr);
int b = 50;
ptr = &b;
printf("Value of ptr in function changePtr is %d, address is %d  \n", *ptr , &ptr);

}


int main() {

int a = 10;
int* ptr;
ptr = &a;
changePtr(ptr);
printf("Value of ptr in main is %d, address is %d  \n", *ptr,&ptr);
return 0;
}

这是输出

Value of ptr is 10, address is 13368768
Value of ptr in function changePtr is 50, address is 13368768
Value of ptr in main is 10, address is 13368980

在这里,当我以ptr作为参数调用函数changePtr时,函数changePtr本身不接收指针,而是main()中ptr的值,而函数changePtr中的变量ptr是一个全新的指针,可以复制从main()接收的指针ptr的值。

如果C支持按引用调用,则下面两行的输出将匹配。

如果C支持引用调用,.....

C没有为函数参数传递通过引用传递的概念。 参数始终使用按值传递。

我们可以通过将指针传递给对象并从被调用函数内部操纵指针所指向的地址处的值来实现按引用传递的类似行为,但是指针本身将通过值传递。

这意味着,如果必须从被调用的函数本身更改指针 ,则应将指针发送到该指针变量以实现该目的。 请参考此答案以获取一个不错的代码示例。

您正在传递一个指针。 该指针按值传递。 即,将指针本身复制为该函数。 因此,当您在其他位置的函数点内创建ptr时,仅在更改指针的本地副本。

如果要更改指针指向的位置的值,则需要使用解引用运算符*

void changePtr(int* ptr) {
    *ptr = 50;
}

这将模拟通过引用。


如果您改为将指针传递给指针变量(模拟通过引用传递指针),则类似于以下程序(简化版)

void changePtr(int** ptr) {
    int b = 50;
    *ptr = &b;
}

int main() {
    int a = 10;
    int* ptr = &a;
    changePtr(&ptr);
    printf("Value of ptr in main is %d, address is %p\n",*ptr, (void *) &ptr);
    return 0;
}

实际上,这更糟,因为在changePtr调用之后,指针指向changePtr函数内部的局部变量,该变量已超出范围且不再存在。 使用指针时,这导致未定义的行为

不它不是。 您要做的是按值传递指针(a的地址)。 调用该函数时,将创建一个新指针,其中包含旧指针ptr的值。 此值是a的地址。 更改功能ptr时,主ptr不会更改,因为它们的位置不相同。 他们只是指向同一个元素。

标识符ptr本身就是一个指针,除非您告诉它应该指向哪种类型,否则它是没有意义的,即

int *ptr;  //says  int <- *ptr or *ptr is an integer

changePtr(ptr); // You pass pointer by value

和在

void changePtr(int* ptr) 
/* you caught the argument 'ptr' from main
 * using the function parameter 'ptr'
 */

所以

ptr_from_mainptr_from_funtion包含相同的值,即从示例中获取的13368980

您在后面的printf语句中犯了一个错误,没有使用格式说明符%p来打印地址,应该是

printf("Value of ptr is %d, address is %p \n" , *ptr,&ptr);

同样,您应该使用ptr代替&ptr来使示例更有意义,即

printf("Value of ptr is %d, address is %p \n" , *ptr,ptr);
/* Would give you
 * Value of ptr is 10, address is 13368980
 */

每个指针确实是一个确实具有地址的对象,因此&ptr为您提供指针的地址而不是其值(记住value确实是一个地址:))


要在C ++中通过引用模拟调用,您需要完全重写程序。

#include <stdio.h>
void changePtr(int** ptr) // Here pointer<-*ptr  & integer<-**ptr;
{
printf("Value of ptr is %d, address is %p \n" , **ptr,*ptr);
int b = 50;
*ptr = &b; // You've just changed the value of ptr in main
printf("Value of ptr in function changePtr is %d, address is %p  \n", **ptr , *ptr);

}


int main() {

int a = 10;
int* ptr;
ptr = &a;
changePtr(&ptr); // Pass the address
printf("Value of ptr in main is %d, address is %p  \n", *ptr,ptr);
return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM