2014-01-13 120 views
1

我想製作一個銀行賬戶程序:C++函數使用參考

創建一個賬戶類,它包含一個賬號,一個PIN和一個餘額。 Acct號碼和PIN碼通過構造函數進入。 賬號永遠不會改變。 PIN碼可以更改,但前提是提供了正確的帳號作爲參數。 只有當正確的個人識別號碼和帳戶號碼作爲參數(當然還有新的餘額)提交給此方法時才能更改餘額。 創建一個方法來一起打印帳號和當前餘額。

到目前爲止我有:

#include <iostream> 
#include <string> 
using namespace std; 

//account structure 
struct account{ 
    char accountNumber[10]; 
    char pin[10]; 
    double balance; 
}account1, account2; 

int main() { 

    //set account info 
    account1.accountNumber = 00011; 
    account1.pin = 1234; 
    account1.balance = 0.00; 

    //set account info 
    account2.accountNumber = 00022; 
    account2.pin = 4321; 
    account2.balance = 100.00; 

    //program end 
    return 0; 
} 

//function to change account pin 
void changePin(char accountNumber, char pin, char newPin)//PROBLEM 
{ 
    if(strcmp(accountNumber.pin, pin) == 0) 
    { 
     accountNumber.pin = newPin; 
    } 
    else 
    { 
     cout << "Account number or password incorrect."; 
    } 
} 

//change account balance 
void changeBalance(char number, char pin, double newBalance)//PROBLEM 
{ 
    if((strcmp(account.pin, pin) == 0) && (strcmp(account.accountNumber, number) == 0)) 
     { 
      account.balance = newBalance; 
     } 
    else 
    { 
     cout >> "Account number or pin incorrect."; 
    } 
} 

//function to print account number and balance 
void printInfo(char accountNumber)//PROBLEM 
{ 
    cout << "Account Number: " << account.accountNumber; 
    cout << "Account Balance: " << account.balance; 
} 

現在我的問題是,我不知道如何引用我想要的帳戶的功能比較進入信息是否經常賬戶信息匹配。

編輯: 我幾乎我的程序做,我只是遇到一個問題在這裏:

class Account; 
class Account{ 

public: 
    int accountNumber; 
    char pin[5]; 
    double balance; 

    void printInfo(); 
    void changeBalance(int n, char * p, double b); 
    void changePin(int n, char * p, char * newPin); 
}; 
void Account::changePin(int n, char * p, char * newPin) 
{ 
    if((n == accountNumber) && (strcmp(p, pin) == 0)) 
    { 
     //pin = newPin; 
    } 
} 

我嘗試寫才能改變管腳數的函數,但我不知道如何寫作業,因爲我不斷收到錯誤。

+0

既然你已經標記了這個'C++',那麼你想在'account'對象上使用* methods *來完成這種事情似乎是合乎邏輯的。這樣,你就可以通過引用一個現有的帳戶來調用該方法。這聽起來合理嗎? –

+0

你似乎是新來的C++。你是一般的編程新手,還是來自不同的語言?這可能有助於我們用您更熟悉的術語來解釋。 – Tim

+0

我已經做了一點的Java,但是啊,我剛剛開始C++ – user3188716

回答

2

創建一個帳戶類

一個class非常相似,在執行一個struct,但在概念上他們有點不同:

c的日子裏,你可能有一些屬於一起的數據(例如帳號,餘額,別針),因此您可以使用struct將它們全部保存在一個包中。您可以將其視爲文件櫃中的(物理)文件夾 - 全部集中在一個地方,但它僅僅是一個數據集合,僅此而已。這是一個struct

爲了使用該文件夾,您必須獲取文件夾,查看其中的內容,並決定如何處理它。對文件夾中的數據沒有真正的保護。這類似於可以將一個struct的實例傳遞給一組函數,並且該函數可以修改該結構的內容。這是在c中完成的事情,但是沒有數據保護,它可能有點乏味,並且希望有更好的東西。

A class有數據和方法。突然間,這不是一個無生氣的文件夾被傳遞。現在它是一個實際的小事件 - 它保存着數據,但你也可以告訴它爲你做些事情,並知道如何使用自己的數據來完成任務。這樣,僕從可以保護數據免受外部干擾,並且仍然可以做有用的工作。

所以,正如@Greg所說,定義一個類將是一個更好的方法。您會希望它包含每個帳戶獨有的數據,以及將使用該數據進行處理的方法(構造函數將其初始化,其他方法可更改PIN和平衡值,並可能包含一些獲取器以查看數據 - 或者至少爲了調試打印它)。

通過這樣做,不需要引用,但我稍後會談談一些關於數據類型的內容,因爲您似乎也對此感到困惑。

數據類型

讓我們來看看您的帳戶結構:

struct account{ 
    char accountNumber[10]; 
    char pin[10]; 
    double balance; 
}; 

什麼是balance?這是一個浮點數。這意味着它包含一個數字,它可以有一個小數點。例如,它可以是5,3.7,3.1415926535898,-123,-2.34等,但它不能是「狗」,「貓」,也不能是「q」字母。

