在〈定義結構〉中示範的printAcct 函式,參數直接以結構型態宣告,指定結構實例 ... 函式成為結構的成員之一,這麼組合有點物件導向語言中,物件與方法的概念,例如:
回C語言目錄
在〈定義結構〉中示範的printAcct函式,參數直接以結構型態宣告,指定結構實例作為引數時,會建立新的實例並複製各個值域。
如果不希望複製的行為發生,可以傳遞位址,例如:
#include
typedefconstchar*String;
typedefstruct{
Stringid;
Stringname;
doublebalance;
}Account;
voiddeposit(Account*acct,doubleamount){
if(amount<=0){
puts("必須存入正數");
return;
}
acct->balance+=amount;
}
voidwithdraw(Account*acct,doubleamount){
if(amount>acct->balance){
puts("餘額不足");
return;
}
acct->balance-=amount;
}
intmain(){
Accountacct={"1234-5678","JustinLin",1000};
deposit(&acct,500);
withdraw(&acct,200);
//顯示Account(1234-5678,JustinLin,1300.000000)
printf("Account(%s,%s,%f)\n",acct.id,acct.name,acct.balance);
return0;
}
如果使用結構宣告的指標來存取成員,必須使用->運算子,因為傳遞的是結構實例的位址,函式中對實例的變更,就是對原結構實例的變更。
以上範例的withdraw、deposit等函式,都是服務於Account,若想要的話,也可以令函式成為結構的成員之一,這麼組合有點物件導向語言中,物件與方法的概念,例如:
#include
#include
typedefconstchar*String;
typedefstructAccount{
Stringid;
Stringname;
doublebalance;
char*_to_str;
void(*deposit)(structAccount*,double);
void(*withdraw)(structAccount*,double);
String(*to_str)(structAccount*);
}Account;
voiddeposit(Account*acct,doubleamount){
if(amount<=0){
puts("必須存入正數");
return;
}
acct->balance+=amount;
}
voidwithdraw(Account*acct,doubleamount){
if(amount>acct->balance){
puts("餘額不足");
return;
}
acct->balance-=amount;
}
Stringto_str(Account*acct){
intn=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
);
returnacct->_to_str;
}
Account*new_account(Stringid,Stringname,doublebalance){
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;
returnacct;
}
voiddel_account(Account*acct){
free(acct->_to_str);
free(acct);
}
intmain(){
Account*acct=new_account("1234-5678","JustinLin",1000);
acct->deposit(acct,500);
acct->withdraw(acct,200);
printf("%s\n",acct->to_str(acct));
del_account(acct);
return0;
}