这是一个通过引用调用的有效示例在C中不是真的吗?

时间:2016-08-24 07:51:17

标签: c pass-by-reference pass-by-value

#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的值,以及变量ptr。 function changePtr是一个全新的指针,它复制从main()接收的指针ptr的值。

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

4 个答案:

答案 0 :(得分:2)

  

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

C没有通过引用传递函数参数传递的概念。参数总是使用pass by value传递。

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

这意味着,如果你必须从被调用函数更改指针本身,你应该发送一个指向指针变量的指针来实现它。请参阅this answer以获得一个很好的代码示例。

答案 1 :(得分:2)

你正在传递一个指针。该指针按值传递。即为函数复制指针本身。因此,当你在其他地方的函数点内部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函数内的局部变量,一个超出范围且没有变量的变量更长的存在。使用指针时,这会导致未定义的行为

答案 2 :(得分:0)

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

答案 3 :(得分:0)

标识符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_main&amp; ptr_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给你指针的地址而不是它的值(记住值确实是一个地址:))

要在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;
}