C结构初始化-有趣



我有一个C程序,它初始化两个结构并尝试打印它们的值。请参阅下面的代码。

#include<stdio.h>
#include<stdlib.h>
typedef struct node{
    int data;
    struct node * next;
}node_t;
typedef struct bstNode{
    int data;
    struct bstNode* right;
    struct bstNode* left;
}bstNode_t;
main(){
    struct bstNode* rootptr = malloc(sizeof(struct bstNode));
    printf("n*rootptr  %xn",*rootptr);
    printf("rootptr = %xn",rootptr);
    rootptr->data = 8;
    rootptr->left = NULL;
    printf("n*rootptr  %xn",*rootptr);
    printf("rootptr = %xn",rootptr);

    node_t* tmp = (node_t*) malloc(sizeof(node_t));
    printf("n*tmp = %x",*tmp);
    printf("n tmp = %xn",tmp);
    tmp->data = 9;
    tmp->next = NULL;
    printf("n*tmp = %x",*tmp);
    printf("n tmp = %xn",tmp);
    printf("n ptr size = %xn",sizeof(int));
}

程序的输出是

*rootptr  20fe1
rootptr = 4a78010
*rootptr  4691e000
rootptr = 4a78010
*tmp = 0
 tmp = 4a78030
*tmp = 9
 tmp = 4a78030
 ptr size = 4

*rootptr的值与*tmp不同,这让我很惊讶。在将值分配给变量之前和之后。为什么会发生这种情况?当*tmp可以将值打印为9时。为什么不将*rootptr打印为8?这里的数据是两个结构中的第一个值。所以指针(结构)上的值应该打印第一个数据的值,对吧?

您不能使用打印自定义结构的值

printf("n*rootptr  %xn",*rootptr);
printf("n*tmp = %x",*tmp);

您应该编写一个自定义函数并调用它来打印BST和节点指针。例如:

int print_node(node_t *nd)
{
  if(nd == 0) return printf("<null>");
  else return printf("[data = %d, next = %p]", nd->data, nd->next);
}

然后用代替printf("n*rootptr %xn",*rootptr);

printf("n*rootptr  ");
print_node(rootptr);
printf("n");

同样,您也可以编写自定义函数来打印BST节点。

关于printf %x说明符,来自手册页

o、 u,x,x
无符号int参数转换为无符号八进制(o)、无符号十进制(u)或无符号十六进制(x和x)符号字母abcdef用于x转换;字母ABCDEF用于X转换。精度(如果有的话)给出了必须出现的最小位数;如果转换后的值需要更少的数字,它被填充在左边是零。默认精度为1。当0以显式精度0打印时,输出为空。

若参数不是无符号的int,则可能会得到奇怪的结果。

当您尝试打印结构成员值时,不应该使用*运算符来执行此操作。相反,您应该使用.->运算符来根据其类型执行此操作!

尝试此更改-

#include<stdio.h>
#include<stdlib.h>
typedef struct node{
        int data;
        struct node * next;
}node_t;
typedef struct bstNode{
        int data;
        struct bstNode* right;
        struct bstNode* left;
}bstNode_t;
int main(){
        struct bstNode* rootptr = malloc(sizeof(struct bstNode)); // where rootptr is structure pointer. so you need do use -> operator to access ins members
        printf("nrootptr->data  %dn",rootptr->data); // Fix 1.
        printf("rootptr = %pn",rootptr); // use %p to print addresses
        rootptr->data = 8;
        rootptr->left = NULL;
        printf("nrootptr->data  %dn",rootptr->data); // Fix 2.
        printf("rootptr = %pn",rootptr);
        node_t* tmp = (node_t*) malloc(sizeof(node_t));
        printf("ntmp->data = %d",tmp->data); // Fix 3.
        printf("n tmp = %pn",tmp);
        tmp->data = 9;
        tmp->next = NULL;
        printf("ntmp->data = %d",tmp->data); // Fix 4.
        printf("n tmp = %pn",tmp);
        printf("n ptr size = %xn",sizeof(int));
        return 0;
}

输出-

rootptr->data  0
rootptr = 0x966a008
rootptr->data  8
rootptr = 0x966a008
tmp->data = 0
 tmp = 0x966a018
tmp->data = 9
 tmp = 0x966a018
 ptr size = 4

输出是正确的,不知怎么的,你得到了这个结果。。。。让我解释一下。

当您调用"malloc"时,内存被分配给您,但它没有初始化,所以基本上,如果以前使用过内存,那么它只会被一些过去的值"弄脏"。您必须始终初始化您的值,否则指向的内存的内容将变脏。

现在,让我们看看您向编译器要求了什么:

printf("n*rootptr  %xn",*rootptr);

您基本上要求打印一个指针(%x),但传递的参数是一个取消引用的指针(*rootptr)。在这种情况下,printf将接收4个字节的解引用指针:前两个字节是rootptr->data的值,后两个字节为rootptr->left 的值

由于设置了一些值,rootptr->data和rootptr-->left(即您打印的内容)的值都会随时间变化,因此*rootptr的输出会随时间改变。

同样适用于tmp

在第二种情况下,你问

printf("rootptr = %xn",rootptr);

所以您要求编译器打印指针的地址。这是正确的,正如你所看到的,它不会在你的输出中改变

底线:如果你打算打印整个结构,你应该做一些类似的事情:

printf("nrootptr value %d,%x,%xn",rootptr->data, rootptr->left, rootptr->right);

除非您确切了解的结构

,否则永远不要打印未引用的指针

相关内容

  • 没有找到相关文章