首页 > 其他分享 >面向象和面向过程的区别

面向象和面向过程的区别

时间:2024-10-10 10:12:46浏览次数:8  
标签:BankAccount account 区别 self amount 余额 面向 balance 过程

银行账户管理

用户:

int balance = 0;
void deposit(int amount) {
balance += amount;
}
void withdraw(int amount) {
if (amount <= balance) {
balance -= amount;
}
} 解释代码

ChatGPT:

这段代码是一个简单的银行账户管理示例,使用了 C++ 或类似语言的语法。下面是对代码的逐行解释:

int balance = 0;
  • 这里定义了一个整型变量 balance,并初始化为 0。这个变量用来表示账户的当前余额。
void deposit(int amount) {
    balance += amount;
}
  • 这是一个名为 deposit 的函数,它接受一个整型参数 amount,表示要存入的金额。
  • 在函数内部,通过 balance += amount; 将存入的金额添加到当前余额中。这意味着调用这个函数时,账户余额会增加相应的存款金额。
void withdraw(int amount) {
    if (amount <= balance) {
        balance -= amount;
    }
}
  • 这是一个名为 withdraw 的函数,它同样接受一个整型参数 amount,表示要提取的金额。
  • 函数内部首先检查 amount 是否小于或等于当前的 balance(即检查账户是否有足够的余额)。如果条件成立,则通过 balance -= amount; 从余额中扣除提取的金额。
  • 如果账户余额不足以满足提款请求,则不会进行任何操作,这样可以防止透支。

总结

  • 这段代码实现了一个简单的存款和取款功能,允许用户向账户存入资金或从中提取资金,同时确保在提款时不会超过当前余额。

用户:

int main() {
BankAccount myAccount;
myAccount.deposit(1000);
myAccount.withdraw(500);
// 可以添加代码来显示或使用 myAccount 的 balance
return 0;
} 这段什么意思

ChatGPT:

这段代码是一个 C++ 程序的 main 函数部分,展示了如何使用一个名为 BankAccount 的类来管理银行账户。下面是对代码的逐行解释:

int main() {
  • 这是程序的入口点,main 函数是每个 C++ 程序的起始执行位置。
    BankAccount myAccount;
  • 这里创建了一个名为 myAccountBankAccount 类的实例(对象)。假设 BankAccount 类已经在其他地方定义,并包含存款和取款的功能。
    myAccount.deposit(1000);
  • 调用 myAccount 对象的 deposit 方法,将 1000 存入账户。这意味着账户的余额将增加 1000
    myAccount.withdraw(500);
  • 调用 myAccount 对象的 withdraw 方法,从账户中提取 500。如果账户余额足够,这将导致余额减少 500
    // 可以添加代码来显示或使用 myAccount 的 balance
  • 这是一条注释,提示开发者可以在这里添加代码来显示或使用 myAccount 的余额。具体的显示方法取决于 BankAccount 类的实现。
    return 0;
}
  • return 0; 表示程序成功结束,返回值 0 通常表示没有错误。

总结

这段代码展示了如何创建一个银行账户对象,并通过调用其方法进行存款和取款操作。具体的余额管理和显示功能依赖于 BankAccount 类的实现。

用户:

所以写了一个类,之后就可以反复调用这个类创建对象(实例)是吗,类就相当于一个面包模具,每次做相同款式的面包用它就好了

ChatGPT:

是的,你的理解非常正确!在面向对象编程(OOP)中,类确实可以被视为一个“模具”或“模板”,用于创建对象(实例)。下面是对这个概念的进一步解释:

类与对象的关系

  1. 类(Class)

    • 类是一个蓝图或模板,定义了一组属性(数据)和方法(功能)。它描述了对象的特征和行为。
    • 例如,在银行账户的例子中,BankAccount 类可能包含属性如 balance(余额)和方法如 deposit(存款)和 withdraw(取款)。
  2. 对象(Object)

    • 对象是类的实例。每次使用类创建一个对象时,都会生成一个新的实例,具有类定义的属性和方法。
    • 例如,myAccountBankAccount 类的一个对象。你可以创建多个 BankAccount 对象,每个对象都有自己的余额和状态。

