我有一个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?
这里的数据是两个结构中的第一个值。所以指针(结构)的值应该打印第一个数据的值,对吗?
答案 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);
除非您完全了解结构,否则不要打印未引用的指针