什麼是accountNumberpin?您已將它們創建爲字符數組(特別是,10個字符長)。那是什麼意思?那麼,他們可以容納一個字符塊,9個字符或更少(記住爲空終止符留出空間)。例如,他們可以持有「1」,「2.3」,「1.2.3.4」,「狗」,「貓」,「X」。

請注意,1"1"之間存在差異。 1是一個數字。如果我們在計算機內部查看所有的零和零計算機,它將存儲在內存中,如00000000 00000000 00000000 00000001。我們通常以十六進制編寫這樣的數字,因爲它更短,並且看起來像:0x00000001。它有32位長(又名4字節)。這是平臺特定的,但這是最常見的,應該足以與文本「1」對比:「1」是兩個字符:'1'和'\ 0'(字符 - - 不是數字 - 一個,以及一個結束字符串的空終止符)。這將在內存中是這樣的:00110001 00000000 - 或int十六進制:0x3100。請注意,這是很短的(每個字符是一個字節),所以「1」只有2個字節,而實際的整數是4個字節。而1位是在不同的地方。而'1'實際上是十六進制0x31!

理解字符串和數字之間的區別很重要。基本上,字符串用於文本(或用於以可讀格式打印數字),而數字數據類型用於實際的數字工作。

考慮到這一點,您可能想要在這裏重新考慮您的數據類型。

頭VS來源,宣言VS定義

東西C++Java缺乏,是頭文件。這些可能會非常棘手和煩人,但在其他方面也很有用。除此之外,我只關注實際發生的事情。

聲明VS定義

首先,什麼是一個聲明?這是告訴編譯器「我有一件事」的一種方式。這可能看起來過於基本,但與定義相反:

A 定義是一種告訴編譯器的方法「這是事情的樣子。」

所以,如果你想創建一個功能,有很少多數民衆贊成所需聲明:

int AddTheseNumbers(int a, int b); 

這告訴編譯器有足夠的瞭解AddTheseNumbers,我們現在可以編寫一個使用它的代碼。編譯器知道:

  • 函數的名稱。
  • 函數的返回值 - 因此它知道堆棧上有多少空間用於返回。
  • 參數(兩個int s,按值傳遞) - 所以它知道在調用函數之前要推入堆棧多少。

但是請注意什麼編譯器不知道知道:該函數實際上做了什麼。這是因爲編譯器不需要知道這一點。是的,我們最終需要它(顯然一個程序不能沒有它運行),但不需要生成Foo.obj文件(鏈接器將在生成Program.exe時使用它)。

現在讓我們來看看定義,功能

int AddTheseNumbers(int a, int b) { 
    return a + b; 
} 

這是相同的簽名的聲明 - 這是編譯器/連接怎麼知道我們在界定什麼,現在我們具有機構的功能。 正文是定義。

頭對於聲明,來源是用於定義

所以,我們可以創建Simple.h有:

int AddTheseNumbers(int a, int b); 

而且Simple.cpp有:

int AddTheseNumbers(int a, int b) { 
    return a + b; 
} 

其中我們可以再編譯創建Simple.obj

而且,我們可以創建MyProgram.cpp有:

#include "Simple.h" // Hey look, I can now use my other file! 

int main(int argc, char** argv) { 
    std::cout << "Adding 3 + 5: " << AddTheseNumbers(3, 5) << std::endl; 
    return 0; 
} 

我們可以編譯成MyProgram.obj。然後我們使用連接器將這些obj文件鏈接在一起,生成MyProgram.exe,然後我們可以運行它們。

這個稍微複雜得連班。簡單地說,一類Foo,我們可以這樣做:

class Foo; 

這就是所謂的向前聲明,而只是告訴編譯器「有一個結構稱爲富,但我不知道什麼是在它」。這對於通過引用或指針傳遞Foo的實例很有用,但是您實際上無法對Foo執行任何操作,因爲您不知道其中的內容。

class Foo { 
    int x; 
public: 
    int getX(); 
}; 

這是Foo的完整聲明。編譯器知道它裏面的數據(這是計算Foo的全部大小所必需的)和方法簽名(就像上面的函數聲明一樣)。這足以寫代碼,做:

Foo f; 
std::cout << f.getX(); 

它將編譯,因爲編譯器知道多少內存要分配給Foo,以及如何與它進行交互。它不知道什麼getX做什麼,但它並不在乎 - 這是鏈接器的工作。

int Foo::getX() { 
    return x; 
} 

這是FoogetX方法的定義。它是相同的簽名(返回int,無參數),它的作用域本身是Foo。請注意,此方法可以簡單地使用x - 方法本身的實例爲Foo,因此它可以訪問同一個Foo實例中的所有內容。

+0

我現在得到它。另一個問題是,我只是把我在結構中的東西放到一個新的cpp文件中嗎?我該如何處理.h文件? – user3188716

+0

好問題。快速回答:.h文件用於聲明,.cpp文件用於定義。我會在我的答案中提供更多細節。 – Tim

+0

爲你以前的長答案,所以我應該改變我的數據類型爲int?問題是如果我想讓我的帳號/密碼從零開始。 00123,如果它是一個int而不是一個字符串,程序是否會讀取/打印爲123? – user3188716