类的重复使用

  • 一旦定义了一个类,你可以反复使用它来创建多个对象。例如,你可以创建多个银行账户对象,每个对象都有独立的余额和操作。
  • 这就像使用同一个面包模具,每次都可以做出相同款式的面包,但每个面包都是独立的,具有自己的特性。

示例

class BankAccount {
public:
    int balance = 0;

    void deposit(int amount) {
        balance += amount;
    }

    void withdraw(int amount) {
        if (amount <= balance) {
            balance -= amount;
        }
    }
};

int main() {
    BankAccount account1; // 创建第一个银行账户对象
    account1.deposit(1000);
    account1.withdraw(500);

    BankAccount account2; // 创建第二个银行账户对象
    account2.deposit(2000);
    account2.withdraw(1500);

    // account1 和 account2 是独立的对象,各自有自己的余额
    return 0;
}

在这个示例中,account1account2 是两个独立的 BankAccount 对象,它们各自维护自己的余额。你可以对它们进行不同的操作,而不会相互影响。

总结

类提供了一种组织和管理代码的方式,使得可以创建多个具有相似特征和行为的对象,从而提高代码的重用性和可维护性。

用户:

那面向过程的编程是不是就没有“对象”的概念

ChatGPT:

是的,面向过程的编程(Procedural Programming)与面向对象的编程(Object-Oriented Programming)在设计理念和结构上有显著的不同。下面是对这两种编程范式的比较,特别是关于“对象”概念的区别:

面向过程的编程

  1. 基本概念

    • 面向过程的编程主要围绕“过程”或“函数”来组织代码。程序被视为一系列的步骤或操作,通常是通过函数调用来实现的。
    • 数据和操作数据的函数是分开的,数据通常以结构体或简单变量的形式存在。
  2. 没有对象的概念

    • 在面向过程的编程中,没有“对象”的概念。所有的数据和功能都是分开的,数据通过参数传递给函数,函数对数据进行处理。
    • 例如,处理银行账户的程序可能会有一个结构体来表示账户信息,以及一组函数来处理存款和取款。
  3. 示例

    struct BankAccount {
        int balance;
    };
    
    void deposit(BankAccount* account, int amount) {
        account->balance += amount;
    }
    
    void withdraw(BankAccount* account, int amount) {
        if (amount <= account->balance) {
            account->balance -= amount;
        }
    }
    
    int main() {
        BankAccount myAccount = {0}; // 初始化账户
        deposit(&myAccount, 1000);
        withdraw(&myAccount, 500);
        return 0;
    }
    

面向对象的编程

  1. 基本概念

    • 面向对象的编程围绕“对象”来组织代码。对象是类的实例,封装了数据和操作数据的方法。
    • 数据和操作数据的功能被封装在一起,形成一个完整的实体。
  2. 有对象的概念

    • 在面向对象的编程中,数据和方法是结合在一起的,形成对象。对象可以通过方法来操作其内部状态。
    • 这使得代码更具可读性和可维护性,因为相关的功能和数据被组织在一起。
  3. 示例

    class BankAccount {
    public:
        int balance;
    
        BankAccount() : balance(0) {} // 构造函数初始化余额
    
        void deposit(int amount) {
            balance += amount;
        }
    
        void withdraw(int amount) {
            if (amount <= balance) {
                balance -= amount;
            }
        }
    };
    
    int main() {
        BankAccount myAccount; // 创建银行账户对象
        myAccount.deposit(1000);
        myAccount.withdraw(500);
        return 0;
    }
    

总结

  • 面向过程的编程:强调过程和函数,数据和功能分开,没有对象的概念。
  • 面向对象的编程:强调对象和类,数据和功能结合在一起,提供了更高的抽象层次和代码重用性。

因此,面向过程的编程确实没有“对象”的概念,而是通过函数和数据结构来实现程序的逻辑。

用户:

我看不懂你给的面向过程的编程的示例程序,能给我讲解一下吗?

ChatGPT:

当然可以!下面是对面向过程编程示例程序的详细讲解:

示例程序

#include <stdio.h>

struct BankAccount {
    int balance; // 账户余额
};

// 存款函数
void deposit(BankAccount* account, int amount) {
    account->balance += amount; // 增加账户余额
}

