【问题标题】:Best practice: declaring global arrays of fixed length automatically最佳实践:自动声明固定长度的全局数组
【发布时间】:2019-10-29 08:57:47
【问题描述】:

我想在项目中的文件之间全局共享一个数据结构。

mystruct_s data[] = {
    { // element 1
    }, { // element 2 ...
    }, { 0 } // element N is zero to mark array end
}

在同一个文件中,对象引用data。它的类型读作mystruct_s[N]。这很好,很直接。

在头文件中,我有:

mystruct_s data[];

在其他文件中,我收到类型不匹配警告,因为它被假定为 1 元素数组。

我是根据数组内容计算长度,所以我不需要知道sizeof。一个好的老式指针mystruct_s* 就可以了。

  1. 如何将数组的长度自动传播到另一个文件中?如果我必须手动计算每个元素并将其放入标题中,这将是一场维护噩梦。
    • 我是否应该用一些随机数来声明它,然后#pragma 忽略警告?
  2. 如何将数组本身声明为未知数组或单元素数组(任何都可以)或指针?
    • 我不需要指针变量,而且在 AVR 平台上执行此操作似乎很复杂,其中数组应存储在 PROGMEM 中。如果我声明一个指针,它想把 指针变量 放在 PROGMEM 中。这不是很有用。然后它指向的数组在某处变成了一个未命名的对象。 (编译器(GCC 8.1.0)不喜欢这个,所以我不确定它到底想我在尝试什么......)
  3. 应该如果这是错误的方法,我应该如何处理?把所有东西都扔在标题里? (我喜欢对数据块使用头文件,但我更喜欢在不需要维护的块上这样做;因为这些元素引用 .c 文件中的其他对象,所以放置 @987654327 更自然@那里也是。)

【问题讨论】:

    标签: c arrays variable-declaration avr-gcc


    【解决方案1】:

    我首选的声明全局变量并使其在其他模块中可见的方式如下:

    // to define global variables, use the following:
    
    // module.c
    #include "glo.h"
    
    // glo.h
    #ifndef EXTERN
    # define EXTERN extern
    #endif
    EXTERN int myvar;
    
    #define ARR_SIZE 123
    EXTERN int myArr[ARR_SIZE];
    
    // main.c
    #define EXTERN
    #include "glo.h"
    

    这会为main 中的全局变量分配存储空间,并使它们在所有其他模块中称为extern

    这扩展为:

    // module.c
    extern int myvar;
    extern int myArr[123];
    

    主要是:

    // main.c allocates storage
    int myvar;
    int myArr[123];
    

    编辑

    您需要知道数组大小不是通过定义的常量而是基于初始化器的数组大小。可能一个好方法是为所有其他模块定义具有虚拟大小的数组并提供数组大小作为一个单独的全局变量,在初始化之后在 main 中初始化。

    // glo.h
    #ifndef EXTERN
    # define EXTERN extern
    extern int myArr[2];
    #endif
    EXTERN int gArrSize;
    

    和:

    // main.c
    #define EXTERN
    #include "glo.h"
    int myArr[] = { 1, 2, 3, 4, 0};
    int gArrSize= sizeof(myArr)/sizeof(myArr[0]);
    

    【讨论】:

    • 大写 EXTERN 背后的原因是什么?
    • 表示它是一个宏(#defined 符号)。
    • 我的意思是为什么不只是extern int myvar;?还是我错过了这里的重点?
    • 您错过了重点:考虑在 main 和模块中包含:实际存储将分配到哪里?
    • 这里extern的意义是什么?这可以在没有 ARR_SIZE 的情况下完成,还是自动计算?
    【解决方案2】:

    您可以将“数组”包装在更高级别的结构中

    struct higherlevel {
        mystruct_s *data;
        size_t datalen;
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-26
      • 1970-01-01
      • 1970-01-01
      • 2013-08-03
      相关资源
      最近更新 更多