كيف يمكنني تعديل مؤشر تم تمريره إلى وظيفة في ج؟
-
12-09-2019 - |
سؤال
لذلك، لدي بعض الكود، نوعا من ما يلي، لإضافة بنية إلى قائمة البناط:
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
}
يتم تعريف هذه الهياكل على النحو التالي:
typedef struct Bar
{
// this isn't too important
} Bar;
#define EMPTY_LIST NULL
typedef struct BarList
{
Bar * val;
struct BarList * nextBar;
} BarList;
ثم في ملف آخر أفعل شيئا مثل ما يلي:
BarList * l;
l = EMPTY_LIST;
barPush(l,&b1); // b1 and b2 are just Bar's
barPush(l,&b2);
ومع ذلك، بعد هذا، لا يزال لا يزال يشير إلى Never_List، وليس الإصدار المعدل الذي تم إنشاؤه داخل Barpush. هل يجب علي اجتياز قائمة بمؤشر إلى مؤشر إذا أردت تعديله، أم أن هناك بعض التعويذ الظلام الآخر مطلوب؟
المحلول
تحتاج إلى المرور في مؤشر إلى مؤشر إذا كنت ترغب في القيام بذلك.
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;
}
ثم استخدمه مثل هذا:
BarList * l;
l = EMPTY_LIST;
barPush(&l,&b1); // b1 and b2 are just Bar's
barPush(&l,&b2);
اقترح جوناثان ليفلر إرجاع الرأس الجديد للقائمة في التعليقات:
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;
}
يصبح الاستخدام:
BarList * l;
l = EMPTY_LIST;
l = barPush(l,&b1); // b1 and b2 are just Bar's
l = barPush(l,&b2);
نصائح أخرى
إجابة عامة: اجتياز مؤشر إلى الشيء الذي تريد تغييره.
في هذه الحالة، سيكون مؤشرا للمؤشر الذي تريد تغييره.
تذكر، في ج، يتم تمرير كل شيء حسب القيمة.
تمر في مؤشر إلى مؤشر، مثل هذا
int myFunction(int** param1, int** param2) {
// now I can change the ACTUAL pointer - kind of like passing a pointer by reference
}
نعم، عليك أن تمر في مؤشر إلى المؤشر. جيم الحجج حسب القيمة، وليس بالرجوع إليها.
هذه مشكلة كلاسيكية. إما إرجاع العقدة المخصصة أو استخدام مؤشر المؤشر. في C، يجب عليك اجتياز مؤشر إلى X إلى وظيفة حيث تريد تعديل X الخاص بك. في هذه الحالة، نظرا لأنك تريد تعديل مؤشر، يجب عليك تمرير مؤشر إلى مؤشر.