// 取款函数
void withdraw(BankAccount* account, int amount) {
    if (amount <= account->balance) { // 检查余额是否足够
        account->balance -= amount; // 减少账户余额
    }
}

int main() {
    BankAccount myAccount = {0}; // 初始化账户,余额为0
    deposit(&myAccount, 1000); // 存入1000
    withdraw(&myAccount, 500); // 取出500
    printf("当前余额: %d\n", myAccount.balance); // 打印当前余额
    return 0;
}

代码讲解

  1. 结构体定义

    struct BankAccount {
        int balance; // 账户余额
    };
    
    • 这里定义了一个名为 BankAccount 的结构体,它包含一个整数类型的成员 balance,用于存储账户的余额。
  2. 存款函数

    void deposit(BankAccount* account, int amount) {
        account->balance += amount; // 增加账户余额
    }
    
    • deposit 函数接受两个参数:一个指向 BankAccount 结构体的指针 account 和一个整数 amount(存款金额)。
    • 使用 account->balance 访问结构体中的 balance 成员,并将存款金额加到余额上。
  3. 取款函数

    void withdraw(BankAccount* account, int amount) {
        if (amount <= account->balance) { // 检查余额是否足够
            account->balance -= amount; // 减少账户余额
        }
    }
    
    • withdraw 函数同样接受一个指向 BankAccount 的指针和一个整数 amount(取款金额)。
    • 在取款之前,函数会检查账户余额是否足够。如果余额足够,则从余额中减去取款金额。
  4. 主函数

    int main() {
        BankAccount myAccount = {0}; // 初始化账户,余额为0
        deposit(&myAccount, 1000); // 存入1000
        withdraw(&myAccount, 500); // 取出500
        printf("当前余额: %d\n", myAccount.balance); // 打印当前余额
        return 0;
    }
    
    • main 函数中,首先创建一个 BankAccount 类型的变量 myAccount,并将其余额初始化为 0。
    • 然后调用 deposit 函数,将 1000 存入账户。
    • 接着调用 withdraw 函数,从账户中取出 500。
    • 最后,使用 printf 打印当前余额。

总结

  • 这个程序展示了如何使用面向过程的编程来管理银行账户。数据(账户余额)和操作(存款和取款)是分开的。
  • 通过结构体来存储账户信息,通过函数来处理存款和取款的逻辑。
  • 这种方式虽然有效,但在处理复杂的程序时,可能会导致数据和功能的管理变得更加困难,因为它们没有被封装在一起。

用户:

我看不懂第二点存款函数,指针是什么?

ChatGPT:

指针是编程语言中一个非常重要的概念,尤其是在 C 语言中。下面是对指针的详细解释,以及它在存款函数中的作用。

什么是指针?

  1. 定义

    • 指针是一个变量,它存储的是另一个变量的内存地址。换句话说,指针指向某个数据的存储位置。
  2. 基本概念

    • 每个变量在内存中都有一个地址,指针可以用来引用这个地址。
    • 指针的类型决定了它所指向的数据类型。例如,int* 是一个指向整数的指针,char* 是一个指向字符的指针。
  3. 声明指针

    • 在 C 语言中,声明一个指针的语法如下:

      int* ptr; // ptr 是一个指向整数的指针
      
  4. 获取地址

    • 使用 & 运算符可以获取一个变量的地址。例如:

      int a = 10;
      int* ptr = &a; // ptr 现在指向变量 a 的地址
      
  5. 解引用指针

    • 使用 * 运算符可以访问指针所指向的值。例如:

      int value = *ptr; // 通过 ptr 获取 a 的值
      

存款函数中的指针

在存款函数中,指针的使用是为了能够直接修改传入的 BankAccount 结构体的内容。让我们再看一下存款函数的代码:

void deposit(BankAccount* account, int amount) {
    account->balance += amount; // 增加账户余额
}

