1.1 编写一个简单的C++程序
概述
本小节介绍了如何编写和运行一个简单的C++程序,帮助初学者了解C++程序的基本结构和编译运行过程。
编写第一个C++程序
我们从一个简单的C++程序开始,它的功能是在控制台输出 "Hello, World!"。这是学习任何编程语言的传统起点。
- 程序代码:
#include <iostream>int main() {std::cout << "Hello, World!" << std::endl;return 0;
}
代码解析
- 预处理指令:
#include <iostream>
#include
是一个预处理指令,用于包含标准库头文件。<iostream>
是输入输出流库,用于处理输入和输出操作。
- 主函数:
int main() {// ...return 0;
}
int main()
是程序的入口点,每个C++程序都必须包含一个main
函数。- 函数返回类型为
int
,表示程序执行的状态,0
通常表示成功。
- 输出语句:
std::cout << "Hello, World!" << std::endl;
std::cout
是标准输出流对象,用于输出数据到控制台。<<
是插入运算符,将右侧的数据插入到输出流中。"Hello, World!"
是要输出的字符串。std::endl
是一个流操纵符,用于插入一个换行符并刷新输出缓冲区。
编译和运行
编写完第一个C++程序后,我们需要将其编译成可执行文件,然后运行它。
- 编译:
- 使用C++编译器将源代码编译成机器代码。
- 示例(使用
g++
编译器):
g++ -o hello hello.cpp
-o
选项指定生成的可执行文件名称,这里是hello
。
- 运行:
- 运行生成的可执行文件。
- 示例:
./hello
- 运行结果:
Hello, World!
C++程序的基本结构
通过这个简单的程序,我们可以看到一个C++程序的基本结构:
- 预处理指令
- 主函数
- 输出语句
这些是每个C++程序的基础,后续章节将会详细介绍更多复杂的语法和功能。
重点与难点分析
重点:
- 预处理指令:了解
#include
的作用,知道如何包含标准库头文件。 - 主函数结构:掌握
main
函数的基本结构和作用。 - 输出语句:理解
std::cout
、插入运算符<<
和std::endl
的使用。
难点:
- 编译过程:初学者可能对编译和链接过程不熟悉,需要多练习。
- 标准库:
<iostream>
是一个常用的标准库头文件,需要理解其基本功能。
练习题解析
- 练习1.1:编写并运行一个简单的C++程序,输出你的名字。
- 示例代码:
#include <iostream>int main() {std::cout << "Your Name" << std::endl;return 0;
}
- 练习1.2:修改第一个C++程序,使其输出两行文字。
- 示例代码:
#include <iostream>int main() {std::cout << "Hello, World!" << std::endl;std::cout << "Welcome to C++ Programming!" << std::endl;return 0;
}
- 练习1.3:尝试将
std::cout
替换为cout
,观察编译错误,并修改代码以正确编译。
- 示例代码:
#include <iostream>using std::cout;
using std::endl;int main() {cout << "Hello, World!" << endl;return 0;
}
总结与提高
本节总结:
- 了解了一个简单的C++程序的基本结构,包括预处理指令、主函数和输出语句。
- 学会了如何编写、编译和运行一个简单的C++程序。
提高建议:
- 多编写简单程序:通过不断练习,熟悉C++程序的基本结构和编写流程。
- 探索更多标准库:除了
<iostream>
,C++还有许多有用的标准库,可以逐步学习和使用。 - 了解编译器和开发环境:熟悉编译器的使用和常见选项,掌握IDE或命令行的开发环境,提高开发效率。
1.2 初识输入输出
概述
本小节介绍了C++中基本的输入输出操作,通过标准库中的cin
和cout
对象实现。这些对象是iostream
库的一部分,用于处理控制台的输入输出。
使用cin
进行输入
在C++中,cin
对象用于从标准输入设备(通常是键盘)读取数据。cin
是iostream
库的一部分。
- 基本用法:
#include <iostream>int main() {int number;std::cout << "Please enter a number: ";std::cin >> number;std::cout << "You entered: " << number << std::endl;return 0;
}
代码解析
- 读取输入:
std::cin >> number;
std::cin
是标准输入流对象。>>
是提取运算符,用于从输入流中提取数据并存储到变量中。
- 输入提示:
std::cout << "Please enter a number: ";
- 使用
std::cout
输出提示信息,引导用户输入。
- 输出结果:
Please enter a number: 100
You entered: 100
处理多个输入
我们可以使用cin
一次读取多个输入,并将其存储在不同的变量中。
- 示例代码:
#include <iostream>int main() {int num1, num2;std::cout << "Please enter two numbers: ";std::cin >> num1 >> num2;std::cout << "You entered: " << num1 << " and " << num2 << std::endl;return 0;
}
代码解析
- 读取多个输入:
std::cin >> num1 >> num2;
- 使用提取运算符
>>
连续读取两个整数输入,并存储在num1
和num2
中。
- 输出多个输入:
Please enter two numbers: 10 20
You entered: 10 and 20
输入和输出的类型匹配
在使用cin
和cout
时,需要注意类型匹配。如果输入的数据类型与变量类型不匹配,会导致意外行为或错误。
- 示例代码:
#include <iostream>int main() {int num;std::cout << "Please enter an integer: ";std::cin >> num;if (std::cin.fail()) {std::cout << "Input error! Please enter a valid integer." << std::endl;} else {std::cout << "You entered: " << num << std::endl;}return 0;
}
代码解析
- 检查输入是否失败:
if (std::cin.fail()) {std::cout << "Input error! Please enter a valid integer." << std::endl;
}
std::cin.fail()
用于检测输入是否失败。如果输入的数据类型与变量类型不匹配,fail()
返回true
。
- 重置输入流:
std::cin.clear(); // 重置输入流状态
std::cin.ignore(1000, '\n'); // 忽略输入缓冲区中的字符
std::cin.clear()
清除错误标志。std::cin.ignore()
忽略输入缓冲区中的字符,避免影响后续输入操作。
重点与难点分析
重点:
- 使用
cin
进行输入:掌握cin
对象和提取运算符>>
的基本用法。 - 处理多个输入:学习使用
cin
一次读取多个输入。 - 输入输出的类型匹配:理解类型匹配的重要性,学习如何处理输入错误。
难点:
- 处理输入错误:初学者可能对输入错误处理不熟悉,需要多练习。
- 输入输出流状态管理:理解输入输出流的状态管理方法,如清除错误标志和忽略输入缓冲区。
练习题解析
- 练习1.4:编写一个程序,读取两个整数并输出它们的和。
- 示例代码:
#include <iostream>int main() {int num1, num2;std::cout << "Please enter two integers: ";std::cin >> num1 >> num2;int sum = num1 + num2;std::cout << "The sum is: " << sum << std::endl;return 0;
}
- 练习1.5:编写一个程序,读取三个浮点数并输出它们的平均值。
- 示例代码:
#include <iostream>int main() {float num1, num2, num3;std::cout << "Please enter three floating-point numbers: ";std::cin >> num1 >> num2 >> num3;float average = (num1 + num2 + num3) / 3;std::cout << "The average is: " << average << std::endl;return 0;
}
- 练习1.6:编写一个程序,读取一个整数并检查输入是否合法。如果输入不是整数,输出错误信息。
- 示例代码:
#include <iostream>int main() {int num;std::cout << "Please enter an integer: ";std::cin >> num;if (std::cin.fail()) {std::cout << "Input error! Please enter a valid integer." << std::endl;std::cin.clear(); // 重置输入流状态std::cin.ignore(1000, '\n'); // 忽略输入缓冲区中的字符} else {std::cout << "You entered: " << num << std::endl;}return 0;
}
总结与提高
本节总结:
- 学习了C++中基本的输入输出操作,包括
cin
和cout
对象的使用。 - 掌握了使用
cin
进行输入,处理多个输入,以及输入输出的类型匹配。 - 了解了如何处理输入错误和管理输入输出流的状态。
提高建议:
- 多练习输入输出操作:通过不断练习,熟悉
cin
和cout
的基本用法和常见操作。 - 探索更多输入输出流功能:C++标准库提供了丰富的输入输出流功能,可以逐步学习和使用。
- 了解输入输出流的高级特性:如格式化输出、自定义流操纵符等,提升程序的灵活性和可读性。
1.3 注释简介
概述
注释是程序员在代码中加入的说明性文本,用于解释代码的功能、逻辑或特殊用法。注释不会被编译器执行,它们仅供阅读代码的人使用。合理的注释可以提高代码的可读性和可维护性。
C++支持两种注释方式:单行注释和多行注释。
单行注释
单行注释以 //
开头,直到行尾的所有内容都被视为注释。
- 示例:
#include <iostream>int main() {// 输出 "Hello, World!"std::cout << "Hello, World!" << std::endl; // 单行注释return 0; // 返回 0
}
代码解析
- 单行注释的使用:
// 输出 "Hello, World!"
是一条单行注释,解释了下一行代码的功能。// 返回 0
是一条单行注释,解释了return 0
语句。
- 注释位置:
- 单行注释可以放在代码行的上方,也可以放在代码行的末尾。
多行注释
多行注释以 /*
开头,以 */
结尾,之间的所有内容都被视为注释。
- 示例:
#include <iostream>int main() {/*这是一段多行注释解释了以下代码的功能:输出 "Hello, World!" 并返回 0*/std::cout << "Hello, World!" << std::endl;return 0;
}
代码解析
- 多行注释的使用:
/*
和*/
之间的所有内容都是注释,可以跨越多行。- 多行注释通常用于解释复杂的代码段或提供详细的说明。
- 嵌套注释的注意事项:
- 多行注释不能嵌套,即在一个多行注释内不能再包含另一个多行注释。
- 嵌套会导致编译错误。
注释的最佳实践
合理的注释可以显著提高代码的可读性和可维护性。以下是一些编写注释的最佳实践:
- 解释意图,而非解释语法:
- 注释应解释代码的目的和逻辑,而不是解释语法。例如,不要注释显而易见的语法,而是解释为什么这样写。
- 保持简洁明了:
- 注释应简洁明了,避免冗长。清晰的注释有助于快速理解代码。
- 及时更新注释:
- 代码修改后,应及时更新相应的注释,以确保注释与代码一致。
- 使用TODO注释:
- 对于需要进一步完善或修复的代码,可以使用
TODO
注释标记,提醒以后回顾和处理。 - 示例:
// TODO: 处理可能的错误情况
- 避免过度注释:
- 虽然注释很重要,但过多的注释可能会使代码显得杂乱无章。应在关键部分添加注释,而不是每行都注释。
练习题解析
- 练习1.7:编写一个简单的程序,使用单行注释解释每一行代码。
- 示例代码:
#include <iostream> // 包含输入输出流库int main() {int num; // 定义一个整数变量std::cout << "Please enter a number: "; // 输出提示信息std::cin >> num; // 从标准输入读取一个整数std::cout << "You entered: " << num << std::endl; // 输出读取的整数return 0; // 返回 0
}
- 练习1.8:编写一个程序,使用多行注释解释整个程序的功能。
- 示例代码:
#include <iostream>int main() {/*这是一个简单的C++程序它从用户那里读取一个整数然后输出该整数*/int num;std::cout << "Please enter a number: ";std::cin >> num;std::cout << "You entered: " << num << std::endl;return 0;
}
- 练习1.9:编写一个复杂的代码段,使用注释解释每一步操作。
- 示例代码:
#include <iostream>
#include <vector>int main() {// 定义一个整数向量std::vector<int> numbers;// 向向量中添加数字for (int i = 1; i <= 5; ++i) {numbers.push_back(i); // 添加数字 i 到向量末尾}// 计算向量中数字的总和int sum = 0;for (int num : numbers) {sum += num; // 将每个数字累加到 sum}// 输出结果std::cout << "The sum is: " << sum << std::endl; // 输出总和return 0;
}
总结与提高
本节总结:
- 学习了C++中的两种注释方式:单行注释和多行注释。
- 了解了如何在代码中添加注释,以提高代码的可读性和可维护性。
- 通过示例代码,掌握了注释的基本用法和最佳实践。
提高建议:
- 多练习编写注释:在编写代码时,养成良好的注释习惯,解释代码的功能和逻辑。
- 阅读他人的代码:通过阅读他人代码中的注释,学习如何编写清晰有效的注释。
- 及时更新注释:在修改代码时,确保相应的注释也得到更新,以保持代码和注释的一致性。
1.4 控制结构
概述
控制结构是编程语言中用于控制代码执行流程的语法元素。C++提供了多种控制结构,包括条件语句、循环语句和跳转语句。本小节将介绍C++中的基本控制结构,帮助初学者理解如何控制程序的执行流程。
条件语句
条件语句用于根据某个条件的真假来决定执行哪个代码块。C++中的条件语句主要包括if
语句、if-else
语句。
if语句
if
语句根据条件表达式的真假来决定是否执行相应的代码块。
- 语法:
if (condition) {// 如果 condition 为真,执行这里的代码
}
- 示例:
#include <iostream>int main() {int value = 42;if (value > 0) {std::cout << "Value is positive" << std::endl;}return 0;
}
if-else语句
if-else
语句在条件为真时执行一个代码块,为假时执行另一个代码块。
- 语法:
if (condition) {// 如果 condition 为真,执行这里的代码
} else {// 否则,执行这里的代码
}
- 示例:
#include <iostream>int main() {int value = -10;if (value > 0) {std::cout << "Value is positive" << std::endl;} else {std::cout << "Value is not positive" << std::endl;}return 0;
}
if-else if-else语句
if-else if-else
语句用于检查多个条件,依次判断每个条件表达式。
- 语法:
if (condition1) {// 如果 condition1 为真,执行这里的代码
} else if (condition2) {// 如果 condition2 为真,执行这里的代码
} else {// 如果前面的条件都不为真,执行这里的代码
}
- 示例:
#include <iostream>int main() {int value = 0;if (value > 0) {std::cout << "Value is positive" << std::endl;} else if (value < 0) {std::cout << "Value is negative" << std::endl;} else {std::cout << "Value is zero" << std::endl;}return 0;
}
循环语句
循环语句用于重复执行某段代码,直到满足某个条件。C++中的循环语句主要包括while
循环、do-while
循环和for
循环。
while循环
while
循环在每次迭代之前检查条件,如果条件为真,则执行循环体。
- 语法:
while (condition) {// 如果 condition 为真,执行这里的代码
}
- 示例:
#include <iostream>int main() {int count = 0;while (count < 5) {std::cout << "Count is: " << count << std::endl;++count;}return 0;
}
do-while循环
do-while
循环先执行循环体,然后检查条件,如果条件为真,则继续执行循环体。
- 语法:
do {// 先执行这里的代码
} while (condition);
- 示例:
#include <iostream>int main() {int count = 0;do {std::cout << "Count is: " << count << std::endl;++count;} while (count < 5);return 0;
}
for循环
for
循环在循环开始前初始化变量,在每次迭代前检查条件,并在每次迭代后更新变量。
- 语法:
for (initialization; condition; increment) {// 如果 condition 为真,执行这里的代码
}
- 示例:
#include <iostream>int main() {for (int count = 0; count < 5; ++count) {std::cout << "Count is: " << count << std::endl;}return 0;
}
重点与难点分析
重点:
- 条件语句:掌握
if
、if-else
、if-else if-else
语句的使用。 - 循环语句:理解
while
、do-while
和for
循环的用法。
难点:
- 条件和循环逻辑:初学者可能会对复杂的条件和循环逻辑感到困惑,需要通过实践加深理解。
- 避免滥用
goto
:尽量避免使用goto
,并学习更清晰的控制流程方法。
练习题解析
- 练习1.10:编写一个程序,使用
while
循环输出10到1的数字。
- 示例代码:
#include <iostream>int main() {int count = 10;while (count > 0) {std::cout << "Count is: " << count << std::endl;--count;}return 0
}
- 练习1.11:编写一个程序,使用
for
循环输出1到10的数字。
- 示例代码:
#include <iostream>int main() {for (int count = 1; count <= 10; ++count) {std::cout << "Count is: " << count << std::endl;}return 0;
}
- 练习1.12:编写一个程序,使用
if-else
语句检查输入的整数是正数、负数还是零。
- 示例代码:
#include <iostream>int main() {int number;std::cout << "Please enter an integer: ";std::cin >> number;if (number > 0) {std::cout << "The number is positive." << std::endl;} else if (number < 0) {std::cout << "The number is negative." << std::endl;} else {std::cout << "The number is zero." << std::endl;}return 0;
}
总结与提高
本节总结:
- 学习了C++中的基本控制结构,包括条件语句、循环语句和跳转语句。
- 掌握了
if
、if-else
语句的用法。 - 了解了
while
、do-while
、for
循环的不同用法。
提高建议:
- 多练习控制结构的使用:通过编写各种示例程序,熟悉控制结构的用法和逻辑。
- 理解和优化循环逻辑:在实际编程中,理解和优化循环逻辑,编写高效的代码。
1.5 类简介
概述
类是C++中的一种用户定义类型,它将数据和操作数据的方法封装在一起,是面向对象编程(OOP)的基础。类定义了一组对象的共同属性和行为,通过实例化类,可以创建具体的对象。
定义和使用类
一个类由成员变量(数据成员)和成员函数(方法)组成。成员变量用于存储对象的状态,成员函数用于定义对象的行为。
定义类
- 语法:
class ClassName {
public:// 公有成员// 成员变量// 成员函数
private:// 私有成员// 成员变量// 成员函数
};
- 示例:
#include <iostream>
#include <string>class SalesItem {
public:// 成员函数,声明和定义分离std::string isbn() const { return bookNo; }double avg_price() const;// 成员变量std::string bookNo;unsigned units_sold = 0;double revenue = 0.0;
};// 成员函数的定义
double SalesItem::avg_price() const {if (units_sold) {return revenue / units_sold;} else {return 0;}
}int main() {SalesItem item;item.bookNo = "12345";item.units_sold = 100;item.revenue = 1000.0;std::cout << "ISBN: " << item.isbn() << std::endl;std::cout << "Average Price: " << item.avg_price() << std::endl;return 0;
}
- 注意,编译上面的代码采用如下的命令:
// 假如你将文件存储为test.cpp
// 需要加上参数 -std=c++11 表示使用C++11标准
g++ -std=c++11 test.cpp -o test
代码解析
- 类的定义:
- 类通过关键字
class
定义,后跟类名和类体。类体包含成员变量和成员函数。 public
和private
访问说明符用于控制成员的访问权限。
- 成员变量:
- 成员变量在类中声明,用于存储对象的状态。例如:
std::string bookNo;
。
- 成员函数:
- 成员函数定义了操作成员变量的方法。可以在类内声明,在类外定义。例如:
std::string isbn() const { return bookNo; }
double avg_price() const;
- 成员函数的定义:
- 成员函数可以在类外定义,使用
ClassName::FunctionName
语法。例如:
double SalesItem::avg_price() const {if (units_sold) {return revenue / units_sold;} else {return 0;}
}
- 创建对象:
- 通过类名创建对象,访问对象的成员。例如:
SalesItem item;
item.bookNo = "12345";
item.units_sold = 100;
item.revenue = 1000.0;
重点与难点分析
重点:
- 类的定义和使用:理解类的基本结构,包括成员变量和成员函数的定义和使用。
难点:
- 成员函数的定义和调用:初学者需要熟悉成员函数在类外定义和调用的语法。
练习题解析
- 练习1.13:定义一个类
Book
,包含成员变量title
、author
和price
,以及相应的构造函数和成员函数。
- 示例代码:
#include <iostream>
#include <string>class Book {
public:// 默认构造函数Book() = default;// 带参数的构造函数Book(const std::string &t, const std::string &a, double p) : title(t), author(a), price(p) {}// 成员函数std::string getTitle() const { return title; }std::string getAuthor() const { return author; }double getPrice() const { return price; }private:// 成员变量std::string title;std::string author;double price = 0.0;
};int main() {Book book1;Book book2("C++ Primer", "Stanley B. Lippman", 59.99);std::cout << "Book1 Title: " << book1.getTitle() << std::endl;std::cout << "Book2 Title: " << book2.getTitle() << std::endl;return 0;
}
- 练习1.14:修改
SalesItem
类,添加一个计算总销售额的成员函数。
- 示例代码:
#include <iostream>
#include <string>class SalesItem {
public:SalesItem() = default;SalesItem(const std::string &book, unsigned sold, double rev) : bookNo(book), units_sold(sold), revenue(rev) {}std::string isbn() const { return bookNo; }double avg_price() const;double total_revenue() const { return revenue; }private:std::string bookNo;unsigned units_sold = 0;double revenue = 0.0;
};double SalesItem::avg_price() const {if (units_sold) {return revenue / units_sold;} else {return 0;}
}int main() {SalesItem item("12345", 100, 1000.0);std::cout << "ISBN: " << item.isbn() << std::endl;std::cout << "Total Revenue: " << item.total_revenue() << std::endl;return 0;
}
- 练习1.15:为
Book
类添加析构函数,输出书籍对象销毁时的信息。
- 示例代码:
#include <iostream>
#include <string>class Book {
public:Book() = default;Book(const std::string &t, const std::string &a, double p) : title(t), author(a), price(p) {}std::string getTitle() const { return title; }std::string getAuthor() const { return author; }double getPrice() const { return price; }~Book() {std::cout << "Book object for " << title << " is being destroyed" << std::endl;}private:std::string title;std::string author;double price = 0.0;
};int main() {Book book1("C++ Primer", "Stanley B. Lippman", 59.99);return 0;
}
总结与提高
本节总结:
- 了解了类的基本概念和定义,包括成员变量和成员函数。
- 通过示例代码,掌握了类的基本用法和常见操作。
提高建议:
- 多练习定义和使用类:通过编写各种类,熟悉类的定义、构造函数和析构函数的使用。
- 理解面向对象编程的基本概念:学习封装、继承和多态等面向对象编程的基本概念,编写更复杂的类。
1.6 书店程序
概述
在本小节中,我们将使用之前学到的C++基础知识,编写一个简单的书店程序。这个程序的目标是处理书籍销售记录,通过对销售数据进行统计,计算销售的总额。
需求描述
书店程序需要完成以下功能:
- 读取一系列书籍的销售记录。
- 统计每种书籍的总销售量和总销售额。
- 输出每种书籍的ISBN、销售总量和总销售额。
数据结构
为了处理书籍销售记录,我们需要定义一个类来表示每一本书的销售数据。该类应该包括以下成员:
- ISBN(书籍编号)
- 销售量
- 总销售额
我们可以重用之前定义的SalesItem
类或定义一个新的类Sales_data
。
定义Sales_data
类
- 类定义:
#include <iostream>
#include <string>class Sales_data {
public:// 成员变量std::string bookNo;unsigned units_sold = 0;double revenue = 0.0;// 成员函数std::string isbn() const { return bookNo; }Sales_data& combine(const Sales_data&);double avg_price() const;
};// 成员函数定义
Sales_data& Sales_data::combine(const Sales_data& rhs) {units_sold += rhs.units_sold;revenue += rhs.revenue;return *this;
}double Sales_data::avg_price() const {if (units_sold) {return revenue / units_sold;} else {return 0;}
}
代码解析
- 成员变量:
std::string bookNo
:书籍的ISBN编号。unsigned units_sold
:销售量。double revenue
:总销售额。
- 成员函数:
std::string isbn() const
:返回书籍的ISBN编号。Sales_data& combine(const Sales_data&)
:将另一条销售记录的数据合并到当前对象。double avg_price() const
:计算平均售价。
- 成员函数定义:
combine
函数:将传入的Sales_data
对象的销售量和总销售额累加到当前对象。avg_price
函数:计算平均售价,如果销售量为零,则返回零。
实现书店程序
我们将编写一个主函数,用于读取销售记录、统计每种书籍的总销售量和总销售额,并输出结果。
- 主函数实现:
#include <iostream>
#include <string>
#include "Sales_data.h" // 包含Sales_data类定义int main() {Sales_data total; // 保存当前书籍的销售总记录// 读取第一条销售记录if (std::cin >> total.bookNo >> total.units_sold >> total.revenue) {Sales_data trans; // 保存每次读取的新销售记录// 读取并处理剩余的销售记录while (std::cin >> trans.bookNo >> trans.units_sold >> trans.revenue) {if (total.isbn() == trans.isbn()) {total.combine(trans); // 更新当前书籍的总销售记录} else {// 输出结果std::cout << total.isbn() << " "<< total.units_sold << " "<< total.revenue << " "<< total.avg_price() << std::endl;total = trans; // 处理下一本书的销售记录}}// 输出最后一本书的销售记录std::cout << total.isbn() << " "<< total.units_sold << " "<< total.revenue << " "<< total.avg_price() << std::endl;} else {std::cerr << "No data?!" << std::endl;return -1; // 表示失败}return 0;
}
代码解析
- 变量定义:
Sales_data total
:保存当前书籍的销售总记录。Sales_data trans
:保存每次读取的新销售记录。
- 读取第一条销售记录:
- 使用
std::cin
读取第一条销售记录,并存储到total
对象中。
- 处理剩余销售记录:
- 使用
while
循环读取剩余的销售记录,并存储到trans
对象中。 - 如果当前记录的ISBN与
total
对象的ISBN相同,则调用combine
函数更新总记录。 - 如果ISBN不同,则输出
total
对象的累计结果,并更新total
对象为当前记录。
- 输出最后一本书的销售记录:
- 循环结束后,输出
total
对象的最终累计结果。
- 错误处理:
- 如果没有读取到任何数据,输出错误信息,并返回失败状态。
重点与难点分析
重点:
- 类的定义和使用:复习和应用之前定义的
Sales_data
类,包括成员变量和成员函数。 - 输入输出操作:熟练使用
std::cin
和std::cout
进行数据读取和输出。 - 条件判断和循环控制:使用
if
语句和while
循环控制程序流程。
难点:
- 数据合并逻辑:正确理解和实现
combine
函数的逻辑,确保销售记录的准确累计。 - 输入数据处理:处理标准输入中的数据,并根据ISBN判断是否需要合并或输出结果。
练习题解析
- 练习1.16:编写一个程序,从标准输入读取多条销售记录,并计算每条记录的总和。
- 示例代码:
#include <iostream>
#include <string>int main() {Sales_data total;while (std::cin >> total.bookNo >> total.units_sold >> total.revenue) {std::cout << "ISBN: " << total.isbn() << ", "<< "Units Sold: " << total.units_sold << ", "<< "Revenue: " << total.revenue << ", "<< "Average Price: " << total.avg_price() << std::endl;}return 0;
}
- 练习1.17:修改主程序,增加输入错误处理逻辑,当输入数据格式不正确时,输出错误信息。
- 示例代码:
#include <iostream>
#include <string>int main() {Sales_data total;while (true) {std::cout << "Enter bookNo, units_sold, and revenue: ";if (!(std::cin >> total.bookNo >> total.units_sold >> total.revenue)) {std::cerr << "Input error! Please enter valid data." << std::endl;std::cin.clear();std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');} else {std::cout << "ISBN: " << total.isbn() << ", "<< "Units Sold: " << total.units_sold << ", "<< "Revenue: " << total.revenue << ", "<< "Average Price: " << total.avg_price() << std::endl;}}return 0;
}
- 练习1.18:扩展程序,允许用户输入多组数据,每组数据包含多个销售记录,并计算每组数据的总和。
- 示例代码:
#include <iostream>
#include <string>int main() {Sales_data total;while (true) {std::cout << "Enter bookNo, units_sold, and revenue (enter 'end' to finish): ";std::string bookNo;if (!(std::cin >> bookNo)) break;if (bookNo == "end") break;total.bookNo = bookNo;if (!(std::cin >> total.units_sold >> total.revenue)) {std::cerr << "Input error! Please enter valid data." << std::endl;std::cin.clear();std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');continue;}Sales_data trans;while (true) {std::cout << "Enter another record for the same book (enter 'done' to finish this book): ";std::string transBookNo;if (!(std::cin >> transBookNo)) break;if (transBookNo == "done") break;trans.bookNo = transBookNo;if (!(std::cin >> trans.units_sold >> trans.revenue)) {std::cerr << "Input error! Please enter valid data." << std::endl;std::cin.clear();std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');continue;}if (total.isbn() == trans.isbn()) {total.combine(trans);} else {std::cerr << "ISBN mismatch! Please enter the correct record." << std::endl;}}std::cout << "Total for book " << total.isbn() << ": "<< "Units Sold: " << total.units_sold << ", "<< "Revenue: " << total.revenue << ", "<< "Average Price: " << total.avg_price() << std::endl;}return 0;
}
总结与提高
本节总结:
- 通过实现书店程序,综合应用了类、输入输出、条件判断和循环控制等C++基础知识。
- 学习了如何定义和使用一个类来处理实际问题中的数据。
- 掌握了如何从标准输入读取数据,处理和统计这些数据,并输出结果。
提高建议:
- 多练习实际应用场景:通过更多实际应用场景的练习,巩固和加深对C++基础知识的理解和应用。
- 优化程序逻辑:在编写程序时,注重代码的结构和逻辑,提高代码的可读性和可维护性。
- 处理输入错误和异常情况:在实际应用中,输入数据可能会有错误,需要学习如何处理这些错误和异常情况,编写健壮的程序。
本主页会定期更新,为了能够及时获得更新,敬请关注我:点击左下角的关注。也可以关注公众号:请在微信上搜索公众号“iShare爱分享”并关注,或者扫描以下公众号二维码关注,以便在内容更新时直接向您推送。