gpt4 book ai didi

c - 以一致的方式对结构和数组进行别名

转载 作者:行者123 更新时间:2023-11-30 16:16:09 25 4
gpt4 key购买 nike

在 ISO C 之前的时代,下面的代码不会让任何人感到惊讶:

struct Point {
double x;
double y;
double z;
};
double dist(struct Point *p1, struct Point *p2) {
double d2 = 0;
double *coord1 = &p1.x;
double *coord2 = &p2.x;
int i;
for (i=0; i<3; i++) {
double d = coord2[i] - coord1[i]; // THE problem
d2 += d * d;
return sqrt(d2);
}

当时,我们都知道 double 对齐可以让编译器在 struct Point 中不添加任何填充。 ,我们只是假设指针算术可以完成这项工作。

不幸的是,这个有问题的行使用了指针算术( p[i] 根据定义 *(p + i) )在任何数组之外,这是标准明确不允许的。 C11 的 n1570 草案在 6.5.6 加法运算符 §8 中表示:

When an expression that has integer type is added to or subtracted from a pointerpointer, the result has the type of the pointer operand. If the pointer operand points to an element of an array object, and the array is large enough, the result points to an element offset from the original element such that the difference of the subscripts of the resulting and original array elements equals the integer expression...

由于当我们没有同一数组的两个元素时,什么也没说,因此标准未指定,因此未定义行为(即使所有常见编译器都对此感到高兴......)

问题:

因为这个习惯用法可以避免代码复制更改xy然后z这很容易出错,什么是浏览结构体元素的一致方法,就像它们是同一数组的成员一样?

免责声明:它显然只适用于相同类型的元素,并且可以使用简单的 static_assert 来检测填充。如that other question所示我的,所以填充、对齐和混合类型不是我的问题。

最佳答案

C 没有定义任何方法来指定编译器不得在 struct Point 的命名成员之间添加填充,但许多编译器都有一个可以提供此功能的扩展。如果您使用这样的扩展,或者您只是愿意假设不会有填充,那么您可以使用带有匿名内部structunion,例如所以:

union Point {
struct {
double x;
double y;
double z;
};
double coords[3];
};

然后,您可以通过其各自的名称或通过 coords 数组访问坐标:

double dist(union Point *p1, union Point *p2) {
double *coord1 = p1->coords;
double *coord2 = p2->coords;
double d2 = 0;

for (int i = 0; i < 3; i++) {
double d = coord2[i] - coord1[i];
d2 += d * d;
}
return sqrt(d2);
}

int main(void) {
// Note: I don't think the inner braces are necessary, but they silence
// warnings from gcc 4.8.5:
union Point p1 = { { .x = .25, .y = 1, .z = 3 } };
union Point p2;

p2.x = 2.25;
p2.y = -1;
p2.z = 0;

printf("The distance is %lf\n", dist(&p1, &p2));

return 0;
}

关于c - 以一致的方式对结构和数组进行别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56749186/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com