我创建了这个函数,它应该创建一个随机生成的二叉树,它工作正常,但在函数结束时根 == NULL,我不明白为什么!
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define MAX_B 7
typedef struct _ramo{
int nbanane;
struct _ramo *dx;
struct _ramo *sx;
}ramo;
void creaAlbero(ramo *root, int n){
printf("%dn",n);
root = malloc(sizeof(ramo));
root->nbanane=rand()%MAX_B;
printf("BANANA! %dn",root->nbanane);
root->dx=NULL;
root->sx=NULL;
if ((int)(rand()%n)==0)
creaAlbero(root->dx, n+1);
if ((int)(rand()%n)==0)
creaAlbero(root->sx, n+1);
}
int main(){
srand((unsigned int)time(NULL));
ramo *root=NULL;
creaAlbero(root, 1);
if (root==NULL) {
printf("EMPTY!!");
}
return 0;
}
您将root
设置为 NULL
:
ramo *root=NULL;
然后将它的副本传递给creaAlbero()
:
creaAlbero(root, 1);
修改副本
root = malloc(sizeof(ramo));
然后返回。原来的root
仍然NULL
,因为没有什么改变它。
考虑从creaAlbero()
返回root
:
ramo * creaAlbero(int n){
printf("%dn",n);
ramo *root = malloc(sizeof(ramo));
root->nbanane=rand()%MAX_B;
printf("BANANA! %dn",root->nbanane);
root->dx=NULL;
root->sx=NULL;
if ((int)(rand()%n)==0)
root->dx = creaAlbero(n+1);
if ((int)(rand()%n)==0)
root->sx = creaAlbero(n+1);
return root;
}
int main(){
srand((unsigned int)time(NULL));
ramo *root=NULL;
root = creaAlbero(1);
if (root==NULL) {
printf("EMPTY!!");
}
return 0;
}
示例:https://ideone.com/dXiv8A
creaAlbero(ramo *root, int n)
是一个函数,它复制指向ramo
的指针。 然后,它继续使用此指针副本执行操作,然后返回。 然后main
查找原始root
变量的值,该变量(显然)从未更改过。
如果希望函数修改传入的值,则必须通过指针传递对象。 澄清一下:如果你想让一个函数修改一个指针,该函数必须将一个指向事物的指针作为参数:
void creaAlbero(ramo **rootptr, int n){ //pass rootptr by pointer
*rootptr = malloc(sizeof(ramo)); //modify pointer pointed at by rootptr
ramo* root = *rootptr; //make local copy of value for ease of use
//rest of your code here
}
int main(){
ramo *root=NULL;
creaAlbero(&root, 1); //pass by pointer
Paul Roub 的回答还提出了另一个好主意:从函数返回ramo*
,而不是将其作为可变参数。 到目前为止,它更简单、更直观。
root
按值传递给creaAlbero
。在creaAlbero
中对root
所做的任何更改都只是本地修改。它们不会更改 main 中root
的值。更好的选择是将creaAlbero
的签名更改为:
ramo* creaAlbero(int n){
printf("%dn",n);
ramo* root = malloc(sizeof(ramo));
root->nbanane=rand()%MAX_B;
printf("BANANA! %dn",root->nbanane);
root->dx=NULL;
root->sx=NULL;
if ((int)(rand()%n)==0)
root->dx = creaAlbero(n+1);
if ((int)(rand()%n)==0)
root->sx = creaAlbero(n+1);
return root;
}
并将用法更改为:
int main(){
srand((unsigned int)time(NULL));
ramo *root = creaAlbero(1);
if (root==NULL) {
printf("EMPTY!!");
}
return 0;
}