我有一个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);
除非您确切了解的结构