c++ - C++函数引用

标签 c++ function struct structure account

我正在尝试制作一个银行帐户程序,该程序:

创建一个具有帐号,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”。

什么是accountNumberpin?您已将它们创建为字符数组(具体来说,长度为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;
    }
    

    这是FoogetX方法的定义。它是相同的签名(返回int,不带参数),其作用域是Foo本身。请注意,此方法可以简单地使用x -该方法本身带有Foo实例,因此它可以访问同一Foo实例中的所有内容。

    关于c++ - C++函数引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21082986/

    相关文章:

    c++ - Android中的Jni层

    c++ - 构造函数内部的 Printf 未显示在控制台中

    javascript - 将变量的值作为参数插入,并将其值插入对象的函数参数中

    javascript - 可以省略一组中间的 JavaScript 函数参数吗?

    c - 结构无法在结构中定义新类型和结构

    C++动态链接库和void指针

    c++ - 我什么时候应该在 C++ 中使用单例类?

    jquery - 一个函数具有多个触发器。查询

    c - 指针有问题吗?

    将堆栈内存用于不完整结构的 C 最佳实践