解释:

  1. 参数

    • BankAccount* account:这里的 account 是一个指向 BankAccount 结构体的指针。它允许函数访问和修改传入的账户信息。
  2. 使用指针

    • account->balance:使用 -> 运算符可以访问指针所指向的结构体的成员。在这里,account 指向一个 BankAccount 结构体,因此可以通过 account->balance 来访问和修改该结构体的 balance 成员。
  3. 为什么使用指针

    • 如果不使用指针,而是直接传递 BankAccount 结构体(即按值传递),函数将会接收到结构体的一个副本。这样,函数对副本的修改不会影响原始的 BankAccount 结构体。
    • 使用指针可以直接修改原始结构体的内容,从而实现存款操作。

总结

  • 指针是存储变量地址的变量,允许我们直接访问和修改内存中的数据。
  • 在存款函数中,使用指针可以让我们直接修改传入的 BankAccount 结构体的余额,而不是修改其副本。这使得存款操作能够影响到原始的账户数据。

用户:

看完了,谢谢你,但是我还有两处没懂,1.通过结构体来存储账户信息,通过函数来处理存款和取款的逻辑。①结构体是什么
2.这种方式虽然有效,但在处理复杂的程序时,可能会导致数据和功能的管理变得更加困难,因为它们没有被封装在一起。②为什么说他没有封装在一起

ChatGPT:

当然可以!下面是对你提到的两个问题的详细解释。

1. 结构体是什么?

结构体(struct)是 C 语言中一种用户定义的数据类型,用于将不同类型的数据组合在一起。它允许你将多个相关的变量(称为成员)组织在一个单一的复合数据类型中。

结构体的基本概念:

  • 定义结构体
    你可以使用 struct 关键字来定义一个结构体。例如,下面是一个定义 BankAccount 结构体的示例:

    struct BankAccount {
        int balance; // 账户余额
        char accountHolder[50]; // 账户持有者的名字
    };
    
  • 成员
    在这个结构体中,balanceaccountHolder 是结构体的成员。balance 是一个整数,表示账户的余额;accountHolder 是一个字符数组,用于存储账户持有者的名字。

  • 创建结构体变量
    一旦定义了结构体,你可以创建结构体的实例(变量):

    struct BankAccount myAccount; // 创建一个 BankAccount 类型的变量
    myAccount.balance = 1000; // 设置余额
    strcpy(myAccount.accountHolder, "Alice"); // 设置账户持有者的名字
    
  • 访问结构体成员
    使用点运算符(.)来访问结构体的成员:

    printf("账户持有者: %s\n", myAccount.accountHolder);
    printf("账户余额: %d\n", myAccount.balance);
    

2. 为什么说它没有封装在一起?

封装是面向对象编程(OOP)中的一个重要概念,指的是将数据和操作数据的函数组合在一起,从而隐藏内部实现细节,只暴露必要的接口。在面向过程编程中,数据和功能是分开的,这就是为什么说它没有封装在一起。

具体解释:

  • 数据和功能分开
    在面向过程编程中,数据(如 BankAccount 结构体)和操作这些数据的函数(如 depositwithdraw)是分开的。你可以在程序的不同部分使用这些函数,但它们并不直接与数据结构关联。

  • 缺乏数据保护
    由于数据和功能分开,任何地方的代码都可以直接访问和修改结构体的成员。这可能导致数据的不一致性或错误。例如,如果没有适当的检查,程序的其他部分可能会直接修改 balance,而不通过 depositwithdraw 函数,这样就可能导致不正确的余额。

  • 难以管理复杂性
    当程序变得复杂时,管理数据和功能的关系会变得更加困难。你需要确保所有对数据的访问都通过适当的函数进行,这可能会导致代码的可维护性降低。

总结

  • 结构体是将不同类型的数据组合在一起的用户定义数据类型,允许你将相关的信息组织在一起。
  • 在面向过程编程中,数据和功能是分开的,缺乏封装,这可能导致数据管理变得复杂和不安全。面向对象编程通过将数据和操作数据的函数封装在一起,提供了更好的数据保护和管理方式。

用户:

面向对象的编程数据和功能是不分开的,从哪里体现

ChatGPT:

面向对象编程(OOP)通过以下几个关键概念将数据和功能结合在一起,体现了数据和功能不分开的特性:

1. 类和对象

  • :类是面向对象编程的基本构建块,它定义了一种数据类型,包括数据(属性)和操作这些数据的函数(方法)。类可以被视为一个蓝图,用于创建对象。

  • 对象:对象是类的实例,包含了类定义的属性和方法。每个对象都有自己的状态(属性值)和行为(方法)。

