有没有比以下方法更好的初始化带有数组的结构的方法?
struct Parameters
{
double distance;
double radius;
double strength;
long distanceX;
long distanceY;
long clickX;
long clickY;
};
void calculate(double dParameters[], long lParameters[])
{
Parameters param =
{
dParameters[0],
dParameters[1],
dParameters[2],
lParameters[0],
lParameters[1],
lParameters[2],
lParameters[3]
};
}
我想到了分配指针:
void calculate(double dParameters[], long lParameters[])
{
Parameters param;
(double*)(¶m.distance) = &dParameters[0];
(long*)(¶m.distanceX) = &lParameters[0];
}
但是我确定它在c ++中是否有效。
答案 0 :(得分:0)
您的第二个示例是非法的,但是优化器(知道实际的布局)确实会像这样实现它。
答案 1 :(得分:0)
如果您知道该结构的布局,并且已经精心选择将所有类似类型的成员按顺序放置,而它们之间没有任何东西,那么您可以使用memcpy()
。
memcpy(¶m.distance, dParameters, sizeof(*dParameters) * 3);
memcpy(¶m.distanceX, lParameters, sizeof(*lParameters) * 4);
这是相当脆弱的代码,因为distance
必须是连续四个正好是双精度参数的第一个双精度参数,否则您将得到损坏的数据,并且在编译时不会对此进行验证。
可以使用offsetof
进行改进以获取和/或验证长度。如:
void calculate(double dParameters[], size_t n_dParameters, long lParameters[], size_t n_lParameters)
{
Parameters param;
assert(offsetof(Parameters, strength) - offsetof(Parameters, distance) == sizeof(*dParameters) * n_dParameters);
memcpy(¶m.distance, dParameters, offsetof(Parameters, strength) - offsetof(Parameters, distance));
assert(offsetof(Parameters, clickY) - offsetof(Parameters, distanceX) == sizeof(*lParameters) * n_lParameters);
memcpy(¶m.distanceX, dParameters, offsetof(Parameters, clickY) - offsetof(Parameters, distanceX));
}
从历史上看,gcc在优化结构初始化方面并不擅长,例如在可能且有益的情况下使用等效的memcpy()
或memset()
。如果您的结构有一百个字段,那么这实际上可能会有用。
另一种技术将用于联合,以定义结构的数组版本和单个字段版本。
struct ParametersArrays {
double doubles[3];
long longs[4];
};
union ParametersUnion {
struct Parameters params;
struct ParametersArrays arrays;
};
ParametersUnion u;
memcpy(u.arrays.doubles, dParameters, sizeof(u.arrays.doubles));
memcpy(u.arrays.longs, lParameters, sizeof(u.arrays.longs));
Parameters& p = u.params; // Now you can use p
请注意,在C ++中使用这样一个联合体中的多个成员并不是严格合法的,但在C中是合法的,大多数/所有C ++编译器都会按预期进行编译。