C结构初始化 - 很有意思

时间:2014-09-01 11:30:59

标签: c memory malloc structure

我有一个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  %x\n",*rootptr);
    printf("rootptr = %x\n",rootptr);

    rootptr->data = 8;
    rootptr->left = NULL;

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


    node_t* tmp = (node_t*) malloc(sizeof(node_t));

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

    tmp->data = 9;
    tmp->next = NULL;

    printf("\n*tmp = %x",*tmp);
    printf("\n tmp = %x\n",tmp);
    printf("\n ptr size = %x\n",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? 这里的数据是两个结构中的第一个值。所以指针(结构)的值应该打印第一个数据的值,对吗?

3 个答案:

答案 0 :(得分:1)

您无法使用

打印自定义结构的值
printf("\n*rootptr  %x\n",*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 %x\n",*rootptr);
printf("\n*rootptr  ");
print_node(rootptr);
printf("\n");

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

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

  

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

如果参数不是unsigned int,则可能会得到奇怪的结果。

答案 1 :(得分:0)

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

尝试此更改 -

#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  %d\n",rootptr->data); // Fix 1.
        printf("rootptr = %p\n",rootptr); // use %p to print addresses

        rootptr->data = 8;
        rootptr->left = NULL;

        printf("\nrootptr->data  %d\n",rootptr->data); // Fix 2.
        printf("rootptr = %p\n",rootptr);

        node_t* tmp = (node_t*) malloc(sizeof(node_t));

        printf("\ntmp->data = %d",tmp->data); // Fix 3.
        printf("\n tmp = %p\n",tmp);

        tmp->data = 9;
        tmp->next = NULL;

        printf("\ntmp->data = %d",tmp->data); // Fix 4.
        printf("\n tmp = %p\n",tmp);

        printf("\n ptr size = %x\n",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

答案 2 :(得分:0)

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

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

现在,让我们看看你向编译器询问的内容:

printf("\n*rootptr  %x\n",*rootptr);

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

由于您设置了一些值,因此rootptr-&gt;数据和rootptr-&gt; left(这是您打印的)的值随着时间的推移而变化,因此* rootptr的输出会随时间变化。

同样适用于tmp

在第二种情况下,你问了

printf("rootptr = %x\n",rootptr);

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

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

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

除非您完全了解结构,否则不要打印未引用的指针