示例:

class BankAccount:
    def __init__(self, account_holder, balance=0):
        self.account_holder = account_holder  # 属性
        self.balance = balance  # 属性

    def deposit(self, amount):  # 方法
        self.balance += amount

    def withdraw(self, amount):  # 方法
        if amount <= self.balance:
            self.balance -= amount
        else:
            print("余额不足")

# 创建对象
my_account = BankAccount("Alice", 1000)
my_account.deposit(500)  # 调用方法
print(my_account.balance)  # 1500

2. 封装

  • 封装是将数据和操作数据的函数组合在一起的过程。通过封装,类的内部状态(属性)可以被保护,外部代码不能直接访问或修改这些属性,而是通过类提供的方法进行操作。

示例:

在上面的 BankAccount 类中,balance 属性是封装的,外部代码不能直接修改它,只能通过 depositwithdraw 方法来改变余额。这种方式确保了对余额的操作是安全的。

3. 继承

  • 继承允许一个类(子类)继承另一个类(父类)的属性和方法。这样,子类可以重用父类的功能,同时可以扩展或修改这些功能。

示例:

class SavingsAccount(BankAccount):  # 继承
    def __init__(self, account_holder, balance=0, interest_rate=0.01):
        super().__init__(account_holder, balance)  # 调用父类构造函数
        self.interest_rate = interest_rate

    def apply_interest(self):
        self.balance += self.balance * self.interest_rate

# 创建 SavingsAccount 对象
savings_account = SavingsAccount("Bob", 2000)
savings_account.apply_interest()  # 调用子类方法
print(savings_account.balance)  # 2020.0

4. 多态

  • 多态允许不同类的对象以相同的方式调用相同的方法。通过多态,程序可以使用统一的接口来处理不同类型的对象。

示例:

def process_account(account: BankAccount):
    account.deposit(100)  # 对不同类型的账户调用相同的方法

# 可以传入 BankAccount 或其子类的对象
process_account(my_account)
process_account(savings_account)

总结

面向对象编程通过类和对象的概念、封装、继承和多态等特性,将数据和功能紧密结合在一起。这种方式使得数据的管理更加安全和高效,同时提高了代码的可维护性和可重用性。通过封装,数据的内部状态被保护,外部只能通过定义好的方法进行访问和修改,从而实现了数据和功能的不分开。

用户:

我看不懂你给的三个示例,你先给我讲第一个示例

ChatGPT:

当然可以!我们来详细讲解第一个示例,关于 BankAccount 类的定义和使用。

示例代码

class BankAccount:
    def __init__(self, account_holder, balance=0):
        self.account_holder = account_holder  # 属性
        self.balance = balance  # 属性

    def deposit(self, amount):  # 方法
        self.balance += amount

    def withdraw(self, amount):  # 方法
        if amount <= self.balance:
            self.balance -= amount
        else:
            print("余额不足")

# 创建对象
my_account = BankAccount("Alice", 1000)
my_account.deposit(500)  # 调用方法
print(my_account.balance)  # 1500

逐行解释

  1. 定义类

    class BankAccount:
    

    这里我们定义了一个名为 BankAccount 的类。这个类将用于表示银行账户。

  2. 构造函数

    def __init__(self, account_holder, balance=0):
    
    • __init__ 是一个特殊的方法,称为构造函数。当我们创建一个 BankAccount 对象时,这个方法会被自动调用。
    • account_holder 是账户持有者的名字,balance 是账户的初始余额,默认为 0。
  3. 属性

    self.account_holder = account_holder  # 属性
    self.balance = balance  # 属性
    
    • self.account_holderself.balance 是类的属性(成员变量),用于存储账户持有者的名字和账户余额。
    • self 代表当前对象的实例,允许我们在类的方法中访问和修改对象的属性。
  4. 存款方法

    def deposit(self, amount):  # 方法
        self.balance += amount
    
    • deposit 是一个方法,用于向账户中存款。
    • amount 是存款的金额。方法内部通过 self.balance += amount 将存款金额加到当前余额上。
  5. 取款方法

    def withdraw(self, amount):  # 方法
        if amount <= self.balance:
            self.balance -= amount
        else:
            print("余额不足")
    
    • withdraw 是一个方法,用于从账户中取款。
    • 方法首先检查请求的取款金额是否小于或等于当前余额。如果是,则从余额中减去取款金额;如果不是,则打印“余额不足”的提示。
  6. 创建对象

    my_account = BankAccount("Alice", 1000)
    
    • 这里我们创建了一个 BankAccount 对象,名为 my_account,账户持有者是 "Alice",初始余额为 1000。
  7. 调用存款方法

    my_account.deposit(500)  # 调用方法
    
    • 通过 my_account 对象调用 deposit 方法,存入 500。此时,my_account.balance 的值将变为 1500。
  8. 打印余额

    print(my_account.balance)  # 1500
    
    • 最后,我们打印 my_account 的余额,输出结果为 1500。

