二叉树运算之创建二叉树

为什么编译器会出现如下警告?


void Create(BiTree *bt) {//创建二叉树
    char ch; 
    ch = getchar();
    if (ch == '#') { *bt = NULL; }
    else {
        *bt = (BiTree)malloc(sizeof(BiTNode));
        (*bt)->data = ch;
        Create(&((*bt)->lchild));
        Create(&((*bt)->rchild));
    }
}

img

答案参考Chatgpt解答
报错信息提示在第19行取消对*bt的引用时,可能为NULL。这意味着在使用*bt之前需要对其进行NULL检查,以确保其不为NULL。为了解决这个问题,你可以修改代码如下:

void Create(BiTree *bt) {
    char ch; 
    ch = getchar();
    if (ch == '#') {
        *bt = NULL;
    } else {
        *bt = (BiTree)malloc(sizeof(BiTNode));
        if (*bt == NULL) {
            // 处理内存分配失败的情况
            // 可以选择报错、退出程序或其他处理方式
        } else {
            (*bt)->data = ch;
            (*bt)->lchild = NULL;
            (*bt)->rchild = NULL;
            Create(&((*bt)->lchild));
            Create(&((*bt)->rchild));
        }
    }
}

在修改后的代码中,我添加了对malloc返回的指针是否为NULL的检查,以确保内存分配成功。如果分配失败,你可以根据实际需求选择适当的错误处理方式。此外,还初始化了lchildrchild为NULL,以避免未定义的行为。

请注意,修改后的代码仅解决了取消对NULL指针的引用的问题。如果还有其他问题或逻辑错误,你可能需要进一步检查和调试代码。


 
void Create(BiTree **bt) {//创建二叉树 // 这里需要改为二级指针,因为需要把函数里面分配的内存指针带出来,所以需要一个指向指针的针指
    char ch; 
    ch = getchar();
    if (ch == '#') { *bt = NULL; }
    else {
        *bt = (BiTree)malloc(sizeof(BiTNode));
        (*bt)->data = ch;
        Create(&((*bt)->lchild));    
        Create(&((*bt)->rchild));
    }
}

  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7434871
  • 这篇博客也不错, 你可以看下二维数组作为函数的参数进行传值,调用和使用
  • 除此之外, 这篇博客: 为什么要使用二级指针?中的 结论 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 上述就是关于二级指针的相关内容,总体来说,二级指针也是指针,用指针的思想来处理这个问题就好,区别只是在于一级指针是由于存放普通变量的地址的,二级指针是由于存放指针变量的地址的。另外需要注意的就是 C 语言在进行函数调用时,实参的传递采用的是实参值的一份拷贝。如果要在函数内部改变变量的值,就要传入指针,如果要在函数内部改变指针的值,就需要传入二级指针。

  • 您还可以看一下 褚英昊老师的人工智能必备数学知识课程中的 最小二乘法求解线性回归小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    答案:

    对于二叉树创建过程中出现的警告,可能的原因和解决方法如下:

    1.警告:assignment within conditional expression 在while或if条件语句中同时对变量赋值,编译器会发出警告。例如:

    while ((ptr = head) != nullptr) { //这里会提示无括号的扩展且优先级可能出错 .... }

    解决方法:将赋值操作移到外面,例如:

    ptr = head; while (ptr != nullptr) { .... ptr = ptr->next; }

    2.警告:comparison between signed and unsigned integer expressions 在比较有符号和无符号整型表达式时,编译器会发出警告。例如:

    for (int i = 0; i < vec.size(); i++) { //关于vec.size()得到类型的问题,在后续段落会给出 do_something(vec[i]); }

    解决方法:尽量让比较的类型相同,例如:

    for (size_t i = 0; i < vec.size(); i++) { //使用size_t类型 do_something(vec[i]); }

    或者:

    for (auto& it : vec) { //使用auto关键字 do_something(it); }

    3.警告:control reaches end of non-void function 在非void类型的函数中没有返回值时,编译器会发出警告。例如:

    int my_abs(int x) { if (x < 0) { return -x; } //没有else语句,函数可能会没有返回值,造成警告 }

    解决方法:在函数末尾添加返回语句,例如:

    int my_abs(int x) { if (x < 0) { return -x; } else { return x; } }

    或者使用assert()语句保证函数不会执行到末尾,例如:

    int my_abs(int x) { if (x < 0) { return -x; } assert(x >= 0); }

    4.警告:unused variable 定义了变量但是没有使用时,编译器会发出警告。例如:

    void foo() { int x = 0; //定义了变量但是没有使用 }

    解决方法:删除或者使用这个变量,例如:

    void foo() { int x = 0; std::cout << x; //使用变量 }

    或者:

    void foo() { }

    5.警告:unused parameter 定义了函数的参数但是没有使用,编译器会发出警告。例如:

    void foo(int x) { //定义了参数但是没有使用 }

    解决方法:删除或者使用这个参数,例如:

    void foo(int x) { std::cout << x; //使用参数 }

    或者:

    void foo() { //删除参数 }

    参考资料中关于插入排序的代码和二进制文件的复制方法并不是本题所需要的答案,因此不予展示。