简体   繁体   English

按值返回结构每次都会给出相同的错误答案

[英]Returning a struct by value gives the same wrong answer every time

I'm trying to return a struct by value to find the position of a node in a tree.我正在尝试按值返回结构以查找树中节点的 position。 However using a wrapper to simplify the function call returns the incorrect value.但是,使用包装器来简化 function 调用会返回不正确的值。

Relevant code:相关代码:


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;
}

The output: output:

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

Currently, your node_pos_ function does not return a value in all execution paths, and has no way to indicate to the caller whether the node was found or not.目前,你的node_pos_ function 并不是在所有的执行路径中都返回一个值,也没有办法向调用者指示是否找到了节点。 Both of those are essential for a recursive algorithm that searches for a node in a tree.这两者对于在树中搜索节点的递归算法都是必不可少的。

In keeping with the spirit of returning a coordinate_t by value, I have reserved the coordinate pair ( UINT16_MAX , UINT16_MAX ) to represent the "not found" condition.本着按值返回coordinate_t值的精神,我保留了坐标对( UINT16_MAXUINT16_MAX )来表示“未找到”条件。

The modified function is below:修改后的 function 如下:

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;
}

As pointed out by @yano, the use of the %u printf format specifier to print a uint16_t value is not portable.正如@yano 所指出的,使用%u printf 格式说明符来打印uint16_t值是不可移植的。 A simple fix is to cast the values to unsigned int as below:一个简单的解决方法是将值转换为unsigned int ,如下所示:

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

The "proper" way to fix it, avoiding the type cast, is to use the printf format specifier macros from #include <inttypes.h> as below:修复它的“正确”方法,避免类型转换,是使用来自#include <inttypes.h>的 printf 格式说明符宏,如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM