2012-06-07 18 views
0

當我們想通過函數改變普通變量的值時,我們使用call by reference來傳遞它。但是當我們必須通過refence傳遞一個指針變量(如二叉樹的節點)時,我無法理解錯綜複雜的情況。我明白如果我們想修改poiter變量指向另一個節點,我們必須使用引用調用。但是如果我們必須修改根的數據元素呢。我認爲要改變它,我們也需要通過引用來打電話。但是,下面的代碼片段提供了10,10,10的輸出,即使我已經通過函數modifyTree中的值調用傳遞了樹的根節點。我在這裏錯過了什麼嗎?在處理二叉樹時按值調用vs通過引用調用

#include<stdio.h> 
#include<stdlib.h> 


struct node 
{ 
int data; 
struct node* left; 
struct node* right; 
}; 

/* Helper function that allocates a new node with the 
given data and NULL left and right pointers. */ 
struct node* newNode(int data) 
{ 
struct node* node = (struct node*)malloc(sizeof(struct node)); 

node->data = data; 
node->left = NULL; 
node->right = NULL; 
return(node); 
} 

/* This function sets the data fields of some of the nodes of tree to 10*/ 
void modifyTree(struct node* node) 
{ 

node->data = 10; 
node->left->data = 10; 
node->right->data = 10; 
} 

int main() 
{ 
struct node *root = newNode(1); 
root->left   = newNode(2); 
root->right   = newNode(3); 
root->left->left  = newNode(4); 
root->left->right = newNode(5); 

modifyTree(root); 

printf("%d\n", root->data); 
printf("%d\n", root->left->data); 
printf("%d\n", root->right->data); 

getchar(); 
return 0; 
} 
+1

'modifyTree(struct node * node)':所以你*將一個指向'root'節點的指針傳遞給'modifyTree'。所以它*是一個'通過引用調用'。 – ArjunShankar

+0

我已經傳遞了根元素作爲modifyTree(root)而不是像modifyTree(&root)。所以這是一個價值的呼叫。 – Prateek

+0

C不支持按引用進行呼叫。指針與C++中的引用不完全相同。請參閱http://c-faq.com/ptrs/passbyref.html。 –

回答

1

您按值傳遞指針,但指針仍指向相同的東西。我會用一些假設值來演示。

main中,您分配了一個新的struct node。假設它在內存位置0x12345處創建。所以現在你的struct node *root包含0x12345。您可以撥打modifyTree(root);root通過值通過root參數modifyTree

root現在包含0x12345它指向相同的內存位置。

因此,當您使用node->data = 10訪問該位置時,您正在訪問您在main中創建的相同內存。

3

通過傳遞值的指針指被調用的函數接收完全相同的指針值所使用的呼叫者,所以任何訪問通過該指針將是指相同的存儲器。

如果您希望函數修改指針的值(例如通過分配新樹,從而「創建」新的指針值),您將需要雙指針。

+1

相關:http://c-faq.com/ptrs/passptrinit.html –

0

您通過值yes傳遞指針,但是您在modifyTree函數內部正在更改的是指針所指向的結構的元素。按值傳遞指針將不會阻止您更改參數指向的結構的內部內容。如果是你正在改變的指針本身,那麼你會看到你期待的行爲。