2

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

3 回答 3

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。)

于 2012-07-17T02:50:44.387 回答
1

将指针视为数组的能力肯定会让大多数 C 初学者感到困惑。当作为参数传递给函数时,数组甚至会衰减为指针,给人的印象是数组和指针是完全可互换的——它们不是。Expert C Programming: Deep C Secrets中有一个很好的描述。(这是我最喜欢的书之一;如果你想了解 C,强烈推荐它。)

无论如何,写作与大多数人阅读(和写作)pointer[2]一样,数组语法要容易得多。*(pointer+2)

由于您正在使用此*points变量来更轻松地访问另一个内存块( 中的指针pointsstruct 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;
}

我不确定临时变量是否有助于提高易读性——它只是节省了输入几个字符,但以添加大量字符为代价。(也是一个令人困惑的变量。)

于 2012-07-17T02:51:42.737 回答
0

在中间部分,您说点是指向结构跨度的指针的数组 4。在第三部分中,您从 self->points 分配点(意味着点的先前值,该数组,已丢失)。然后,您取消引用点,就好像它是一个 struct Span 数组,而不是一个指向 struct Span 的指针数组。

在其他作品中,这无法编译,因为您正在混合类型,即使您没有,您也正在覆盖由 points 变量的定义分配的内存。

提供 Series 的定义可能有助于解释发生了什么。

但可以肯定的是,在第一个示例中,点数可能应该是 a Span *points,但没有看到 Series,我们无法确定。

于 2012-07-17T02:51:19.220 回答