2009-04-20 33 views
34

Yani, bir yapıya bir yapı eklemek için aşağıdaki gibi bir kodum var:C'deki bir işleve iletilen işaretçiyi nasıl değiştirebilirim?

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 
} 

Bu yapılar aşağıdaki gibi tanımlanır:

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

#define EMPTY_LIST NULL 

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

ve sonra başka bir dosyada Şöyle bir şey yapıyorum:

BarList * l; 

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

Ancak, bundan sonra hala barPush içinde oluşturulan değiştirilmiş sürümü değil, EMPTY_LIST işaret ediyor. Listeyi değiştirmek istediğimde işaretçiye bir işaretçi olarak mı girmek zorundayım yoksa başka bir karanlık küfür gerekli mi?

cevap

41

gibi bir işaretçi bir işaretçi geçmektedir.

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; 
} 

Sonra bu gibi kullanmak:

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; 
} 

Kullanımı olur:

BarList * l; 

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

Teşekkürler, bunun sorun olduğunu düşünmüştüm ama bunun olmadığını umuyordum;) –

+3

Alternatif olarak, işlevin işaretçiyi listenin yeni başlığına döndürmesini sağlayın. BarList * barPush (BarList * listesi, Bar * bar) –

2

Evet, işaretçiyi işaretçiden geçirmeniz gerekiyor. C, referanslara göre değil, argümanlara değer verir.

6

Unutmayın, C içinde, HER ŞEY değerle geçirilir.

Sen bunu yapmak istiyorsanız bir işaretçi bir işaretçi geçmesi gerekiyor bu

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

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

} 
2

BarList * l; 

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

Jonathan Leffler yorumlarda listenin yeni başkanı dönen önerdi

Bu klasik bir p Örün. Tahsis edilen düğümü geri döndürün veya işaretçiyi işaretçiyi kullanın. C'de, bir X işaretçisini, X'inizin değiştirilmesini istediğiniz bir işleve iletmeniz gerekir. Bu durumda, bir işaretçinin değiştirilmesini istediğinizden, bir işaretçiye bir işaretçiyi göstermeniz gerekir.

14

Genel cevaplama: Değiştirmek istediğiniz öğeye bir işaretçi aktarın.

Bu durumda, değiştirmek istediğiniz işaretçiyi işaret eder.

İlgili konular