下面是一个综合性的C++代码示例,涵盖了C++的核心语法和常用特性。这个程序实现了一个简单的学生成绩管理系统。
程序代码
cpp
// ============================================
// 文件: student_management.cpp
// 描述: 一个完整的学生成绩管理系统
// 包含了C++常用语法和特性的示例
// ============================================
// ====================
// 1. 预处理指令
// ====================
// #include 用于包含头文件
// <iostream> 标准输入输出流头文件
#include <iostream>
// <string> 字符串操作头文件
#include <string>
// <vector> 动态数组容器
#include <vector>
// <map> 关联容器,键值对存储
#include <map>
// <algorithm> 算法库,包含排序、查找等
#include <algorithm>
// <fstream> 文件流操作
#include <fstream>
// <iomanip> 输入输出格式化
#include <iomanip>
// <stdexcept> 异常处理类
#include <stdexcept>
// 使用命名空间std,避免重复写std::
using namespace std;
// 宏定义:定义常量
// 宏在预处理阶段进行文本替换
#define MAX_STUDENTS 100
#define MIN_SCORE 0
#define MAX_SCORE 100
// 条件编译:调试模式开关
#ifdef DEBUG_MODE
#define DEBUG_LOG(msg) cout << "[DEBUG] " << msg << endl
#else
#define DEBUG_LOG(msg)
#endif
// ====================
// 2. 全局函数声明
// ====================
// 函数原型声明:告诉编译器函数的存在
void displayMenu(); // 显示菜单
int getValidInput(int min, int max); // 获取有效输入
// ====================
// 3. 枚举类型
// ====================
// enum: 定义一组相关的命名常量
enum class GradeLevel {
FRESHMAN, // 大一
SOPHOMORE, // 大二
JUNIOR, // 大三
SENIOR // 大四
};
// ====================
// 4. 结构体定义
// ====================
// struct: 定义一组相关数据的复合类型
struct Date {
int year;
int month;
int day;
// 结构体方法
string toString() const {
return to_string(year) + "-" + to_string(month) + "-" + to_string(day);
}
};
// ====================
// 5. 类定义
// ====================
// class: 面向对象的核心,封装数据和操作
// 前向声明
class Student;
// 基类:Person
class Person {
// protected: 保护成员,子类可以访问
protected:
string name;
int age;
// public: 公有成员,任何代码都可以访问
public:
// 构造函数:对象创建时自动调用
Person(const string& n, int a) : name(n), age(a) {
DEBUG_LOG("Person构造函数被调用: " + n);
}
// 虚析构函数:确保派生类正确释放资源
virtual ~Person() {
DEBUG_LOG("Person析构函数被调用: " + name);
}
// 虚函数:支持多态
virtual void displayInfo() const {
cout << "姓名: " << name << ", 年龄: " << age << endl;
}
// 纯虚函数:抽象类,不能实例化
virtual string getType() const = 0;
// 内联函数:小型函数,直接在调用处展开
inline const string& getName() const { return name; }
inline int getAge() const { return age; }
// 静态成员函数:属于类而不是对象
static void showPersonCount() {
// 静态局部变量:只在第一次调用时初始化
static int callCount = 0;
callCount++;
cout << "showPersonCount被调用了 " << callCount << " 次" << endl;
}
};
// 派生类:Student
class Student : public Person {
// private: 私有成员,只有类内可以访问
private:
string studentId;
GradeLevel gradeLevel;
vector<int> scores; // 使用vector存储成绩
static int studentCount; // 静态成员变量:所有对象共享
public:
// 构造函数初始化列表
Student(const string& n, int a, const string& id, GradeLevel grade)
: Person(n, a), studentId(id), gradeLevel(grade) {
studentCount++; // 每创建一个学生,计数器加1
}
// 析构函数
~Student() override {
studentCount--; // 对象销毁时计数器减1
DEBUG_LOG("Student析构函数被调用: " + name);
}
// 成员函数
void addScore(int score) {
// 异常处理:检查输入是否有效
if (score < MIN_SCORE || score > MAX_SCORE) {
throw out_of_range("成绩必须在0到100之间");
}
scores.push_back(score);
}
double calculateAverage() const {
if (scores.empty()) return 0.0;
int sum = 0;
// 范围for循环:C++11特性
for (int score : scores) {
sum += score;
}
return static_cast<double>(sum) / scores.size(); // 类型转换
}
// 重写基类虚函数
void displayInfo() const override {
Person::displayInfo(); // 调用基类方法
cout << "学号: " << studentId << ", 年级: ";
// switch语句
switch (gradeLevel) {
case GradeLevel::FRESHMAN: cout << "大一"; break;
case GradeLevel::SOPHOMORE: cout << "大二"; break;
case GradeLevel::JUNIOR: cout << "大三"; break;
case GradeLevel::SENIOR: cout << "大四"; break;
}
cout << endl;
if (!scores.empty()) {
cout << "平均成绩: " << fixed << setprecision(2) << calculateAverage() << endl;
}
}
string getType() const override {
return "学生";
}
// 友元函数声明:可以访问类的私有成员
friend void printStudentDetails(const Student& s);
// 静态成员函数
static int getStudentCount() {
return studentCount;
}
// 重载运算符:使对象支持比较
bool operator<(const Student& other) const {
return calculateAverage() < other.calculateAverage();
}
};
// 静态成员变量初始化
int Student::studentCount = 0;
// 友元函数定义
void printStudentDetails(const Student& s) {
cout << "=== 学生详细信息 ===" << endl;
cout << "姓名: " << s.name << endl; // 友元可以访问私有成员
cout << "学号: " << s.studentId << endl;
}
// ====================
// 6. 模板类
// ====================
// template: 泛型编程,支持多种数据类型
template<typename T>
class Container {
private:
vector<T> items;
public:
void add(const T& item) {
items.push_back(item);
}
void displayAll() const {
for (const auto& item : items) {
item.displayInfo();
}
}
// 模板函数
template<typename Compare>
void sortItems(Compare comp) {
std::sort(items.begin(), items.end(), comp);
}
size_t size() const {
return items.size();
}
};
// ====================
// 7. 函数定义
// ====================
// 显示主菜单
void displayMenu() {
cout << "\n========== 学生成绩管理系统 ==========" << endl;
cout << "1. 添加学生" << endl;
cout << "2. 显示所有学生" << endl;
cout << "3. 为学生添加成绩" << endl;
cout << "4. 按平均成绩排序" << endl;
cout << "5. 保存到文件" << endl;
cout << "6. 从文件加载" << endl;
cout << "7. 显示学生总数" << endl;
cout << "8. 使用模板容器示例" << endl;
cout << "0. 退出" << endl;
cout << "=====================================" << endl;
cout << "请选择操作: ";
}
// 获取有效输入
int getValidInput(int min, int max) {
int choice;
while (true) {
cin >> choice;
if (cin.fail() || choice < min || choice > max) {
cin.clear(); // 清除错误状态
cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 忽略错误输入
cout << "输入无效,请重新输入 (" << min << "-" << max << "): ";
} else {
cin.ignore(); // 清除换行符
break;
}
}
return choice;
}
// 保存数据到文件
void saveToFile(const Container<Student>& container, const string& filename) {
// ofstream: 输出文件流
ofstream outFile(filename);
if (!outFile) {
cerr << "无法打开文件: " << filename << endl;
return;
}
// 这里简化处理,实际项目需要更复杂的序列化
outFile << "学生总数: " << container.size() << endl;
outFile << "=== 学生数据结束 ===" << endl;
outFile.close();
cout << "数据已保存到 " << filename << endl;
}
// 从文件加载数据
void loadFromFile(const string& filename) {
// ifstream: 输入文件流
ifstream inFile(filename);
if (!inFile) {
cerr << "无法打开文件: " << filename << endl;
return;
}
string line;
while (getline(inFile, line)) {
cout << line << endl;
}
inFile.close();
cout << "数据已从 " << filename << " 加载" << endl;
}
// ====================
// 8. Lambda表达式
// ====================
// C++11特性:匿名函数
auto compareByAverageDesc = [](const Student& a, const Student& b) {
return a.calculateAverage() > b.calculateAverage();
};
// ====================
// 9. 主函数
// ====================
int main() {
// 设置控制台输出为UTF-8,支持中文
system("chcp 65001 > nul");
cout << "欢迎使用学生成绩管理系统!" << endl;
Container<Student> students;
int choice;
do {
displayMenu();
choice = getValidInput(0, 8);
try {
switch (choice) {
case 1: {
// 添加学生
if (students.size() >= MAX_STUDENTS) {
cout << "学生数量已达上限!" << endl;
break;
}
string name, id;
int age, gradeChoice;
cout << "请输入学生姓名: ";
getline(cin, name);
cout << "请输入学生年龄: ";
age = getValidInput(1, 100);
cout << "请输入学号: ";
getline(cin, id);
cout << "请选择年级 (1-大一, 2-大二, 3-大三, 4-大四): ";
gradeChoice = getValidInput(1, 4);
GradeLevel grade;
switch (gradeChoice) {
case 1: grade = GradeLevel::FRESHMAN; break;
case 2: grade = GradeLevel::SOPHOMORE; break;
case 3: grade = GradeLevel::JUNIOR; break;
case 4: grade = GradeLevel::SENIOR; break;
}
Student newStudent(name, age, id, grade);
// 添加成绩
char addScore;
cout << "是否添加成绩? (y/n): ";
cin >> addScore;
cin.ignore();
if (addScore == 'y' || addScore == 'Y') {
int scoreCount;
cout << "要添加几门成绩? ";
scoreCount = getValidInput(1, 10);
for (int i = 0; i < scoreCount; i++) {
cout << "请输入第 " << (i + 1) << " 门成绩: ";
int score = getValidInput(0, 100);
newStudent.addScore(score);
}
}
students.add(newStudent);
cout << "学生添加成功!" << endl;
break;
}
case 2:
// 显示所有学生
cout << "\n=== 所有学生信息 ===" << endl;
if (students.size() == 0) {
cout << "没有学生记录。" << endl;
} else {
students.displayAll();
}
break;
case 3:
// 这里简化为提示信息,实际需要实现选择学生并添加成绩
cout << "功能待实现: 请先选择学生,然后添加成绩" << endl;
break;
case 4:
// 按平均成绩排序
if (students.size() > 0) {
students.sortItems(compareByAverageDesc);
cout << "学生已按平均成绩降序排列!" << endl;
students.displayAll();
} else {
cout << "没有学生记录可排序。" << endl;
}
break;
case 5:
// 保存到文件
saveToFile(students, "students.txt");
break;
case 6:
// 从文件加载
loadFromFile("students.txt");
break;
case 7:
// 显示学生总数
cout << "当前学生总数: " << Student::getStudentCount() << endl;
Person::showPersonCount();
break;
case 8: {
// 模板容器示例
cout << "=== 模板容器示例 ===" << endl;
// 创建整数容器
Container<int> intContainer;
intContainer.add(10);
intContainer.add(20);
intContainer.add(5);
// 创建字符串容器
Container<string> strContainer;
strContainer.add("苹果");
strContainer.add("香蕉");
strContainer.add("橙子");
cout << "整数容器大小: " << intContainer.size() << endl;
cout << "字符串容器大小: " << strContainer.size() << endl;
break;
}
case 0:
cout << "感谢使用,再见!" << endl;
break;
default:
cout << "无效选择!" << endl;
}
} catch (const exception& e) {
// 异常处理
cerr << "发生错误: " << e.what() << endl;
}
} while (choice != 0);
return 0;
}
如何编译和运行
在Windows上:
使用MinGW (推荐):
下载并安装MinGW-w64
打开命令提示符或PowerShell
导航到代码所在目录
编译:g++ -std=c++11 student_management.cpp -o student_management.exe
运行:student_management.exe
使用Visual Studio:
创建新的C++控制台项目
将代码复制到main.cpp
按F5编译并运行
在Linux/macOS上:
打开终端
导航到代码所在目录
编译:g++ -std=c++11 student_management.cpp -o student_management
运行:./student_management
C++基础知识概览
-
预处理指令
#include:包含头文件
#define:定义宏
#ifdef/#endif:条件编译
-
基本数据类型
int:整数
double:双精度浮点数
char:字符
bool:布尔值
string:字符串(来自标准库)
-
复合数据类型
struct:结构体
class:类
enum:枚举
union:联合(未在示例中展示)
-
变量作用域
局部变量:函数内定义
全局变量:文件内定义
静态变量:static关键字
成员变量:类的组成部分
-
控制结构
if/else:条件判断
for:循环
while:循环
switch:多分支选择
break/continue:循环控制
-
函数
函数声明和定义
参数传递(值传递、引用传递)
返回值
函数重载
递归(未在示例中展示)
-
面向对象编程
类与对象
构造函数与析构函数
继承与多态
封装(public/private/protected)
虚函数与纯虚函数
-
内存管理
自动存储(栈)
动态存储(堆,使用new/delete)
智能指针(未在示例中展示)
-
标准库组件
vector:动态数组
map:关联数组
string:字符串
fstream:文件流
算法库:sort, find等
-
高级特性
模板(泛型编程)
异常处理
命名空间
Lambda表达式(C++11)
类型推导(auto)
学习建议
从简单的程序开始,逐步增加复杂度
多写代码,多调试
理解指针和内存管理
学习STL(标准模板库)
阅读优秀的开源代码
使用现代C++特性(C++11/14/17/20)
这个示例涵盖了C++的大部分核心概念,通过运行和修改这个程序,你可以快速上手C++编程。建议你尝试以下练习:
添加删除学生的功能
实现按姓名搜索学生
添加教师类并实现继承关系
使用智能指针改进内存管理
添加单元测试