การส่งโครงสร้างไปยังฟังก์ชันใช้ไม่ได้ [ซ้ำกัน]

Aug 16 2020

ในโค้ดด้านล่างฉันได้สร้างฟังก์ชันนอกเหนือจาก main เพื่อแบ่ง int ภายในโครงสร้างออกเป็นครึ่งหนึ่ง

หลังจากนั้นฉันต้องการพิมพ์ค่าใหม่ อย่างไรก็ตามค่าที่พิมพ์ออกมายังคงเป็นค่าแบบเก่า

ฉันเชื่อว่าความรู้พื้นฐานเกี่ยวกับโครงสร้างและตัวชี้ยังไม่ดีพอ

ใครสามารถช่วยฉันด้วยเรื่องนี้? ขอบคุณมาก!!!

typedef struct{
    int age;
    int wage;
}person;


void divide(person A)
{
    person half;
    half.age = A.age / 2;
    half.wage = A.wage / 2;
    
    A = half;
}

int main(void)
{
    person A;
    A.age = 30;
    A.wage = 35000;
    
    divide(A);
    
    printf("%i\n", A.age);

}

คำตอบ

1 Miket25 Aug 16 2020 at 07:56

ฟังก์ชันdivideกำลังแก้ไขสำเนาของโครงสร้างนั้นเนื่องจากโครงสร้างถูกส่งต่อโดยค่า คุณจะต้องส่งตัวชี้ไปยังโครงสร้างเพื่อให้ฟังก์ชันสามารถแก้ไขต้นฉบับได้

void divide(person* A)
{
    person half;

    half.age  = A->age  / 2;
    half.wage = A->wage / 2;
    
    *A = half;
}

เรียกdivideด้วยที่อยู่ของโครงสร้างเดิม

divide(&A);
2 Peter Aug 16 2020 at 08:05

เมื่อคุณผ่านAไปจะdivideมีการสร้างสำเนาAขึ้น การปรับเปลี่ยนภายในสำเนานี้divideไม่มีผลกระทบต่อตัวแปรท้องถิ่นที่คุณกำหนดไว้ในA mainเพื่อแก้ไขปัญหานี้คุณสามารถทำให้การdivideใช้ตัวชี้personไป ตัวชี้แสดงที่อยู่ในหน่วยความจำได้อย่างมีประสิทธิภาพซึ่งคุณสามารถใช้เพื่อเข้าถึงตัวแปรท้องถิ่นที่กำหนดไว้ในฟังก์ชันอื่น ๆ ที่ไม่สามารถเข้าถึงได้ (ค้นคว้าสแต็กเฟรมหากคุณต้องการเข้าใจว่าเหตุใดจึงเป็นเช่นนั้น)

ดังนั้นในทางปฏิบัติคุณเปลี่ยนdivide's ลายเซ็นให้กับ: void divide(person *A)และในบรรทัดสุดท้ายของฟังก์ชั่นนี้คุณ assing ไม่Aแต่สิ่งที่Aจะชี้ไปโดยใช้ประกอบการ dereference *A = halfนี้: ในคุณmainฟังก์ชั่นที่คุณนั้นจากนั้นส่งที่อยู่ของAแทนAตัวเองไปโดยใช้ที่อยู่ของผู้ประกอบการ:dividedivide(&A)

แก้ไข: ดียิ่งขึ้นคุณสามารถหลีกเลี่ยงการสร้างชั่วคราวhalfโดยการดำเนินการโดยตรงA->age /= 2และA->wage /= 2ที่เป็นน้ำตาลประโยคสำหรับA.x(*A).x