2009-04-20 13 views
34

Vì vậy, tôi có một số mã, loại như sau, để thêm một struct vào một danh sách các cấu trúc:Làm cách nào để sửa đổi một con trỏ đã được chuyển vào một hàm trong C?

void barPush(BarList * list,Bar * bar) 
{ 
    // if there is no move to add, then we are done 
    if (bar == NULL) return;//EMPTY_LIST; 

    // allocate space for the new node 
    BarList * newNode = malloc(sizeof(BarList)); 

    // assign the right values 
    newNode->val = bar; 
    newNode->nextBar = list; 

    // and set list to be equal to the new head of the list 
    list = newNode; // This line works, but list only changes inside of this function 
} 

Những cấu trúc được định nghĩa như sau:

typedef struct Bar 
{ 
    // this isn't too important 
} Bar; 

#define EMPTY_LIST NULL 

typedef struct BarList 
{ 
    Bar * val; 
    struct BarList * nextBar; 
} BarList; 

và sau đó trong một nộp tôi làm điều gì đó như sau:

BarList * l; 

l = EMPTY_LIST; 
barPush(l,&b1); // b1 and b2 are just Bar's 
barPush(l,&b2); 

Tuy nhiên, sau này, l vẫn trỏ tới EMPTY_LIST, không phải là phiên bản sửa đổi được tạo ra bên trong barPush. Tôi có phải vượt qua danh sách như một con trỏ đến một con trỏ nếu tôi muốn sửa đổi nó, hoặc là có một số câu thần chú tối khác cần thiết?

Trả lời

41

Bạn cần phải vượt qua trong một con trỏ đến một con trỏ nếu bạn muốn làm điều này.

void barPush(BarList ** list,Bar * bar) 
{ 
    if (list == NULL) return; // need to pass in the pointer to your pointer to your list. 

    // if there is no move to add, then we are done 
    if (bar == NULL) return; 

    // allocate space for the new node 
    BarList * newNode = malloc(sizeof(BarList)); 

    // assign the right values 
    newNode->val = bar; 
    newNode->nextBar = *list; 

    // and set the contents of the pointer to the pointer to the head of the list 
    // (ie: the pointer the the head of the list) to the new node. 
    *list = newNode; 
} 

Sau đó sử dụng nó như thế này:

BarList * l; 

l = EMPTY_LIST; 
barPush(&l,&b1); // b1 and b2 are just Bar's 
barPush(&l,&b2); 

Jonathan Leffler đề nghị trả lại người đứng đầu mới của danh sách trong các ý kiến:

BarList *barPush(BarList *list,Bar *bar) 
{ 
    // if there is no move to add, then we are done - return unmodified list. 
    if (bar == NULL) return list; 

    // allocate space for the new node 
    BarList * newNode = malloc(sizeof(BarList)); 

    // assign the right values 
    newNode->val = bar; 
    newNode->nextBar = list; 

    // return the new head of the list. 
    return newNode; 
} 

Cách sử dụng trở thành:

BarList * l; 

l = EMPTY_LIST; 
l = barPush(l,&b1); // b1 and b2 are just Bar's 
l = barPush(l,&b2); 
+1

Cảm ơn, tôi đã nhận ra đây là vấn đề, nhưng hy vọng rằng nó không phải là;) –

+3

Hoặc, có chức năng trả về con trỏ đến đầu mới của danh sách. BarList * barPush (danh sách BarList *, Bar * bar) –

2

Có, bạn phải chuyển con trỏ đến con trỏ. C chuyển đối số theo giá trị, không phải bằng tham chiếu.

6

Hãy nhớ rằng, trong C, EVERYTHING được truyền theo giá trị.

Bạn vượt qua trong một con trỏ đến một con trỏ, như thế này

int myFunction(int** param1, int** param2) { 

// now I can change the ACTUAL pointer - kind of like passing a pointer by reference 

} 
2

Đây là một p cổ điển roblem. Quay trở lại nút được phân bổ hoặc sử dụng một con trỏ của con trỏ. Trong C, bạn nên chuyển một con trỏ tới một X đến một hàm mà bạn muốn sửa đổi X của mình. Trong trường hợp này, vì bạn muốn một con trỏ được sửa đổi, bạn nên chuyển một con trỏ tới một con trỏ.

14

Câu trả lời chung: Chuyển con trỏ đến thứ bạn muốn thay đổi.

Trong trường hợp này, nó sẽ là con trỏ tới con trỏ bạn muốn thay đổi.