2016-08-24 72 views
1
#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; 
} 

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

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 

在这里,当我打电话功能changePtr与PTR,因为它的参数,函数changePtr没有收到指针本身,而PTR的主要价值() ,函数changePtr中的变量ptr是一个全新的指针,它复制从main()接收到的指针ptr的值。

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

+3

C没有参考文献。 – 2501

+0

如果你想使用['printf'](http://en.cppreference.com/w/c/io/fprintf)打印一个指针,你应该使用''%p''格式打印一个' void *'(铸造是必要的)。 –

回答

2

如果C支持通过参考呼叫,.....

C具有由功能参数传递参考没有通的概念。参数始终使用按值传递。

我们可以通过将指针传递到对象和操作在从被调用函数内由指针指出的地址的值实现通过引用通的类似的行为,但随后,指针本身被传递按价值。

这意味着,如果你有一个指针自己从被调用函数的变化,您应该发送一个指针的指针变量来实现这一目标。请参阅this answer以获取更好的代码示例。

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

为了这个例子(pointer-to-pointer〜= by-reference)你可以使它成为'static int b = 50;'来摆脱UB。 – TripeHound

0

不,它不是。你所做的是按值传递指针(a的地址)。当你调用函数时,将会创建一个新的指针,其中包含旧指针ptr的值。这个值是一个地址。当你改变函数ptr时,主ptr不会改变,因为它们在哪里不一样。他们只是指出了相同的元素。

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 & ptr_from_funtion contians在此处的值为13368980,与您的示例相同。

你在下面,不使用格式说明%p用于打印地址printf声明一个错误,它应该是

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为您提供了p的地址ointer不是它的值(记住值是一个地址确实:))


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