最佳实践:自动声明固定长度的全局数组
Best practice: declaring global arrays of fixed length automatically
我有一个数据结构,我想在项目中的文件之间全局共享。
mystruct_s data[] = {
{ // element 1
}, { // element 2 ...
}, { 0 } // element N is zero to mark array end
}
在同一个文件中,objects 引用 data
。它的类型读作 mystruct_s[N]
。这很好,很直接。
在 header 文件中,我有:
mystruct_s data[];
在其他文件中,我收到类型不匹配警告,因为它被假定为 1 元素数组。
我是根据数组内容计算长度的,所以我不需要知道sizeof
。一个好的老式指针 mystruct_s*
就可以了。
- 如何自动将数组的长度传播到另一个文件中?如果我必须手动计算每个元素并将该计数放入 header,这将是一场维护噩梦。
- 我是否应该只用一些 random-ass 数字来声明它,#pragma 忽略警告?
- 如何将数组本身声明为未知数组或 single-element 数组(任何数组都可以)或指针?
- 我不需要指针变量,而且在 AVR 平台上也这样做似乎很复杂,数组应存储在 PROGMEM 中。如果我声明一个指针,它想把指针变量放在PROGMEM中。这不是很有用。然后它指向的数组在某处变成未命名的 object 。 (编译器 (GCC 8.1.0) 不喜欢这样,所以我不确定它到底认为我在尝试什么..)
- 我应该如何处理这个问题,如果这是错误的方法?把所有东西都扔进header? (我确实喜欢对数据块使用 header 文件,但我更喜欢在不需要维护的块上这样做;因为这些元素引用 .c 文件中的其他 objects , 也将
data[]
放在那里更自然。)
我首选的声明全局变量并使它们在其他模块中已知的方式如下:
// 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];
编辑
您需要知道数组大小,而不是通过定义的常量,而是基于 initializers.Possibly 的数组大小,一个好方法是为所有其他模块定义具有虚拟大小的数组并在初始化后将数组大小作为您在 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]);
您可以将 "array" 包装在更高级别的结构中
struct higherlevel {
mystruct_s *data;
size_t datalen;
};
我有一个数据结构,我想在项目中的文件之间全局共享。
mystruct_s data[] = {
{ // element 1
}, { // element 2 ...
}, { 0 } // element N is zero to mark array end
}
在同一个文件中,objects 引用 data
。它的类型读作 mystruct_s[N]
。这很好,很直接。
在 header 文件中,我有:
mystruct_s data[];
在其他文件中,我收到类型不匹配警告,因为它被假定为 1 元素数组。
我是根据数组内容计算长度的,所以我不需要知道sizeof
。一个好的老式指针 mystruct_s*
就可以了。
- 如何自动将数组的长度传播到另一个文件中?如果我必须手动计算每个元素并将该计数放入 header,这将是一场维护噩梦。
- 我是否应该只用一些 random-ass 数字来声明它,#pragma 忽略警告?
- 如何将数组本身声明为未知数组或 single-element 数组(任何数组都可以)或指针?
- 我不需要指针变量,而且在 AVR 平台上也这样做似乎很复杂,数组应存储在 PROGMEM 中。如果我声明一个指针,它想把指针变量放在PROGMEM中。这不是很有用。然后它指向的数组在某处变成未命名的 object 。 (编译器 (GCC 8.1.0) 不喜欢这样,所以我不确定它到底认为我在尝试什么..)
- 我应该如何处理这个问题,如果这是错误的方法?把所有东西都扔进header? (我确实喜欢对数据块使用 header 文件,但我更喜欢在不需要维护的块上这样做;因为这些元素引用 .c 文件中的其他 objects , 也将
data[]
放在那里更自然。)
我首选的声明全局变量并使它们在其他模块中已知的方式如下:
// 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];
编辑
您需要知道数组大小,而不是通过定义的常量,而是基于 initializers.Possibly 的数组大小,一个好方法是为所有其他模块定义具有虚拟大小的数组并在初始化后将数组大小作为您在 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]);
您可以将 "array" 包装在更高级别的结构中
struct higherlevel {
mystruct_s *data;
size_t datalen;
};