C++
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented C++
-
Section 4: Memory Management
-
Section 5: Templates and Generic Programming
-
Section 6: The Standard Template Library
-
Section 7: Modern C++ Features
-
Section 8: Error Handling
-
Section 9: Multithreading
-
Section 10: Operator Overloading and Type Conversion
-
Section 11: Advanced Topics
-
Section 12: Tooling and Build Systems
-
Section 13: Design Patterns in C++
-
Section 14: Interfacing with C and Systems Programming
-
Section 15: Networking and IPC Basics
-
Section 16: Graphics and Game Programming Basics
-
Section 17: The Boost Libraries
-
Section 18: Data Structures and Algorithms in C++
-
Section 19: Practical Projects
-
Section 20: More Concurrency Patterns
-
Section 21: More OOP and Design Practice
-
Section 22: File I/O and Streams
-
Section 23: More Standard Library
-
Section 24: Practice Exercises
-
Section 25: Interview and Algorithm Practice
-
Section 26: Compiler and Language Internals
-
Section 27: GUI and Application Frameworks Overview
-
Section 28: Testing and Quality Practices
-
Section 29: Numerics Library
-
Section 30: Concepts Library (C++20)
-
Section 31: Ranges Library (C++20) In Depth
-
Section 32: More Utility Library
207: Practice Exercise: Building a Student Grading System
Alright, we've talked about the theory of data structures and object management, but it's time to actually get our hands dirty. We're going to build a Student Grading System. Now, I could just give you the finished code, but that's not how we actually work in the field. Let's build this out in real-time, make a few mistakes, and figure out the best way to handle the data.
Getting the skeleton together
First, I need a way to represent a student. A struct feels right here because we're mostly just grouping data together—a name and a grade. I'll throw them into a std::vector because I don't know how many students the user will enter.
struct Student {
std::string name;
double grade;
};
// ... inside main ...
std::vector<Student> classroom;
classroom.push_back({"Alice", 92.5});
classroom.push_back({"Bob", 78.0});
classroom.push_back({"Charlie", 88.2});
This looks clean enough. I can iterate through the vector and print the names and grades. So far, so good. But a grading system isn't useful if you can't modify the data, like when a student does extra credit.
Wait, why isn't the grade updating?
I want to write a quick helper function to bump up a student's grade. I'll try something like this:
void applyExtraCredit(Student s, double bonus) {
s.grade += bonus;
}
// Calling it in main:
applyExtraCredit(classroom[0], 2.0);
// Alice should now have 94.5
I run it, print Alice's grade, and... it's still 92.5. I've done this a hundred times, and it's always the same culprit. I'm passing the Student object by value. The function is creating a local copy of Alice, adding the bonus to that copy, and then destroying the copy when the function ends. The original Alice in my vector remains untouched.
I need to pass by reference so I'm operating on the actual memory location inside the vector:
void applyExtraCredit(Student& s, double bonus) {
s.grade += bonus;
}
Now, when I run it, Alice's grade actually hits 94.5. It's a small change—just one & symbol—but it's the difference between a working program and a very frustrating hour of debugging.
Handling the "Not Found" problem
Now let's get more realistic. I want to find a student by name and update their grade. I'll loop through the vector and check the name. But what happens if the user typos "Alise" instead of "Alice"?
void updateGrade(std::vector<Student>& students, std::string targetName, double newGrade) {
for (auto& s : students) {
if (s.name == targetName) {
s.grade = newGrade;
}
}
}
This works, but it's "silent." If the name isn't found, the function just finishes and the user has no idea why the grade didn't change. In a real app, that's a terrible user experience. I should probably return a boolean to indicate if the operation actually succeeded.
bool updateGrade(std::vector<Student>& students, std::string targetName, double newGrade) {
for (auto& s : students) {
if (s.name == targetName) {
s.grade = newGrade;
return true; // Found and updated!
}
}
return false; // We searched everyone and found nothing.
}
By returning a bool, I can now wrap the call in an if statement in main and print a "Student not found" warning. It makes the program feel robust rather than fragile.
Calculating the class average
Last thing: I need the class average. I could just loop through and sum the grades, but since we're using C++, I'm tempted to use <numeric>. However, std::accumulate doesn't natively know how to handle a vector of Student structs—it wants a vector of doubles.
I could write a manual loop, which is fine, but it's a great excuse to use a lambda. I'll tell accumulate to start at 0.0 and, for every student it encounters, just add their grade member to the running total.
#include <numeric>
double total = std::accumulate(classroom.begin(), classroom.end(), 0.0,
[](double sum, const Student& s) {
return sum + s.grade;
});
double average = total / classroom.size();
There it is. We started with a simple list, hit a wall with pass-by-value, fixed our error handling for searches, and used a lambda to keep the math concise. That's a basic but functional grading system.
📋 Practical Task
Exercise: Implement a Grade Distribution Report
Using the Student Grading System logic from the lesson, extend the program to generate a "Grade Distribution Report." Your task is to write a function that analyzes the std::vector<Student> and counts how many students fall into specific grade brackets.
Requirements:
- Create a function
void printDistribution(const std::vector<Student>& students). - The function should count and print how many students are in the following categories:
- A: 90 and above
- B: 80 to 89.9
- C: 70 to 79.9
- D: 60 to 69.9
- F: Below 60
- The function must take the vector by const reference to ensure no student data is accidentally modified during the report generation.
- Test your function with a vector containing at least 5 students with varying grades.
There are no comments for now.