Menu
CoddyTech

传递结构体指针

本课属于 Coddy C 学习旅程的“逻辑与流程”单元。第 47 课,共 63 课。

按值传递结构体适合读取数据,但对于较大的结构体来说效率不高,因为整个结构体都会被复制。更重要的是,你无法在函数内部修改原始结构体。这时,传递指向结构体的指针就非常重要。

当你传递指向结构体的指针,而不是结构体本身时,函数会接收到原始结构体的内存地址。这种方式有两个主要优点:效率更高(无需复制),而且函数可以修改原始数据。

接受指向结构体的指针的函数语法如下:

void functionName(struct StructureName *ptr) {
    // 使用 ptr->member 的函数体
}

在函数内部,你可以使用箭头运算符访问和修改结构体成员。通过指针进行的任何更改都会直接影响调用函数中的原始结构体,因此这种方式非常适合需要更新或转换结构体数据的函数。

这种技术对于编写能够处理复杂数据结构的高效 C 程序至关重要,因为它结合了指针的强大功能和结构体的组织方式。

challenge icon

挑战

简单

创建一个 C 程序,演示如何将指向结构体的指针传递给函数,以高效地修改数据。你的程序应:

  1. 定义一个名为 BankAccount 的 struct,包含以下成员:
    • 一个整数 accountNumber,用于存储账户号码
    • 一个大小为 30 的字符数组 ownerName,用于存储账户所有者的姓名
    • 一个浮点数 balance,用于存储账户余额
    • 一个整数 transactionCount,用于存储交易次数
  2. 编写一个名为 depositMoney 的函数,该函数:
    • 接收指向 BankAccount 结构体的指针和一个浮点数金额作为参数
    • 使用箭头运算符将金额加到账户余额中
    • 将交易次数加 1
    • 打印 Deposit successful. New balance: [balance]
  3. 编写一个名为 withdrawMoney 的函数,该函数:
    • 接收指向 BankAccount 结构体的指针和一个浮点数金额作为参数
    • 检查取款金额是否大于当前余额
    • 如果余额不足,打印 Insufficient funds. Current balance: [balance]
    • 如果余额充足,从余额中扣除该金额,将交易次数加 1,并打印 Withdrawal successful. New balance: [balance]
  4. 编写一个名为 displayAccount 的函数,该函数:
    • 接收指向 BankAccount 结构体的指针作为参数
    • 按照以下确切格式打印账户信息:
      • Account Information:
      • Account Number: [accountNumber]
      • Owner: [ownerName]
      • Balance: [balance]
      • Transactions: [transactionCount]
  5. 在 main 函数中:
    • 创建一个名为 account 的 BankAccount 变量
    • 从输入中读取账户号码、所有者姓名和初始余额
    • 将交易次数设为 0
    • 调用 displayAccount,显示账户的初始状态
    • 读取存款金额并调用 depositMoney
    • 读取取款金额并调用 withdrawMoney
    • 调用 displayAccount,显示账户的最终状态

这个挑战展示了将指向结构体的指针传递给函数的优势。与按值传递不同,函数接收的是原始结构体的内存地址,因此可以直接修改原始数据。这种方式效率更高(无需复制),还能让函数永久修改调用函数中的结构体值。

亲手试试

#include <stdio.h>
#include <string.h>

// TODO:在这里定义 BankAccount 结构体

// TODO:在这里编写 depositMoney 函数

// TODO:在这里编写 withdrawMoney 函数

// TODO:在这里编写 displayAccount 函数

int main() {
    // 读取输入
    int accountNum;
    char ownerName[30];
    float initialBalance;
    float depositAmount;
    float withdrawAmount;
    
    scanf("%d", &accountNum);
    scanf("%s", ownerName);
    scanf("%f", &initialBalance);
    scanf("%f", &depositAmount);
    scanf("%f", &withdrawAmount);
    
    // TODO:创建 BankAccount 变量并初始化
    
    // TODO:调用 displayAccount 显示初始状态
    
    // TODO:将存款金额传给 depositMoney 并调用它
    
    // TODO:将取款金额传给 withdrawMoney 并调用它
    
    // TODO:调用 displayAccount 显示最终状态
    
    return 0;
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

逻辑与流程中的所有课

自己练习: C 在线编译器