关于C语言的易错、知识点

最近在复习C语言好多都忘记了,所以写这篇博文来记录一下打代码时遇到的问题和解决方法

2019-08-03

牛客网华中科技大学——二叉排序数

题目描述

二叉排序树,也称为二叉查找树。可以是一颗空树,也可以是一颗具有如下特性的非空二叉树: 1. 若左子树非空,则左子树上所有节点关键字值均不大于根节点的关键字值; 2. 若右子树非空,则右子树上所有节点关键字值均不小于根节点的关键字值; 3. 左、右子树本身也是一颗二叉排序树。 现在给你N个关键字值各不相同的节点,要求你按顺序插入一个初始为空树的二叉排序树中,每次插入后成功后,求相应的父亲节点的关键字值,如果没有父亲节点,则输出-1。

输入描述:

输入包含多组测试数据,每组测试数据两行。
第一行,一个数字N(N<=100),表示待插入的节点数。
第二行,N个互不相同的正整数,表示要顺序插入节点的关键字值,这些值不超过10^8。

输出描述:

输出共N行,每次插入节点后,该节点对应的父亲节点的关键字值。

错误代码wrong
#include<stdio.h>
typedef struct treenode node;
typedef struct treenode{
    node* left=NULL;
    node* right=NULL;
    int num;
}node;
void insert(int curnum,node* treeroot);
int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        int curnum;
        node* treeroot=NULL;
        for(int i=0;i<n;i++){
            scanf("%d",&curnum);
            //树为空插入节点
            if(treeroot==NULL){
                node rootnode;
                rootnode.num=curnum;
                treeroot=&rootnode;
                printf("-1\n");
            }
            else{
                insert(curnum,treeroot);
            }
        }
    }
}
void insert(int curnum,node* treeroot){
    node* curnode;
    curnode=treeroot;
    node* parentnode;
    while(curnode!=NULL){
        parentnode=curnode;
        if(curnum<curnode->num){
            curnode=curnode->left;
        }
        else if(curnum>curnode->num){
            curnode=curnode->right;
        }
    }
    node newnode;
    newnode.num=curnum;
    curnode=&newnode;
    printf("%d\n",parentnode->num);
}
错误情况

Process returned -1073741819 (0xC0000005)

分析情况

我在指针初始化的时候都没有给它赋值,让他成为了野指针,野指针不是NULL指针,

野指针,也就是指向不可用内存区域的指针。通常对这种指针进行操作的话,将会使程序发生不可预知的错误。

“野指针”不是NULL指针,是指向“垃圾”内存的指针。人们一般不会错用NULL指针,因为用if语句很容易判断。但是“野指针”是很危险的,if语句对它不起作用。野指针的成因主要有两种:

  • 指针变量没有被初始化。(也就是我出现问题的这种情况)任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,有两种方式,要么将指针设置为NULL,要么让它指向合法的内存。
  • 指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。别看free和delete的名字恶狠狠的(尤其是delete),它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉。通常会用语句if (p != NULL)进行防错处理。但是这样是不起作用的,这个时候它已经是野指针了,不是NULL。即便p不是NULL指针,它也不指向合法的内存块。
通过代码bingo
#include<stdio.h>
#include<stdlib.h>
typedef struct treenode node;
typedef struct treenode{
    node* left;
    node* right;
    int num;
}node;
int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        int curnum;
        node* treeroot=NULL;
        for(int i=0;i<n;i++){
            scanf("%d",&curnum);
            //树为空插入节点
            if(treeroot==NULL){
                treeroot=(node*)malloc(sizeof(node));
                treeroot->num=curnum;
                treeroot->left=NULL;
                treeroot->right=NULL;
                printf("-1\n");
            }
            else{
                node *curnode=treeroot;
                node *parnode;
                while(curnode!=NULL){
                    parnode=curnode;
                    if(curnum<curnode->num){
                        curnode=curnode->left;
                    }
                    else if(curnum>curnode->num){
                        curnode=curnode->right;
                    }
                }
                if(curnum<parnode->num){
                    parnode->left=(node *)malloc(sizeof(node));
                parnode->left->num=curnum;
                parnode->left->left=NULL;
                parnode->left->right=NULL;
                }
                else if(curnum>parnode->num){
                    parnode->right=(node *)malloc(sizeof(node));
                parnode->right->num=curnum;
                parnode->right->left=NULL;
                parnode->right->right=NULL;
                }
                printf("%d\n",parnode->num);
            }
        }
    }
}

总结
  • 注意函数中指针传值,传递过来也只能更改指针共同指向的内容,无法更改原来指针的内容。
  • 因为c语言中没有类对象的概念,对于结构体变量看作是int类型来进行操作。理解其结构体指针和结构名两种声明方式。其中结构体名在声明时就已经分配好了空间,而指针在等待。可以使用malloc,也可以直接&结构体名。两种方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值