【问题标题】:How to merge two arrays of typedef structs in C如何在C中合并两个typedef结构数组
【发布时间】:2020-09-05 02:00:42
【问题描述】:

我知道有类似的问题,但我真的被我正在使用结构的事实绊倒了,而且我一般不太擅长 C。

我有两个结构数组,我想将它们连接成一个结构数组。我正在编写视频游戏命令的脚本,所以一个数组是:

// Setup_Controller.c
command setup_controller[] = {
    { NOTHING,  250 },
    { TRIGGERS,   5 },
    { NOTHING,  100 },
    { TRIGGERS,   5 },
    { NOTHING,  100 },
};

另一个是

// Get_Eggs.c
command get_eggs[] = {
    // Face and activate the lady
    { LEFT,       5 },
    { NOTHING,    5 },
    { A,          5 },
    .
    . 
    .
    { LEFT,     250 },
    { NOTHING,   30 },
    { UP,        30 },
};

typedef 就在这里:

// Joystick.h

// Declare Object...?
typedef struct {
    Buttons_t button;
    uint16_t duration;
} command; 

我最后的处决发生在这里 // 操纵杆.c #include

#include "Joystick.h"

#include "./Tasks/Setup_Controller.c"
#include "./Tasks/Get_Eggs.c"

command * merge_arrays( command a[],    command b[],
                        size_t a_size,  size_t b_size ) {
    size_t c_size = a_size + b_size; 
    /*allocate new array of sufficient size*/
    command *c = malloc(c_size);
    unsigned i;
    /*copy elements from a into c*/
    for(i = 0; i<a_size; ++i) {
        c[i] = a[i];
    } 
    /*copy elements from b into c*/
    for(i = 0; i < b_size; ++i) {
        c[a_size+i] = b[i];
    }
    
    return c;
}

size_t setup_controller_size    = sizeof(setup_controller);
size_t get_eggs_size            = sizeof(    get_eggs    );

size_t total_size               = sizeof(setup_controller) + sizeof(    get_eggs    );

command step[total_size] = merge_arrays(setup_controller,      get_eggs,
                                        setup_controller_size, get_eggs_size);

我已经用棍子戳这段代码好几个小时了。我几乎可以使用一些有关如何合并数组的代码来使用它,但是当我尝试获取这些元素之一的大小时,它一直在抛出错误。那个错误是这样的:

invalid application of 'sizeof' to incomplete type 'command[]' {aka 'struct <anonymous>[]'}

All 代替数组 A 和数组 B,使数组 C 首先包含 A 的所有元素,然后是 B 的所有元素,并保留它们各自的原始顺序。不知道为什么这会变成这样的麻烦,但我们来了。


最小可重现示例:

//// main.c ////

#include "main.h"

#include "script.c"

#include <stdlib.h>
#include <string.h>

void merge_arrays( data *a, data *b, data *c,
                   size_t a_size,  size_t b_size ) {
    
    memcpy(c, a, a_size);
    memcpy(((unsigned char *)c) + a_size, b, b_size);
}

size_t script1_size = sizeof(script1);
size_t script2_size = sizeof(script2);

merge_arrays(data *script1, data *script2, data *whole_thing,
             size_t a_size, size_t b_size);

.

//// main.h ////

typedef struct {
    int age;
    int height;
} data; 

.

//// script.c  ////

#include "script.h"

data script1[] = {
    { 123,  250 },
    { 123,   5 },
    { 123,  100 },
    { 123,   5 },
    { 123,  100 },
};

data script2[] = {
    { 123,  250 },
    { 123,   5 },
    { 123,  100 },
    { 123,   5 },
    { 123,  100 },
    { 123,  100 },
};

.

//// script.h //// 

extern data script1[];
extern data script2[];

产生的错误:

.../Documents/test/main.c:20:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
merge_arrays(data *script1, data *script2, data *whole_thing,
^
/Users/.../Documents/test/main.c:20:1: error: conflicting types for 'merge_arrays'
/Users/.../Documents/test/main.c:10:6: note: previous definition is here
void merge_arrays( data *a, data *b, data *c,
     ^
1 warning and 1 error generated.

【问题讨论】:

  • 您在main.c 末尾有第二个不完整的merge_arrays 声明。如果您希望它正确,请在其前面添加void,以匹配定义中的返回类型。或者只是删除整个声明,因为它是多余的。
  • @NateEldredge 所以我第二次尝试调用它时,如果我删除该部分,我如何真正让 merge_arrays 发生?
  • 如果你真的想执行这个函数,你需要在另一个函数中调用它,可能是main。与解释型语言不同,C 不允许您在函数之外拥有可执行代码。您来自“顶层”的“调用”被解析为声明,因为您在函数之外唯一能做的就是声明对象并定义数据和其他函数。

标签: arrays c struct concatenation typedef


【解决方案1】:

a_sizeb_size 是以字节为单位的大小,因为这是sizeof 产生的,但是在C 中数组索引的通常方式中,c[i] 计算元素的数量。因此,例如,如果 command 的大小为 4,那么您索引的元素数量是 4 倍。

merge_arrays 更改为计算元素数量可能会更惯用,并以sizeof(get_eggs) / sizeof(command) 作为参数调用它。然后确保调整malloc 调用,使其参数乘以sizeof(command)

但更好的是简单地使用memcpy,它以字节为单位工作并且可能更有效:

memcpy(c, a, a_size);
memcpy(((unsigned char *)c) + a_size, b, b_size);

c 的强制转换确保 + 以字节为单位而不是以 sizeof(command) 为单位相加。

【讨论】:

  • 所以我仍然在获取我正在使用的结构的 sizeof 方面遇到问题。它不断抛出这个错误:error: invalid application of 'sizeof' to incomplete type 'command[]' {aka 'struct &lt;anonymous&gt;[]'}
  • 我在您发布的代码中看不到任何会导致这种情况的内容。你能创建一个minimal reproducible example吗?
  • 抱歉,拖了这么久,我终于让我的主程序和我的 MRE 抛出了同样的错误。它添加在我的帖子末尾。这不再是类型或大小问题,可能只是我对 C 的普遍无知。上帝我想念 ruby​​。为什么我会得到一个微控制器?
猜你喜欢
  • 2020-12-15
  • 2015-09-11
  • 2021-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-16
  • 1970-01-01
  • 2021-08-29
相关资源
最近更新 更多