我有一个棘手的 C 语法问题。我正在构建一个链表数组,其中列表中的每个节点都由一个结构表示。每个结构体保存一个字符串,这在后面很重要:
// "linkedList.h"
typedef struct llnode listnode;
struct llnode {
char* data; // string
// ...and other data
};
我的代码构建了一个指向这些“列表节点”的指针表,并将所有这些指针设置为 NULL,原因超出了本文的范围:
void initTable(listnode** table){
// Initialize all pointers in the table to NULL
for (int i = 0; i < TABLESIZE; i++)
table[i] = NULL;
}
int main(){
// Create table of linked lists
listnode** table = (listnode**) malloc(TABLESIZE * sizeof(listnode*));
initTable(table);
return 1;
}
到目前为止,还不错。稍后,我的程序将数据填充到表中,并在必要时添加到正确的链表中。执行此操作的代码有效,但为了使我的帖子尽可能简短,我将在此处提供一个高度简化的版本:
void insert(listnode** table, int index, char* newData){
if(*(table+index)==NULL){
// Create the new Node
listnode *newNode = NULL;
newNode = (listnode*)malloc(sizeof(listnode)); // allocate for the struct
newNode->data = (char*)malloc(sizeof(char)*15); // allocate for the string within the struct
strcpy(newNode->data, newData); // copy newData into newNode->data
// Insert node into table (Super simple version)
*(table+index) = newNode;
}
}
int main(){
listnode** table = (listnode**) malloc(TABLESIZE * sizeof(listnode*));
initTable(table);
insert(table, 0, "New String A");
insert(table, 5, "New String B");
insert(table, 7, "New String C");
return 1;
}
这一切都很好。现在问我真正的问题……假设我想进入表格并取消引用其中一个字符串?
void printTable(listnode** table){
for(int i=0; i<TABLESIZE; i++){
if(*(table+i)==NULL)
printf("table[%d] == NULL\n", i);
else
printf("table[%d] == %s\n", i, **(table+i)->data); // << PROBLEM IS HERE!
}
}
int main(){
// create & initialize the table, as above
// insert data into the table, as above
printTable(table);
return 1;
}
编译器不喜欢我的语法:
$ gcc -Wall linkedList.c
linkedListc: In function ‘printTable’:
linkedList.c:31:48: error: request for member ‘data’ in something not a structure or union
printf("table[%d] == %s\n", i, **(table+i)->data);
^
$
所以我知道对于一个简单的问题来说这是一个冗长的前提,但是有人可以在这里帮助我使用正确的语法吗?我尝试了多种语法变体,但没有成功。
更令人费解的是,当我稍微修改代码编译它时,然后在 GDB 中查看这个,我可以看到 **(table+i)
是我的结构,但是 **(table+i)->data
不可访问。这是我调试(修改后的)程序时的 GDB 输出;表示“New String A”的节点首先插入表中的索引 0 处。 :
31 printf("table[%d] == %d\n", i, **(table+i));
(gdb) p *(table+i)
$1 = (listnode *) 0x6000397b0
(gdb) p **(table+i)
$2 = {data = 0x6000397d0 "New String A"}
(gdb) p **(table+i)->data
Cannot access memory at address 0x4e
(gdb)
我真的很困惑。一旦一个 C 指针经历了不止一层的取消引用,我就开始怀疑了。有人知道这里的正确语法是什么吗?
感谢一百万, -皮特
PS - 为这篇超长的帖子道歉。我发誓我努力将它保持在可管理的大小......
最佳答案
给出声明
listnode **table;
则以下表达式具有指定的类型
Expression Type
---------- ----
table listnode **
table + i listnode **
*table listnode *
*(table + i) listnode *
table[i] listnode *
**(table + i) listnode
*table[i] listnode
因此,您将使用以下表达式之一来访问 data
成员,从最难看的到最难看的:
table[i]->data // use this, please
(*table[i]).data
(*(table + i))->data
(**(table + i)).data
分组括号是必需的 - .
和 ->
成员选择运算符的优先级高于一元 *
,因此 * table[i].data
将被解析为 *(table[i].data)
,这不是您想要的。
关于c - 取消引用数组中结构中字符串的 C 指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39923870/