在〈定義結構〉中示範的 printAcct
函式,參數直接以結構型態宣告,指定結構實例作為引數時,會建立新的實例並複製各個值域。
如果不希望複製的行為發生,可以傳遞位址,例如:
#include <stdio.h>
typedef const char* String;
typedef struct {
String id;
String name;
double balance;
} Account;
void deposit(Account *acct, double amount) {
if(amount <= 0) {
puts("必須存入正數");
return;
}
acct->balance += amount;
}
void withdraw(Account *acct, double amount) {
if(amount > acct->balance) {
puts("餘額不足");
return;
}
acct->balance -= amount;
}
int main() {
Account acct = {"1234-5678", "Justin Lin", 1000};
deposit(&acct, 500);
withdraw(&acct, 200);
// 顯示 Account(1234-5678, Justin Lin, 1300.000000)
printf("Account(%s, %s, %f)\n", acct.id, acct.name, acct.balance);
return 0;
}
如果使用結構宣告的指標來存取成員,必須使用 ->
運算子,因為傳遞的是結構實例的位址,函式中對實例的變更,就是對原結構實例的變更。
以上範例的 withdraw
、deposit
等函式,都是服務於 Account
,若想要的話,也可以令函式成為結構的成員之一,這麼組合有點物件導向語言中,物件與方法的概念,例如:
#include <stdio.h>
#include <stdlib.h>
typedef const char* String;
typedef struct Account {
String id;
String name;
double balance;
char *_to_str;
void (*deposit)(struct Account*, double);
void (*withdraw)(struct Account*, double);
String (*to_str)(struct Account*);
} Account;
void deposit(Account *acct, double amount) {
if(amount <= 0) {
puts("必須存入正數");
return;
}
acct->balance += amount;
}
void withdraw(Account *acct, double amount) {
if(amount > acct->balance) {
puts("餘額不足");
return;
}
acct->balance -= amount;
}
String to_str(Account *acct) {
int n = snprintf(NULL, 0,
"Account(%s, %s, %f)",
acct->id, acct->name, acct->balance
);
if(acct->_to_str != NULL) {
free(acct->to_str);
}
acct->_to_str = malloc((n + 1) * sizeof(char));
snprintf(acct->_to_str, n + 1,
"Account(%s, %s, %f)",
acct->id, acct->name, acct->balance
);
return acct->_to_str;
}
Account* new_account(String id, String name, double balance) {
Account *acct = (Account*) malloc(sizeof(Account));
acct->id = id;
acct->name = name;
acct->balance = balance;
acct->_to_str = NULL;
acct->deposit = deposit;
acct->withdraw = withdraw;
acct->to_str = to_str;
return acct;
}
void del_account(Account *acct) {
free(acct->_to_str);
free(acct);
}
int main() {
Account *acct = new_account("1234-5678", "Justin Lin", 1000);
acct->deposit(acct, 500);
acct->withdraw(acct, 200);
printf("%s\n", acct->to_str(acct));
del_account(acct);
return 0;
}