更好地声明一个数组的方法?

时间:2012-07-17 02:37:54

标签: c arrays syntax

我正在用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;

3 个答案:

答案 0 :(得分:3)

声明unsigned long *pointspoints是一个指针。它指向数组的开头。 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但是没有看到系列我们无法确定。