【问题标题】:Returning a struct by value gives the same wrong answer every time按值返回结构每次都会给出相同的错误答案
【发布时间】:2019-10-31 16:21:01
【问题描述】:

我正在尝试按值返回结构以查找树中节点的位置。但是使用包装器来简化函数调用会返回不正确的值。

相关代码:


typedef struct {
    uint16_t x;
    uint16_t y;
} coordinate_t;

coordinate_t node_pos_(uint16_t x, uint16_t y, node_t *node, node_t *find) {
    printf("%u, %u\n", x, y);

    if (node == find) {
        printf("found node at %u, %u\n", x, y);
        coordinate_t coords;
        coords.x = x;
        coords.y = y;
        return coords;
    }

    for (uint16_t i = 0; i < node->child_count; i++) {
        node_pos_(x + i, y + 1, node->children[i], find);
    }
}

coordinate_t node_pos(node_t *root, node_t *node) { 
    return node_pos_(0, 0, root, node);
}

int main() {
    coordinate_t coords = node_pos(root, child2);

    printf("coordinates of %s: %u, %u\n", child2->name, coords.x, coords.y);

    return 0;
}

输出:

0, 0
0, 1
0, 2
1, 2
1, 1
found node at 1, 1
coordinates of child2: 2, 0

【问题讨论】:

  • 请发送minimal reproducible example。显示的代码看起来不可编译。
  • node_pos_ 中,如果node == find 不正确,则不会返回任何内容。
  • 如果node != find 那你返回什么?我认为您需要重新考虑递归函数的实现。
  • 您应该会收到来自编译器的警告。请务必为 gcc 启用警告 -Wall,为 Microsoft 启用警告 /W3。然后阅读并修复所有的警告。
  • 你打算如何表示“未找到”的结果?

标签: c


【解决方案1】:

目前,您的node_pos_ 函数不会在所有执行路径中返回值,并且无法向调用者指示是否找到了节点。这两者对于在树中搜索节点的递归算法都是必不可少的。

本着按值返回coordinate_t 的精神,我保留了坐标对(UINT16_MAXUINT16_MAX)来表示“未找到”条件。

修改后的功能如下:

coordinate_t node_pos_(uint16_t x, uint16_t y, node_t *node, node_t *find) {
    coordinate_t coords;

    printf("%u, %u\n", x, y);

    if (node == find) {
        printf("found node at %u, %u\n", x, y);
        coords.x = x;
        coords.y = y;
        return coords;
    }

    // look for node in children
    for (uint16_t i = 0; i < node->child_count; i++) {
        coords = node_pos_(x + i, y + 1, node->children[i], find);
        if (!(coords.x == UINT16_MAX && coords.y == UINT16_MAX)) {
            // found
            return coords;
        }
    }

    // not found
    coords.x = UINT16_MAX;
    coords.y = UINT16_MAX;
    return coords;
}

正如@yano 所指出的,使用%u printf 格式说明符来打印uint16_t 值是不可移植的。一个简单的解决方法是将值转换为 unsigned int,如下所示:

        printf("found node at %u, %u\n", (unsigned)x, (unsigned)y);

修复它的“正确”方法,避免类型转换,是使用来自#include &lt;inttypes.h&gt; 的 printf 格式说明符宏,如下所示:

        printf("found node at %" PRIu16 " , %" PRIu16 "\n", x, y);

【讨论】:

  • 这按我想要的方式工作,但我修改了函数以获取 x 和 y 的 int16_t 参数,并在未找到时返回 -1。比检查两个整数是否相等要便宜。
猜你喜欢
  • 2020-08-25
  • 1970-01-01
  • 2020-01-28
  • 1970-01-01
  • 1970-01-01
  • 2012-05-28
  • 1970-01-01
  • 1970-01-01
  • 2014-03-26
相关资源
最近更新 更多