C:处理指针的方法

我想知道为什么第一种方法不起作用,但第二种方法不起作用:

//第一种方法

int create_node(struct node *create_me, int init){ create_me = malloc(sizeof(struct node)); if (create_me == 0){ perror("Out of momory in ''create_node'' "); return -1; } (*create_me).x = init; (*create_me).next = 0; return 1; } int main( void ){ struct node *root; create_node(root, 0); print_all_nodes(root); } 

好的,这里的print_all_nodes函数告诉我,root还没有被初始化。 现在第二种方法很好:

 struct node* create_node(struct node *create_me, int init){ //<------- create_me = malloc(sizeof(struct node)); if (create_me == 0){ perror("Out of momory in ''create_node'' "); exit(EXIT_FAILURE); } (*create_me).x = init; (*create_me).next = 0; return create_me; //<--------- } int main( void ){ struct node *root; root = create_node(root, 0); //<--------------- print_all_nodes(root); } 

在我的理解中(谈论方法1),当我给create_node函数指向根节点的指针时,它实际上改变了xnext root。

就像你这样做:

 void change_i(int* p){ *p = 5; } int main( void ){ int i = 2; printf("%d\n", i); change_i(&i); printf("%d", i); } 

它实际上改变了i 。 明白了吗? 有人可以和我分享他/她的知识!

你需要一个指向指针的指针,而不仅仅是一个指针。

如果要在另一个函数中更改变量,则必须发送指向该变量的指针。 如果变量是整数变量,则发送指向该整数变量的指针。 如果变量是指针变量,则发送指向该指针变量的指针。

你在问题中说“当我给create_node函数指向根节点的指针时,它实际上改变了x和root的next 。” 你的措辞让我怀疑这里有一些混乱。 是的,您正在更改xnext的内容,但不更改rootroot没有xnext ,因为root是指向包含xnext的结构的指针。 您的函数不会更改root的内容,因为您的函数获取的只是该指针的副本

您的代码更改:

 int create_node(struct node **create_me, int init) { *create_me = malloc(sizeof(struct node)); if (*create_me == 0){ perror("Out of momory in ''create_node'' "); return -1; } (*create_me)->x = init; (*create_me)->next = 0; return 1; } int main( void ){ struct node *root; create_node(&root, 0); print_all_nodes(root); } 

你需要做一些像create_node(&root, 0); 然后在被调用的方法中将其作为**进行访问。 C没有传递参考概念。 您需要提供地址以在另一个函数中访问它。

这是变量范围的问题。 在第一个示例中,您提供指向节点指针 ,您可以更改该节点,之后更改将保持不变。 但是, malloc更改此指针,该指针在作用域(您的函数)结束后将被丢弃。

在第二个示例中,您返回此指针,因此在被丢弃之前复制它。

这将在您给出的示例中对应于此。 3:

 void change_i(int* p){ *p = 5; // you can 'change i' p = 5 // but not p (pointer to i), as it is local -> gets discarded after following '}' } 

当我给create_node函数指向根节点的指针时,它实际上改变了x和下一个root。

没有create_node()函数(在两个版本中)指向根节点的指针,因为您首先没有根节点。

声明:

 struct node *root; 

创建类型为struct node *的变量root ,并使其未初始化。 root是一个变量,它可以将地址存储在struct node value(指向struct node value的指针)的内存中。 但代码不会创建任何struct node值, root的值只是垃圾。

接下来,作为调用的结果,函数create_node()两个版本都在参数create_me接收root的垃圾值:

 create_node(root, 0); 

create_node()的两个实现的第一件事是忽略它们在create_me参数中接收的值(无论是否有效),创建struct node类型的值并将其地址存储在create_me

线条:

 (*create_me).x = init; (*create_me).next = 0; 

将一些值放入新分配的struct node对象的属性中。

然后函数的第一个版本返回1并忽略存储在create_me的值。 作为函数参数(函数的局部变量),其值被丢弃并永远丢失。 代码只是创建了一个内存泄漏:一个已分配但无法访问的内存块,因为没有指向它的指针。 不要这样做!

函数的第二个版本返回create_me的值(即struct node的新分配值的地址)。 调用代码( root = create_node(root, 0); )将函数返回的值存储到变量root (替换用于初始化此变量的垃圾值)。

巨大的成功! create_node()函数的第二个版本创建一个新的struct node对象,初始化其属性并返回要存储和/或进一步处理的新对象的地址。 当不再需要该对象时,不要忘记调用free(root)