所以我将列表定义为全局变量:
typedef struct center {
char center_name[100];
char hostname[100];
int port;
struct center *next_center;
} center;
我需要在列表中添加元素。但是我需要添加的这些元素位于文件中,所以:
int main(int argc, char** argv) {
center *head = NULL;
parse(argv, head);
}
parse是一个函数,它读取文件并将这些读取的元素添加到新的中心(所有这些都可以,它会被双重检查)
void parser (char** argv, center *head) {
//read the elements i need to add
//creates a newCenter and adds the elements read to the new center
//this far it works
addToCenter(newCenter, head);
}
其中:
addToCenter(center *newCenter, center *head){
//adds newCenter to the list
if (head == null)
head = newCenter;
else {
//find last element
lastelement.next_center = newCenter;
}
}
一切正常,但Main上的列表总是返回null。换句话说,引用没有被修改。我不明白为什么,因为我传递一个指向列表的指针。
另一种解决方案我是将列表的head变量创建为全局变量,但最好避免这些情况。
提前致谢。
答案 0 :(得分:6)
您的列表头是按值传递的。你需要通过地址传递头指针,以防它被修改(它将是)。
示例:
addToCenter(center *newCenter, center *head) // <=== note: passed by value
{
//adds newCenter to the list
if (head == null)
head = newCenter; // <=== note: modified local stack parameter only.
else {
//find last element
lastelement.next_center = newCenter;
}
}
应该是:
addToCenter(center *newCenter, center **head) // <=== note: now passed by address
{
//adds newCenter to the list
if (*head == null)
*head = newCenter; // <=== note: now modifies the source pointer.
else {
//find last element
lastelement.next_center = newCenter;
}
}
与解析相同:
void parser (char** argv, center **head) // <=== again, the head-pointer's *address*
{
//read the elements i need to add
//creates a newCenter and adds the elements read to the new center
//this far it works
addToCenter(newCenter, head); // <=== just forward it on.
}
最后回到主要:
int main(int argc, char** argv)
{
center *head = NULL;
parse(argv, &head); // <=== note: passing address of the head-pointer. (thus a dbl-pointer).
}
答案 1 :(得分:3)
你需要像这样传递:
void parser (char** argv, center **head) {
//read the elements i need to add
//creates a newCenter and adds the elements read to the new center
//this far it works
addToCenter(newCenter, &head);
}
addToCenter(center *newCenter, center **head){
//adds newCenter to the list
if (*head == null)
*head = newCenter;
else {
//find last element
lastelement.next_center = newCenter;
}
}
主要是:
int main(int argc, char** argv) {
center *head = NULL;
parse(argv, &head);
}
您必须这样做,因为默认情况下C中的值是按值传递的。由于您按值传递列表的地址,而不是通过引用传递。当您通过引用传递变量head
作为上述程序时,您将能够修改列表并将数据返回到列表中。否则,它将按值传递,head
的值永远不会被修改(因此你得到NULL
)
答案 2 :(得分:2)
将指针传递给函数可以让您查看在函数外部指定指向值的结果。但是,指针本身仍然按值传递。
要修改head
和parser
中的addToCenter
,您必须将指针传递给head
两个函数。
void parser(char** argv, centerPtr **headPtr) {
/* rewrite using *headPtr instead of head */
}
void addToCenter(center *newCenter, center **headPtr) {
/* rewrite using *headPtr instead of head */
}
int main(int argc, char** argv) {
....
parser(argv, &head);
....
}
答案 3 :(得分:1)
在函数中,您修改指针的本地副本,而不是指针本身。您应该更改函数定义以获取指针指针。
答案 4 :(得分:1)
您似乎缺少有关指针逻辑的知识的一部分。我会尝试描述这里的错误。
首先,让我们将void*
重写为int
,这是(某种)内部发生的事情。
addToCenter(int newCenter, int head){
//adds newCenter to the list
if (head == 0)
head = newCenter;
你去了,问题就说明了。
解决方案?
addToCenter(center *newCenter, center **head){
//adds newCenter to the list
if (*head == null)
*head = newCenter;