在我被迫使用C进行科学计算的作业中(而不是说C ++,我的默认选择),我经常会遇到以下模式:
通常,许多功能通常需要一组数据。例如,在求解微分方程时,我需要知道点的数量,方程式'参数等:
struct parameters{
unsigned int num_x;
double length_x;
// so forth
};
我经常最终必须将它们组合在一个结构中,然后最终在几乎所有函数中重复自己:void f(struct parameters* p, ...)
。如果每个函数都将其作为其界面的一部分是有意义的,那就不会那么糟糕,但情况并非总是如此,而且我还是不喜欢重复。
此外,将所有这些参数放在一个结构中并不总是有意义,但将其拆分会使界面更难以管理。
是否有任何变通办法或有用的设计模式来处理这个问题?制作全局p
可以解决这个问题,但是在通常不建议使用全局的情况下证明这一点是合理的。
答案 0 :(得分:5)
在我看来,不使用全局变量有两个重要原因:
但有时候,有些数据只是真正的全球性,可能需要在一个项目的所有部分,如果是这样,我不相信应该有任何耻辱,使它成为全球性的,如果基本上是。
你可以尽职地传递一个指向你的共享"或"普通"数据(如你所建议的),这通常是正确的模式,但在这种情况下,你基本上重新引入了问题#1。
如果您确定自己永远不会想要将您的程序重新打包为可分离的,可调用的库,那么异议#2也会消失。
正如Mark Benningfield在评论中所说,不使用全局变量的原因不仅仅是因为每个人都说你不应该这样做。如果你知道自己在做什么,如果全球不会给你带来问题,你应该继续使用它。
我,我唯一坚持的是,如果一个变量是全局变量,它必须有一个漂亮的,长的描述性名称。单字符或双字符全局变量名称就在右边。
(但是所有这些都说明了,你通常会发现像goto
这样的全局变量可以保持在最低限度。尽管有这样的建议,一般的建议是尽可能避免它们。事实上,有时过分热心或虔诚地应用,通常是正确的。)
答案 1 :(得分:1)
通常你只是传递一个指针,使用一个大结构可能是prefererd。您可以在函数中记录它使用的成员(实际界面)。
你可以在不同类型的计算的许多结构中分解结构,所有结构都有不同的成员,并且可以将它们全部组合在大结构中。
可能没有首选的设计模式。
答案 2 :(得分:0)
我过去使用的一种方法是在文件级别声明一组宏常量 - 您的示例将类似于
#define NUM_X <value>
#define LENGTH_X <value>
这些当然是由预处理器代替的,它在全球规避的情况下是有益的。
答案 3 :(得分:0)
如果你真的想避免使用全局变量但只想设置一次你的结构,那么你可以编写一个模块来做到这一点。
parameters.h:
struct t_param{
unsigned int num_x;
double length_x;
// so forth
};
int get_parameters(struct t_param * out);
int init_parameters(const struct t_param* in);
parameters.c:
#include <string.h>
#include "parameters.h"
static struct t_param parameters = {0,0.0};
static int initialized = 0;
int init_paramaters(const t_param* in)
{
if(initialized == 0)
{
memcpy(¶meters, in);
initialized = 1;
return 0;
}else
{
return -1;
}
}
int get_parameters(t_param *out)
{
if(initialized == 0)
{
return -1;
}else
{
memcpy(out, ¶meters);
return 0;
}
}
修改:将memcpy
来电的成员分配。