双指针(struct tree\u st**root)实际上是如何工作的?

双指针(struct tree\u st**root)实际上是如何工作的?,c,pointers,struct,double-pointer,C,Pointers,Struct,Double Pointer,我们必须用汽车模型创建一个二叉树,并以不同的方式修改它。我的主要问题是使用双指针(struct tree\u st**root) 为什么我不能使用标准的单指针 如果您需要有关我所说内容的更多详细信息,请参阅以下代码: #include<stdio.h> #include<stdlib.h> #include<string.h> #define MAX_SIZE 20+1 typedef struct auto_st //auto as in "car"

我们必须用汽车模型创建一个二叉树,并以不同的方式修改它。我的主要问题是使用双指针(
struct tree\u st**root

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

如果您需要有关我所说内容的更多详细信息,请参阅以下代码:

#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;
}
#包括
#包括
#包括
#定义最大尺寸20+1
typedef struct auto\u st//auto as in“car”
{
char marka[MAX_SIZE];//标记为“汽车模型”
int kubikaza;/“容积”
int godiste;/“生产年份”
结构自动左,右;
}汽车;
文件*安全打开(字符*文件名,字符*模式,整数退出代码);
void init(自动**根);
自动*新建(字符标记[],int-kubikaza,int-godiste);
作废添加位置(自动*新建,自动**根);
无效读取文件(文件*in,自动**根);
无效写入(文件*输出,自动*根);
全部无效写入(文件*输出,自动*根);
void find(自动*根,字符标记[]);
自动*最新(自动*根,int max_kub);
int main(int arg_num,char*args[])
{
自动*根;
如果(arg_num!=4)
{
printf(“参数数量错误!\n”);
出口(1);
}
int max_kub=atoi(args[1]);
char*in_filename=args[2];
char*out_filename=args[3];
FILE*in=safe\u fopen(文件名为“r”,10);
FILE*out=safe\u fopen(out\u文件名,“w”,11);
init(&根);
读取_文件(在,&根目录中);
全部写入(输出,根);
自动*最佳=最新(根,最大值);
如果(最佳==NULL)
{
printf(“汽车不存在!\n”);
}
其他的
{
写出一个(最好的);
}
查找(根,“法拉利”);
fclose(in);
fclose(out);
返回退出成功;
}
文件*安全打开(字符*文件名,字符*模式,整数退出代码)
{
FILE*pf=fopen(文件名,模式);
if(pf==NULL)
{
printf(“无法打开文件%s\n”,文件名);
退出(退出代码);
}
返回pf;
}
void init(自动**根)
{
*root=NULL;
}
自动*新建(字符标记[],int-kubikaza,int-godiste)
{
AUTO*new=(AUTO*)malloc(sizeof(AUTO));
if(new==NULL)
{
printf(“内存不足!!\n”);
出口(5);
}
strcpy(新建->标记,标记);
新建->库比卡扎=库比卡扎;
新建->godiste=godiste;
新建->左=空;
新建->右=空;
归还新的;
}
无效添加位置(自动*新建,自动**根)
{
如果(*root==NULL)
{
*根=新的;
}
else if(strcmp((*root)->marka,new->marka)==1)
{
添加_位置(新,&(*根)->左);
}
else if(strcmp((*root)->marka,new->marka)=-1)
{
添加_位置(新,&(*根)->右);
}
}
无效读取文件(文件*in,自动**根)
{
char tmarka[最大尺寸];
内特库比卡扎;
int tgodiste;
而(fscanf(在“%s%d%d”、tmarka、tkubikaza和tgodiste中)!=EOF)
{
自动*新建=新建(tmarka、tkubikaza、tgodiste);
添加_位置(新,根);
}
}
无效写入(文件*out,自动*root)
{
fprintf(out,“%s%d%d\n”,root->marka,root->kubikaza,root->godiste);
}
全部无效写入(文件*out,自动*root)
{
if(root!=NULL)
{
全部写入(输出,根->左);
写出一个(out,root);
全部写入(输出,根->右);
}
}
无效查找(自动*根,字符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)
{
查找(根->左,tmarka);
}
else if(strcmp(root->marka,tmarka)=-1)
{
查找(根->右,tmarka);
}
}
}
自动*最新(自动*根,整数最大值)
{
if(root==NULL)
{
返回NULL;
}
自动*best=NULL;
如果(根->库比卡扎左,最大库布);
if(左!=NULL)
{
if(best==NULL | | left->godiste>best->godiste)
{
最佳=左;
}
}
自动*右=最新(根->右,最大);
if(右!=NULL)
{
if(best==NULL | | right->godiste>best->godiste)
{
最佳=正确;
}
}
回报最好;
}

指针就是指针,仅此而已。它指向另一个方面

例如

int int_value = 1;
int *ptr_to_int = &int_value;
变量
ptr_to_int
指向存在
int_值的位置

现在有一个“双指针”:

变量
ptr_to_ptr_to_int
指向存在
ptr_to_int
的位置

从更“图形化”的角度来看,上面的内容可以看作是

+-------------------+ +------------+ +-----------+ | ptr_to_ptr_to_int | ---> | ptr_to_int | ---> | int_value | +-------------------+ +------------+ +-----------+ +-------------------+ +------------+ +-----------+ |ptr|u至| ptr|u至| int-->| ptr|u至| int-->| int|u值| +-------------------+ +------------+ +-----------+
“双指针”基本上有三种用途,都与数组有关

  • 第一个是拥有指向对象(主要是结构)的指针的动态数组
  • 第二种是拥有动态对象数组的动态数组(也称为动态“2d数组”)
  • 模拟指针的按引用传递

在您显示的例子中,函数
init
read\u file
采用“双指针”,这是模拟按引用传递的最后一种情况。

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

在代码中:

void init(AUTO **root);
init
指向NULL的指针的值,从而更改它。发送
AUTO*root
将不允许此操作

void add_location(AUTO *new, AUTO **root)
add_location
如果是第一个添加的位置,也可以设置基本指针

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

read\u file
通过创建新实例更改指针。

@IMug3tsu将示例中的类型
int
替换为结构。实际类型不重要,它是(a
void read_file(FILE *in, AUTO **root);