双指针(struct tree_st ** root)实际上如何工作? [英] How do the double pointers (struct tree_st **root) actually work?

查看:105
本文介绍了双指针(struct tree_st ** root)实际上如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们必须用汽车模型创建一个二叉树,并以不同的方式对其进行修改.我的主要问题是使用双指针(struct tree_st **root).

We have to create a binary tree with car models and modify it in different ways. The main problem for me is the use of a double pointer (struct tree_st **root).

为什么我不能只使用标准的单指针?

Why can't I just use a standard, single pointer?

如果您需要我所谈论的内容的更多详细信息,请使用以下代码:

Here's the code if you need more details of what I'm talking about:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_SIZE 20+1

typedef struct auto_st   //auto as in "car"
{
    char marka[MAX_SIZE];  //marka as in "car model"
    int kubikaza;  // "cubage"
    int godiste;  // "year of production"
    struct auto_st *left, *right;

}AUTO;

FILE *safe_fopen(char *filename, char *mode, int exit_code);
void init(AUTO **root);
AUTO *create_new(char marka[], int kubikaza, int godiste);
void add_location(AUTO *new, AUTO **root);
void read_file(FILE *in, AUTO **root);
void write_one(FILE *out, AUTO *root);
void write_all(FILE *out, AUTO *root);
void find(AUTO *root, char marka[]);
AUTO *newest(AUTO *root, int max_kub);

int main(int arg_num, char *args[])
{
    AUTO *root;
    if(arg_num!=4)
    {
        printf("WRONG NUMBER OF ARGUMENTS!\n");
        exit(1);
    }

    int max_kub = atoi(args[1]);
    char *in_filename = args[2];
    char *out_filename = args[3];

    FILE *in = safe_fopen(in_filename,"r",10);
    FILE *out = safe_fopen(out_filename,"w",11);

    init(&root);
    read_file(in,&root);
    write_all(out,root);

    AUTO *best = newest(root, max_kub);
    if(best==NULL)
    {
        printf("CAR DOESN'T EXIST!\n");
    }
    else
    {
        write_one(out,best);
    }

    find(root,"Ferrari");

    fclose(in);
    fclose(out);
    return EXIT_SUCCESS;
}

FILE *safe_fopen(char *filename, char *mode, int exit_code)
{
    FILE *pf = fopen(filename,mode);
    if(pf==NULL)
    {
        printf("CAN'T OPEN FILE %s\n", filename);
        exit(exit_code);
    }
    return pf;
}

void init(AUTO **root)
{
    *root = NULL;
}

AUTO *create_new(char marka[], int kubikaza, int godiste)
{
    AUTO *new = (AUTO*)malloc(sizeof(AUTO));
    if(new == NULL)
    {
        printf("NOT ENOUGH RAM!!\n");
        exit(5);
    }

    strcpy(new->marka,marka);
    new->kubikaza = kubikaza;
    new->godiste = godiste;

    new->left = NULL;
    new->right = NULL;

    return new;
}

void add_location(AUTO *new, AUTO **root)
{
    if(*root==NULL)
    {
        *root = new;
    }
    else if(strcmp((*root)->marka,new->marka)==1)
    {
        add_location(new,&((*root)->left));
    }
    else if(strcmp((*root)->marka,new->marka)==-1)
    {
        add_location(new,&((*root)->right));
    }
}

void read_file(FILE *in, AUTO **root)
{
    char tmarka[MAX_SIZE];
    int tkubikaza;
    int tgodiste;

    while(fscanf(in,"%s %d %d",tmarka, &tkubikaza, &tgodiste)!=EOF)
    {
        AUTO *new = create_new(tmarka, tkubikaza, tgodiste);
        add_location(new,root);
    }
}

void write_one(FILE *out, AUTO *root)
{
    fprintf(out,"%s %d %d\n",root->marka, root->kubikaza, root->godiste);
}

void write_all(FILE *out, AUTO *root)
{
    if(root!=NULL)
    {
        write_all(out,root->left);
        write_one(out,root);
        write_all(out,root->right);
    }
}

void find(AUTO *root, char tmarka[])
{
    if(root!=NULL)
    {
        if(strcmp(root->marka,tmarka)==0)
        {
            printf("%s %d %d\n",root->marka, root->kubikaza, root->godiste);
        }
        else if(strcmp(root->marka,tmarka)==1)
        {
            find(root->left, tmarka);
        }
        else if(strcmp(root->marka,tmarka)==-1)
        {
            find(root->right, tmarka);
        }
    }
}

AUTO *newest(AUTO *root, int max_kub)
{
    if(root==NULL)
    {
        return NULL;
    }

    AUTO *best = NULL;
    if(root->kubikaza <= max_kub)
    {
        best = root;
    }

    AUTO *left = newest(root->left, max_kub);
    if(left!=NULL)
    {
        if(best==NULL || left->godiste > best->godiste)
        {
            best = left;
        }
    }

    AUTO *right = newest(root->right, max_kub);
    if(right!=NULL)
    {
        if(best==NULL || right->godiste > best->godiste)
        {
            best = right;
        }
    }

    return best;
}

推荐答案

除非明确定义为引用,否则C/C ++中的所有参数均按值传递,包括指针.当您更改指针的内容时,您不会更改指针本身,它实际上只是一个内存地址.如果必须能够更改指针,则必须通过引用或将其作为双指针传递.

Unless explicitly defined as a reference, all parameters in C/C++ are passed by value, including pointers. When you change the contents of the pointer, you don't change the pointer itself, which is really just a memory address. If you have to be able to change the pointer, then you have to either pass it by reference, or as a double pointer.

在您的代码中:

void init(AUTO **root);

init指向NULL的指针的值,从而对其进行更改.发送AUTO *root不允许这样做.

init the value of the pointer to NULL, thus changing it. Sending AUTO *root would not allow this.

void add_location(AUTO *new, AUTO **root)

如果

add_location是添加的第一个位置,则还可以设置基本指针.

add_location can also set the base pointer if it is the first location added.

void read_file(FILE *in, AUTO **root);

read_file通过创建新实例来更改指针.

read_file changes the pointer by creating a new instance.

这篇关于双指针(struct tree_st ** root)实际上如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