总结

这个示例展示了如何使用面向对象编程来创建一个银行账户类。通过定义属性和方法,我们将数据(账户持有者和余额)和操作这些数据的功能(存款和取款)结合在一起。这种方式使得代码更易于管理和维护,因为所有与银行账户相关的逻辑都封装在 BankAccount 类中。

用户:

第二点构造函数部分没懂,怎么突然在类中用了一个构造函数,为什么当创建一个 BankAccount 对象时,这个函数会被自动调用,def、self是什么,这个函数的语法是什么,我的问题有点多,还是希望你耐心回答, 谢谢

ChatGPT:

当然可以!我们来逐步解释构造函数的概念,以及相关的 defself 和语法。

1. 什么是构造函数?

构造函数是一个特殊的方法,用于在创建对象时初始化对象的属性。在 Python 中,构造函数的名称是 __init__。当你创建一个类的实例(对象)时,Python 会自动调用这个构造函数。

2. 为什么构造函数会被自动调用?

当你使用类名创建一个对象时,Python 会执行以下步骤:

  1. 分配内存:为新对象分配内存。
  2. 调用构造函数:自动调用 __init__ 方法,以初始化对象的属性。

例如:

my_account = BankAccount("Alice", 1000)

在这行代码中,BankAccount("Alice", 1000) 会自动调用 __init__ 方法,传入 "Alice"1000 作为参数。

3. defself 的含义

  • def:这是 Python 中定义函数的方法。后面跟着函数的名称和参数列表。构造函数也是一种函数,因此使用 def 来定义它。

  • self:这是一个约定俗成的名称,代表当前对象的实例。它允许你在类的方法中访问对象的属性和其他方法。每当你调用类的方法时,Python 会自动将当前对象作为第一个参数传递给方法,这个参数通常命名为 self

4. 构造函数的语法

构造函数的基本语法如下:

def __init__(self, 参数1, 参数2, ...):
    # 初始化对象的属性
    self.属性名1 = 参数1
    self.属性名2 = 参数2
    # 其他初始化代码

示例解释

让我们回到 BankAccount 类的构造函数部分:

def __init__(self, account_holder, balance=0):
    self.account_holder = account_holder  # 属性
    self.balance = balance  # 属性
  • def __init__(self, account_holder, balance=0):

    • def 表示定义一个函数。
    • __init__ 是构造函数的名称。
    • self 是当前对象的引用。
    • account_holderbalance 是传入的参数,其中 balance 有一个默认值 0。
  • self.account_holder = account_holder

    • 这里我们将传入的 account_holder 参数赋值给对象的属性 self.account_holder。这样,每个 BankAccount 对象都有自己的 account_holder 属性。
  • self.balance = balance

    • 同样地,将传入的 balance 参数赋值给对象的属性 self.balance

5. 总结

构造函数 __init__ 是在创建对象时自动调用的,用于初始化对象的属性。def 用于定义函数,self 是指向当前对象的引用,允许我们在类的方法中访问和修改对象的属性。通过构造函数,我们可以确保每个对象在创建时都有适当的初始状态。

如果你还有其他问题,或者需要更详细的解释,请随时告诉我!

用户:

我的天啊,原来这是python程序,我们刚刚不是一直在讲C语言吗,我没学过python,所以希望你用C语言

ChatGPT:

