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