我正在用C语言编写并使用GCC进行编译。
是否有更好的方式来声明积分。我很惊讶地发现积分是一个数组。有没有办法声明点,所以看起来更像是一个数组。
typedef struct Span
{
unsigned long lo;
unsigned long hi;
} Span;
typedef struct Series
{
unsigned long *points;
unsigned long count;
unsigned long limit;
} Series;
void SetSpanSeries(Series *self, const Span *src)
{
unsigned long *points;
if (src->lo < src->hi )
{
// Overlays second item in series.
points = self->points; // a pointer in self structure
points[0] = src->lo;
points[1] = src->hi;
self->count = 1;
}
}
现在让我们说这些点指向一个数组结构。
typedef struct Span
{
unsigned long lo;
unsigned long hi;
} Span;
span *points[4];
现在我该如何编写这些代码行?我做对了吗?
points = self->points; // a pointer in self structure
points[0].lo = src->lo;
points[0].hi = src->hi;
答案 0 :(得分:3)
声明unsigned long *points
,points
是一个指针。它指向数组的开头。 arr[x]
与*(arr + x)
相同,因此arr
是否为数组(在这种情况下,它采用数组的地址,添加x
,并取消引用'指针' ')或指针(在这种情况下,它接受指针值,添加x
,并取消引用指针),arr[0]
仍然获得相同的数组访问权。
在这种情况下,您不能将points
声明为数组,因为您不是将用作数组 - 您将其用作指针,指向数组。指针是浅拷贝 - 如果更改指针指向的数据,它将更改原始数据。要创建常规数组,您需要执行深层复制,这会阻止pointer
中的更改影响数组self
,这最终会是您想要的。
事实上,你可以在没有points
的情况下重写整个事情:
void SetSpanSeries(Series *self, const Span *src)
{
if (src->lo < src->hi )
{
self->points[0] = src->lo;
self->points[1] = src->hi;
self->count = 1;
}
}
至于你的第二个例子,是的,points[0].lo
是正确的。 points->lo
也是正确的,只要您只访问points[0]
即可。 (如果您完全取出self->points[0].lo
,则为points
。)
答案 1 :(得分:1)
将指针视为数组的能力肯定会使大多数C初学者感到困惑。当作为参数传递给函数时,数组甚至衰减到指针,给人的印象是数组和指针是完全可互换的 - 它们不是。 Expert C Programming: Deep C Secrets中有一个很好的描述。 (这是我最喜欢的书之一;如果你想了解C,强烈建议使用。)
无论如何,写pointer[2]
与*(pointer+2)
相同 - 大多数人阅读(和写)数组语法要容易得多。
由于您使用此*points
变量可以更轻松地访问另一个内存块(points
中的指针struct Series
),因此无法使用您的局部变量的数组,因为您无法将数组的基础重新分配给其他内容。请考虑以下非法代码:
int foo[10];
int *bar;
int wrong[10];
bar = foo; /* fine */
wrong = foo; /* compile error -- cannot assign to the array 'wrong' */
重写此代码的另一个选择是删除临时变量:
if (src->lo < src->hi) {
self->points[0] = src->lo;
self->points[1] = src->hi;
self->count = 1;
}
我不确定临时变量是否有助于提高易读性 - 它只是保存了几个字符的输入,但却增加了 lot 字符。 (还有一个令人困惑的变量。)
答案 2 :(得分:0)
在中间部分,您说点是指向struct span的指针的数组4。在第三部分中,您将从自我&gt;点分配点(意味着点的先前值,该数组已丢失)。然后,您取消引用点,就好像它是一个struct Span数组,而不是一个指向struct Span的指针数组。
在其他作品中,这无法编译,因为你正在混合类型,即使你不是,你也会覆盖由你的points变量定义分配的内存。
提供系列的定义可能有助于解释正在发生的事情。
但是在第一个例子当然,积分应该是Span *points
但是没有看到系列我们无法确定。