当然可以!我们可以用 C 语言来解释构造函数的概念,虽然 C 语言没有像 Python 那样的构造函数,但我们可以通过结构体和函数来模拟类似的行为。

C 语言中的结构体和初始化

在 C 语言中,我们通常使用结构体来定义一个数据类型,并通过函数来初始化这个结构体的实例。下面是一个模拟银行账户的示例:

示例代码

#include <stdio.h>
#include <string.h>

typedef struct {
    char account_holder[50];  // 账户持有者
    float balance;            // 账户余额
} BankAccount;

// 初始化函数
void initBankAccount(BankAccount *account, const char *holder, float initial_balance) {
    strcpy(account->account_holder, holder);  // 设置账户持有者
    account->balance = initial_balance;        // 设置初始余额
}

// 存款函数
void deposit(BankAccount *account, float amount) {
    account->balance += amount;  // 增加余额
}

// 取款函数
void withdraw(BankAccount *account, float amount) {
    if (amount <= account->balance) {
        account->balance -= amount;  // 减少余额
    } else {
        printf("余额不足\n");
    }
}

int main() {
    BankAccount my_account;  // 创建一个 BankAccount 变量
    initBankAccount(&my_account, "Alice", 1000.0);  // 初始化账户

    deposit(&my_account, 500.0);  // 存款
    printf("当前余额: %.2f\n", my_account.balance);  // 打印余额

    withdraw(&my_account, 200.0);  // 取款
    printf("当前余额: %.2f\n", my_account.balance);  // 打印余额

    return 0;
}

逐行解释

  1. 包含头文件

    #include <stdio.h>
    #include <string.h>
    
    • stdio.h 用于输入输出函数,string.h 用于字符串处理函数。
  2. 定义结构体

    typedef struct {
        char account_holder[50];  // 账户持有者
        float balance;            // 账户余额
    } BankAccount;
    
    • 这里定义了一个名为 BankAccount 的结构体,包含两个成员:account_holder(账户持有者的名字)和 balance(账户余额)。
  3. 初始化函数

    void initBankAccount(BankAccount *account, const char *holder, float initial_balance) {
        strcpy(account->account_holder, holder);  // 设置账户持有者
        account->balance = initial_balance;        // 设置初始余额
    }
    
    • initBankAccount 是一个函数,用于初始化 BankAccount 结构体的实例。
    • account 是指向 BankAccount 结构体的指针,holder 是账户持有者的名字,initial_balance 是初始余额。
    • 使用 strcpy 函数将 holder 的值复制到 account_holder 中。
  4. 存款函数

    void deposit(BankAccount *account, float amount) {
        account->balance += amount;  // 增加余额
    }
    
    • deposit 函数用于向账户中存款,增加余额。
  5. 取款函数

    void withdraw(BankAccount *account, float amount) {
        if (amount <= account->balance) {
            account->balance -= amount;  // 减少余额
        } else {
            printf("余额不足\n");
        }
    }
    
    • withdraw 函数用于从账户中取款,检查余额是否足够。
  6. 主函数

    int main() {
        BankAccount my_account;  // 创建一个 BankAccount 变量
        initBankAccount(&my_account, "Alice", 1000.0);  // 初始化账户
    
        deposit(&my_account, 500.0);  // 存款
        printf("当前余额: %.2f\n", my_account.balance);  // 打印余额
    
        withdraw(&my_account, 200.0);  // 取款
        printf("当前余额: %.2f\n", my_account.balance);  // 打印余额
    
        return 0;
    }
    
    • main 函数中,我们创建了一个 BankAccount 变量 my_account,并调用 initBankAccount 函数来初始化它。
    • 然后调用 depositwithdraw 函数来操作账户,并打印当前余额。

总结

在 C 语言中,我们使用结构体来定义数据类型,并通过函数来初始化和操作这些数据。虽然没有构造函数的概念,但我们可以通过初始化函数来实现类似的功能。希望这个示例能帮助你理解 C 语言中的对象和初始化的概念!如果你还有其他问题,请随时问我!

标签:BankAccount,account,区别,self,amount,余额,面向,balance,过程
From: https://www.cnblogs.com/dooOoozen/p/18455758

