二维结构的指针混淆



我正在使用malloc创建一个动态结构。我的结构是这样的:

typedef struct
    {
        int v=;
        int t;
        struct a *prev;//points to previous struct in same row
        struct a *next;//points to next struct in same row
        //Is this correct notation?
    } a;
    a **b;
在初始化过程中,我这样做:
for(i=0;i<d1;i++)
    {
        for(j=0;j<d2;j++)
        {
            if (j==0) //if first block, point to NULL
                b[i][j]->prev = NULL;
            else //else point to previous block.
                b[i][j]->prev = *(b[i] + j - sizeof(b[i][j]));
        }
    }

我得到错误无效类型参数。这里出了什么问题?对于先前,我试图首先找到当前块*(b[i]+j)的地址,并获得前一个块的地址,减去每个块的大小,即sizeof(b[i][j])

b[i][j]不是指针。因此,不能使用:

b[i][j]->prev = NULL;
使用

b[i][j].prev = NULL;

对象之间的链接可以使用:

for(j=0;j<d2;j++)
{
    // Fix the prev link
    if (j==0) //if first block, point to NULL
        b[i][j].prev = NULL;
    else //else point to previous block.
        b[i][j].prev = &b[i][j-1];
     // Fix the next link
    if (j==d2-1) //if last block, point to NULL
        b[i][j].next = NULL;
    else //else point to next block.
        b[i][j].next = &b[i][j+1];

}

我猜您希望每行中的元素被链接,但不针对前一行。我的看法:

void
fill(void)
{
    int d1;
    int d2;
    a **b;
    a *x;
    int i;
    int j;
    d1 = 10;
    d2 = 20;
    b = calloc(d1 * d2,sizeof(a));
    x = &b[0][0];
    for (i=0;  i<d1;  i++) {
        x->prev = NULL;
        x->next = x + 1;
        for (x++, j=1;  j<d2;  j++, x++) {
            x->prev = x - 1;
            x->next = x + 1;
        }
        x[-1].next = NULL;
    }
}
更新:

指针运算,在指针上加n。如果n是1,你是在不是给地址加1,你是在加sizeof(*ptr)。考虑以下所有内容都是等效的:

int *xp;
int n;
(A1) xp += n;
(A2) xp = (int *) (((unsigned long) xp) + (n * sizeof(int)))
(A3) xp = &xp[n];
(A4) xp = (int *) (((char *) xp) + (n * sizeof(int)))

盯着这个看一会儿,直到你真正理解为什么这是真的。这是。给指针添加的值应该与相同类型的数组的索引值完全相等。

你的代码在几个方面被破坏了:
-你需要用b[i][j].prev替换b[i][j]->prev,因为b[i][j]已经完全取消了指针的引用[,这是其他人指出的]
-当你做*(b[i] + j - sizeof(b[i][j])时,我甚至不确定你会得到什么。
-你想要&b[i][j-1] (A3)。你的代码[如果它能工作的话],可能会产生&b[i][j-18]
-这是因为你的混合指针算术和字节大小(例如,你正在做上面的(A1), (A2)和(A3)的混搭-你可以使用一个或另一个,但不能同时使用两者/全部)

我的代码只需要一个指针,它在开始时设置,因为它在内循环中增加1。
注意,在完成"j循环"之后,x == &b[i][d2]也就是&b[i+1][0]。这可能有助于让它更清晰。
此外,我在内部j循环之前处理了j==0的情况,并在之后修复了"j==d2-1"的情况。这样的话,if就不在内循环中了为什么它从1开始,而不是0
注意x[-1].next (A3)是(x - 1)->next (A1)

这里的循环被稍微重新编码,以更简单/更快一点。它假定了一个附加变量:a *ep;

for (i=0;  i<d1;  i++) {
    x->prev = NULL;
    x->next = x + 1;
    ep = x + d2;
    for (x++;  x<ep;  x++) {
        x->prev = x - 1;
        x->next = x + 1;
    }
    x[-1].next = NULL;
}

我认为你已经有足够的东西让你的代码工作。之后,试着理解你的代码和我的代码,以及为什么两者都是这样工作的。这样做将使您在处理指针和指针算术方面获得优势,并且很快就会像对普通固定大小的数组进行索引一样简单。Happy Programming…

最新更新