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++.
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(¶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.
It could be improved with offsetof
to get and/or verify the length. 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. 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.
你的第二个例子是非法的,但优化器(知道实际布局)确实像那样实现了它。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.