相关文章

  • 【答疑解惑】图文深入详解undo和redo的区别及其底层逻辑
    题记:最近有些人问我,undo和redo到底是什么关系,他们中不乏已经入行3-4年的同学,今天咱们就来深入探讨下到底什么是undo和redo,他们分别做什么,底层逻辑原理是什么等等。1.undo1.1undo的存储结构Undo段(UndoSegment):–Undo信息存储在数据库的undo段中,这些段是特殊的数据库对......
  • MySql数据库---存储过程
    存储过程概念MySQL5.0版本开始支持存储过程。简单的说,存储过程就是一组SQL语句集,功能强大,可以实现一些比较复杂的逻辑功能,类似于JAVA语言中的方法,类似Python中的函数;存储过就是数据库SQL语言层面的代码封装与重用入门案例语法:delimiter自定义结束符号createpro......
  • java面向对之象类的继承与多态
    目录1.类的继承图解案例:创建一个动物类和一个猫类1.代码1)动物类2)猫类3.测试类2.效果2.父类方法的重写案例:如何重写父类的方法        1.代码1)Animal类2)Dog类3)测试类2.效果3.super关键字案例:如何在子类中调用父类的方法,或属性1.代码1)Animal类......
  • 【网络】初识https协议加密过程
    初识https协议加密过程为什么不用http而要使用https常见的加密方式对称加密非对称加密数据摘要&&数据指纹https的工作过程探究方案一:只使用对称加密方案二:只使用非对称加密方案三:双方都使用对称加密方案四:非对称加密+对称加密中间人攻击如何确认密钥是否被修改理解数......
  • 【MySQL】视图、存储过程、触发器
    目录一、视图1.创建视图2.视图的使用3.查看视图4.删除视图5. 视图的作用二、存储过程 1.存储过程的创建2.使用存储过程3.带参数的存储过程3.1 分页4.存储过程与函数的区别5.存储过程的缺陷三、触发器 --隐式执行1.创建触发器2.查看库中所有......
  • 【javascript 编程】Web前端之JavaScript动态添加类名的两种方法、区别、className、c
    通过className来添加或删除类名添加类名获取元素el.className="类名1类名2...";多个类名用空格隔开。移除类名获取元素名el.className="";直接等于一个空字符串即可删除类名。通过classList来添加或删除类名添加一个类名获取元素名el.classList.add("类名");。......
  • AI即服务平台与传统软件的区别
    随着科技的不断发展,人工智能(AI)技术正逐步改变我们的生产和生活方式。AI即服务平台(AIasaService,AIaaS)作为这一变革的重要载体,与传统软件相比,展现出了许多独特的优势和潜力。下面,petacloud.ai小编从开发方式、功能用途、用户体验、数据处理与学习能力以及应用场景等多个......
  • 在K8S中,Deployment 升级过程有哪些?
    在Kubernetes(K8s)中,Deployment的升级过程是一个受控且平滑的过程,用于将应用的新版本无缝地替换旧版本。以下是Deployment升级过程的详细步骤:1.更新Deployment配置准备新版本镜像或配置:确定新版本的应用程序镜像或需要更改的配置。更新Deployment的YAML配置文件,例如更改镜像......
  • PTA JAVA语言 面向对象程序设计 作业二 6-2 定义学生类 定义一个学生类(Student),其中包
    6-2定义学生类分数10作者 fpc 谢谢大佬关注,不定期分享学习笔记,希望大佬能多多支持,三连必回单位 内蒙古师范大学定义一个学生类(Student),其中包括四个属性:姓名(name),年龄(age),班级号(classNo),爱好(hobby)裁判测试程序样例:/*请在这里填写答案*/测试该类的程序如下:publiccl......
  • PTA JAVA语言 面向对象程序设计 作业二 6-1 sdut-oop-7 计算长方体的体积与质量(类和对
    6-1sdut-oop-7计算长方体的体积与质量(类和对象)分数10作者 周雪芹单位 山东理工大学现根据长方体的长、宽、高、密度,求其底面周长、底面积、体积、质量。若长、宽、高、密度之一有数据为0或者负数,则不能构成长方体,输出的值均为0。补充完整如下类的定义:classCuboid{......