[英]How to initialize struct with an array?
Is there a better way of initializing a struct with an array than doing the following?有没有比执行以下操作更好的用数组初始化结构的方法?
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]
};
}
I thought of assigning pointers:我想到了分配指针:
void calculate(double dParameters[], long lParameters[])
{
Parameters param;
(double*)(¶m.distance) = &dParameters[0];
(long*)(¶m.distanceX) = &lParameters[0];
}
But I am not sure if it is valid in c++.但我不确定它在 C++ 中是否有效。
If you know the layout of the struct, and have carefully chosen to put all members of like type in order without anything between them, then you could use memcpy()
.如果您知道结构的布局,并且仔细选择将所有同类成员按顺序排列,而它们之间没有任何东西,那么您可以使用
memcpy()
。
memcpy(¶m.distance, dParameters, sizeof(*dParameters) * 3);
memcpy(¶m.distanceX, lParameters, sizeof(*lParameters) * 4);
This is rather fragile code, as distance
must be the first double parameter of exactly four double parameters in a row, or you'll get corrupted data, and nothing will verify this at compile time.这是相当脆弱的代码,因为
distance
必须是连续四个双参数中的第一个双参数,否则您将获得损坏的数据,并且在编译时无法验证这一点。
It could be improved with offsetof
to get and/or verify the length.可以使用
offsetof
改进以获取和/或验证长度。 Such as:如:
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));
}
Historically, gcc has not been great at optimizing struct initialization, such as using the equivalent of memcpy()
or memset()
when it would be possible and beneficial.从历史上看,gcc 在优化结构体初始化方面并不是很好,例如在可能且有益的情况下使用
memcpy()
或memset()
的等效项。 If your struct had a hundred fields, this might actually be useful.如果您的结构有一百个字段,这实际上可能很有用。
Another technique would be use to a union to define both an array version and an individual field version of your struct.另一种技术是使用联合来定义结构的数组版本和单个字段版本。
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
Note that using more than one member of a union like this is not strictly legal in C++, but it is in C, and most/all C++ compilers will compile it as expected.请注意,像这样使用多个联合成员在 C++ 中不是严格合法的,但在 C 中是合法的,并且大多数/所有 C++ 编译器都会按预期编译它。
你的第二个例子是非法的,但优化器(知道实际布局)确实像那样实现了它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.