【问题标题】:What does *& mean in C?*& 在 C 中是什么意思?
【发布时间】:2016-04-03 00:38:47
【问题描述】:

我对树的概念不熟悉。我正在学习SerializationdeSerialization。我从链接中获得了一个示例程序,复制了它并执行了它。它跑了,但是当我试图理解它时,我无法理解一行 - void deSerialize(Node *&root, FILE *fp)

*& 是什么意思?

整个代码是:

#include <stdio.h>
#define MARKER -1

/* A binary tree Node has key, pointer to left and right children */
struct Node
{
int key;
struct Node* left, *right;
};

/* Helper function that allocates a new Node with the
given key and NULL left and right pointers. */
Node* newNode(int key)
{
Node* temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return (temp);
}

// This function stores a tree in a file pointed by fp
void serialize(Node *root, FILE *fp)
{
// If current node is NULL, store marker
if (root == NULL)
{
    fprintf(fp, "%d ", MARKER);
    return;
}

// Else, store current node and recur for its children
fprintf(fp, "%d ", root->key);
serialize(root->left, fp);
serialize(root->right, fp);
}

// This function constructs a tree from a file pointed by 'fp'
void deSerialize(Node *&root, FILE *fp)
{
// Read next item from file. If theere are no more items or next
// item is marker, then return
int val;
if ( !fscanf(fp, "%d ", &val) || val == MARKER)
   return;

// Else create node with this item and recur for children
root = newNode(val);
deSerialize(root->left, fp);
deSerialize(root->right, fp);
}

// A simple inorder traversal used for testing the constructed tree
void inorder(Node *root)
{
if (root)
{
    inorder(root->left);
    printf("%d ", root->key);
    inorder(root->right);
}
}

/* Driver program to test above functions*/
int main()
{
// Let us construct a tree shown in the above figure
struct Node *root        = newNode(20);
root->left               = newNode(8);
root->right              = newNode(22);
root->left->left         = newNode(4);
root->left->right        = newNode(12);
root->left->right->left  = newNode(10);
root->left->right->right = newNode(14);

// Let us open a file and serialize the tree into the file
FILE *fp = fopen("tree.txt", "w");
if (fp == NULL)
{
    puts("Could not open file");
    return 0;
}
serialize(root, fp);
fclose(fp);

// Let us deserialize the storeed tree into root1
Node *root1 = NULL;
fp = fopen("tree.txt", "r");
deSerialize(root1, fp);

printf("Inorder Traversal of the tree constructed from file:\n");
inorder(root1);

return 0;
}

任何帮助表示赞赏。

【问题讨论】:

  • 在 C 中它是垃圾,一个语法错误。另一方面,在 C++ 中...您应该查看 The Definitive C++ Book Guide and List 并找到一本不错的初学者书籍或教程。
  • 因为它在 C 中没有任何意义(这是真的),请不要将问题标记为 C。同时编辑问题以反映这一事实。

标签: c++ c serialization tree binary-tree


【解决方案1】:

*&amp; 不是单个符号。但两者的结合:

* 用于指针。 &amp;供参考。

所以你有这个功能:

void deSerialize(Node *&root, FILE *fp)

这个函数的第一个参数是一个节点指针的引用。

含义 - 使用它时,您向它发送一个Node * 对象。并且函数本身可以更改此指针值 - 因为您通过引用传递它。

这允许您在函数内部分配内存。

编写此函数的另一种方法是:

Node *deSerialize(Node *root, FILE *fp)

当然还有不同的用法:

root->left = deSerialize(root->left, fp)

在此处查看完整解决方案:http://ideone.com/5GzAyd。及相关部分:

Node *deSerialize(Node *root, FILE *fp)
{
    // Read next item from file. If theere are no more items or next
    // item is marker, then return
    int val;
    if ( !fscanf(fp, "%d ", &val) || val == MARKER)
       return NULL;

    // Else create node with this item and recur for children
    root = newNode(val);
    root->left = deSerialize(root->left, fp);
    root->right = deSerialize(root->right, fp);
    return root;
}

【讨论】:

  • 很好的解释。 +1,但是当我使用您的技术运行程序时的输出是 - 12 13 -1 -1 -1
  • 在此处查看完整的解决方案:ideone.com/5GzAyd(由于文件使用情况,您无法在那里运行它。但它在本地使用 g++ 对我有用)。我用相关部分更新了答案。
【解决方案2】:

您可以将其解读为

Node* &root

它只是对指针变量的引用。您需要它,因为在某些情况下您的根目录为空,您需要更改它的值。
您也可以通过使用指向指针的指针来实现它。

 Node **root

但是参考文献也有优势-

一旦一个引用被初始化为引用一个对象,它就不能被更改为引用另一个对象(你总是可以使用指针)。因此,它可以确保您不会意外地将根目录更改为指向其他地方,如果您使用指向指针的指针,这是可能的。

【讨论】:

    【解决方案3】:

    在 C 语言中?

    它没有任何意义,并且会给你语法错误。

    在 C++ 中?

    它是对指针的引用。

    节点 *&root。所以它的

     Node*  which is the Node pointer
     & root where  root is reference variable  
    

    请注意,这是在 C++ 中,而不是 C。

    您也可以查看相关帖子:What does *&amp; in a function declaration mean?

    【讨论】:

    • 感谢 rahul,告诉我它是 C++。
    • 那么,如果我必须在 C 中成功编译这个程序,我应该改变什么。我不确定@identicon 的回答是否正确。
    • @Screwdriver “我应该改变什么?”主要是你的方法。 C++ 和 C 是两种不同的语言,它们碰巧共享一个公共的语法子集。不要将它们视为“几乎相同的东西”,它们不是。但是如果您出于某种原因需要它,与引用最接近的 C 等价物是指针 - 因此 Node *&amp;root 在 C 中将变为 Node **root(在使用 @ 的代码中添加了适当的取消引用运算符987654326@).
    猜你喜欢
    • 2013-03-09
    • 2011-07-07
    • 2016-12-08
    • 2016-04-19
    • 2015-04-11
    • 2012-04-25
    • 2011-08-25
    • 2011-11-26
    • 1970-01-01
    相关资源
    最近更新 更多