我正在尝试制作一个银行帐户程序,该程序:
创建一个具有帐号,PIN和余额的帐户类别。
帐户编号和PIN通过构造函数输入。
帐号永远不会改变。
可以更改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;
}
}
我正在尝试编写一个可以更改引脚号的函数,但是由于不断出错,我不知道如何编写分配。
最佳答案
Create an account class
class
与执行中的struct
非常相似,但是从概念上讲它们有点不同:在
c
时代,您可能拥有一些属于同一数据(例如,帐号,余额,大头针),因此您可以使用struct
将所有数据打包在一起。您可以将其视为文件柜中的(物理)文件夹-都放在一个地方,但这只是一组数据,仅此而已。那是一个struct
。为了使用该文件夹,您必须获取该文件夹,查看其中的内容,然后决定如何处理它。文件夹中的数据没有真正的保护。这类似于拥有一堆函数,您可以将
struct
的实例传递给该函数,并且该函数可以修改该结构的内容。这是在c
中完成的方式,但是没有数据保护,这可能有点乏味,并且希望有更好的东西。class
具有数据和方法。突然,这不是一个毫无生气的文件夹。现在这是一个实际的奴才-它拥有数据,但是您也可以告诉它为您做些事情,并且知道如何使用自己的数据来完成任务。这样,奴才可以保护数据免受外界干扰,并且仍然可以做有用的工作。因此,正如@Greg所建议的那样,在此处定义类将是更好的方法。您将希望它包含每个帐户唯一的数据,以及将对该数据进行处理的方法(构造函数对其进行初始化,其他方法来更改PIN和余额,可能还需要一些获取方法来查看数据-或至少要进行一些操作)。为调试起见将其打印出来)。
通过这种方式,就不需要引用,但是稍后我将讨论一些数据类型,因为您似乎对此也感到困惑。
数据类型
让我们看看您的帐户结构:
struct account{
char accountNumber[10];
char pin[10];
double balance;
};
什么是
balance
?这是一个浮点数。这意味着它拥有一个数字,其中可以有一个小数点。例如,可以是5、3.7、3.1415926535898,-123,-2.34等,但不能是“dog”,“cat”或字母“q”。什么是
accountNumber
和pin
?您已将它们创建为字符数组(具体来说,长度为10个字符)。那是什么意思?好吧,它们可以容纳一个字符块,不超过9个字符(请记住为空终止符留出空间)。例如,它们可以容纳“1”,“2.3”,“1.2.3.4”,“dog”,“cat”,“^&* $ ^ @ <> X”。请注意,
1
和"1"
之间存在很大的差异。 1
是一个数字。如果我们在计算机内部查看所有的1和0,它将以类似于00000000 00000000 00000000 00000001
的形式存储在内存中。我们通常用十六进制形式写这个数字,因为它更短,看起来像:0x00000001
。它是32位长(也就是4个字节)。这是特定于平台的,但这是最常见的,应该足以与文本“1”形成对比:“1”是两个字符:“1”和“\ 0”(字符-不是数字-一个,以及用于终止字符串的空终止符)。这将在内存中如下所示:
00110001 00000000
或int hex:0x3100
。注意,这要短得多(每个字符是一个字节),因此“1”仅是2个字节,而实际整数是4个字节。而1位在另一个位置。而“1”实际上是十六进制的0x31!了解字符串和数字之间的区别很重要。基本上,字符串用于文本(或用于以人类可读格式打印数字),而数字数据类型用于实际的数字工作。
考虑到这一点,您可能想在这里重新考虑数据类型。
header 与来源,声明与定义
头文件是
C++
缺少Java
所缺少的。这些有时有时会非常棘手和令人讨厌,但在其他方面也很有用。抛开这些,我将只关注实际情况。声明与定义
首先,什么是声明?这是一种告诉编译器“我有事”的方法。这可能看起来过于基础,但将其与定义进行了对比:
定义是一种告诉编译器“这是事物的样子”的方式。
因此,如果要创建一个函数,则声明几乎不需要什么:
int AddTheseNumbers(int a, int b);
这告诉编译器有关
AddTheseNumbers
的信息,我们现在可以编写使用它的代码。编译器知道:int
)-因此它在调用函数之前知道要压入堆栈的数量。 但是请注意编译器不知道的内容:函数实际上是做什么的。那是因为编译器不需要知道这一点。是的,我们最终需要它(显然,没有它,程序将无法运行),但是不需要生成Foo.obj文件(链接器将在生成Program.exe时使用它)。
现在,让我们看一下该函数的定义:
int AddTheseNumbers(int a, int b) {
return a + b;
}
它与声明具有相同的签名-这就是编译器/链接器知道我们正在定义的内容的方式,现在我们有了函数的主体。 body 就是定义。
header 用于声明,源代码用于定义
因此,我们可以使用以下命令创建
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
实例很有用,但是实际上您不能对Foo
做任何事情,因为您不知道其中的内容。class Foo {
int x;
public:
int getX();
};
这是
Foo
的完整声明。编译器知道其中包含什么数据(计算Foo
的完整大小是必需的)以及方法签名(就像上面的函数声明一样)。这足以编写执行以下操作的代码:Foo f;
std::cout << f.getX();
它将进行编译,因为编译器知道为
Foo
分配多少内存以及如何与之交互。它不知道getX
是做什么的,但是它不在乎-这是链接程序的工作。int Foo::getX() {
return x;
}
这是
Foo
的getX
方法的定义。它是相同的签名(返回int,不带参数),其作用域是Foo
本身。请注意,此方法可以简单地使用x
-该方法本身带有Foo
实例,因此它可以访问同一Foo
实例中的所有内容。
关于c++ - C++函数引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21082986/