Initial Course

This commit is contained in:
David Gil de Gómez Pérez
2026-08-11 17:40:36 +03:00
commit 9aed1d1d86
202 changed files with 3420 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
add_course_exercise(
NAME hello_world
MODULE 01_fundamentals
STANDARD 17
SOURCES
src/hello_world.cpp
test/hello_world_test.cpp
)
add_course_exercise(
NAME variables_and_types
MODULE 01_fundamentals
STANDARD 17
SOURCES
src/variables_and_types.cpp
test/variables_and_types_test.cpp
)
add_course_exercise(
NAME operators
MODULE 01_fundamentals
STANDARD 17
SOURCES
src/operators.cpp
test/operators_test.cpp
)
add_course_exercise(
NAME basic_io
MODULE 01_fundamentals
STANDARD 17
SOURCES
src/basic_io.cpp
test/basic_io_test.cpp
)
+34
View File
@@ -0,0 +1,34 @@
# Module 01: C++ Fundamentals
## Learning Goals
- Understand the structure of a C++ program (`main`, headers, translation units)
- Work with fundamental types (`int`, `double`, `bool`, `char`)
- Use literals, constants, and basic I/O
- Apply arithmetic, relational, and logical operators
- Read and write formatted output
## Exercises
| Exercise | Topic | Standard |
|----------|-------|----------|
| `hello_world` | First program, returning values from functions | C++17 |
| `variables_and_types` | Types, `auto`, type aliases | C++17 |
| `operators` | Arithmetic, comparisons, bitwise ops | C++17 |
| `basic_io` | Streams, string formatting | C++17 |
## How to Work
1. Open the exercise header in `include/` to see the required API.
2. Implement the functions in `src/`.
3. Run the corresponding test target in CLion or with CTest.
4. All tests must pass before moving on.
## Run Tests (CLion)
Select a target like `01_fundamentals_hello_world` and click Run, or use:
```bash
cmake --build build --target 01_fundamentals_hello_world
ctest --test-dir build -R 01_fundamentals_hello_world
```
@@ -0,0 +1,12 @@
#pragma once
#include <string>
#include <vector>
namespace fundamentals {
[[nodiscard]] auto join_words(const std::vector<std::string>& words, char separator) -> std::string;
[[nodiscard]] auto parse_integers(const std::string& csv) -> std::vector<int>;
[[nodiscard]] auto format_score(const std::string& player, int score) -> std::string;
} // namespace fundamentals
@@ -0,0 +1,12 @@
#pragma once
namespace fundamentals {
// Return a greeting message for the given name.
// Example: greet("Ada") -> "Hello, Ada!"
[[nodiscard]] auto greet(const char* name) -> const char*;
// Return the program entry convention value for success.
[[nodiscard]] constexpr auto program_exit_success() -> int { return 0; }
} // namespace fundamentals
@@ -0,0 +1,13 @@
#pragma once
#include <cstdint>
namespace fundamentals {
[[nodiscard]] auto absolute_difference(int lhs, int rhs) -> int;
[[nodiscard]] auto is_in_range(int value, int min, int max) -> bool;
[[nodiscard]] auto count_set_bits(std::uint8_t value) -> int;
[[nodiscard]] auto logical_and(bool lhs, bool rhs) -> bool;
[[nodiscard]] auto logical_or(bool lhs, bool rhs) -> bool;
} // namespace fundamentals
@@ -0,0 +1,15 @@
#pragma once
#include <cstdint>
#include <string>
namespace fundamentals {
[[nodiscard]] auto add_integers(int lhs, int rhs) -> int;
[[nodiscard]] auto multiply_doubles(double lhs, double rhs) -> double;
[[nodiscard]] auto is_even(std::int64_t value) -> bool;
[[nodiscard]] auto describe_type(int value) -> std::string;
[[nodiscard]] auto describe_type(double value) -> std::string;
[[nodiscard]] auto describe_type(bool value) -> std::string;
} // namespace fundamentals
+28
View File
@@ -0,0 +1,28 @@
#include "basic_io.hpp"
#include <sstream>
#include <string>
namespace fundamentals {
auto join_words(const std::vector<std::string>& words, char separator) -> std::string {
// TODO: Join words with separator, no trailing separator.
(void)words;
(void)separator;
return {};
}
auto parse_integers(const std::string& csv) -> std::vector<int> {
// TODO: Parse comma-separated integers (e.g. "1,2,3").
(void)csv;
return {};
}
auto format_score(const std::string& player, int score) -> std::string {
// TODO: Return "<player> scored <score> points".
(void)player;
(void)score;
return {};
}
} // namespace fundamentals
@@ -0,0 +1,11 @@
#include "hello_world.hpp"
namespace fundamentals {
auto greet(const char* name) -> const char* {
// TODO: Return a static string in the format "Hello, <name>!"
(void)name;
return "Hello, World!";
}
} // namespace fundamentals
+40
View File
@@ -0,0 +1,40 @@
#include "operators.hpp"
namespace fundamentals {
auto absolute_difference(int lhs, int rhs) -> int {
// TODO: Return |lhs - rhs| without using std::abs.
(void)lhs;
(void)rhs;
return 0;
}
auto is_in_range(int value, int min, int max) -> bool {
// TODO: Return true when min <= value <= max (inclusive).
(void)value;
(void)min;
(void)max;
return false;
}
auto count_set_bits(std::uint8_t value) -> int {
// TODO: Count how many bits are set to 1.
(void)value;
return 0;
}
auto logical_and(bool lhs, bool rhs) -> bool {
// TODO: Implement logical AND without using &&.
(void)lhs;
(void)rhs;
return false;
}
auto logical_or(bool lhs, bool rhs) -> bool {
// TODO: Implement logical OR without using ||.
(void)lhs;
(void)rhs;
return false;
}
} // namespace fundamentals
@@ -0,0 +1,43 @@
#include "variables_and_types.hpp"
namespace fundamentals {
auto add_integers(int lhs, int rhs) -> int {
// TODO: Return the sum.
(void)lhs;
(void)rhs;
return 0;
}
auto multiply_doubles(double lhs, double rhs) -> double {
// TODO: Return the product.
(void)lhs;
(void)rhs;
return 0.0;
}
auto is_even(std::int64_t value) -> bool {
// TODO: Return true when value is divisible by 2.
(void)value;
return false;
}
auto describe_type(int value) -> std::string {
// TODO: Return "int:" followed by the decimal representation.
(void)value;
return "int:0";
}
auto describe_type(double value) -> std::string {
// TODO: Return "double:" followed by the value with one decimal place.
(void)value;
return "double:0.0";
}
auto describe_type(bool value) -> std::string {
// TODO: Return "bool:true" or "bool:false".
(void)value;
return "bool:false";
}
} // namespace fundamentals
@@ -0,0 +1,18 @@
#include "basic_io.hpp"
#include <gtest/gtest.h>
TEST(BasicIo, JoinWords) {
EXPECT_EQ(fundamentals::join_words({"C", "Plus", "Plus"}, '-'), "C-Plus-Plus");
EXPECT_EQ(fundamentals::join_words({"solo"}, ','), "solo");
EXPECT_EQ(fundamentals::join_words({}, ','), "");
}
TEST(BasicIo, ParseIntegers) {
EXPECT_EQ(fundamentals::parse_integers("1,2,3"), (std::vector<int>{1, 2, 3}));
EXPECT_EQ(fundamentals::parse_integers("42"), (std::vector<int>{42}));
}
TEST(BasicIo, FormatScore) {
EXPECT_EQ(fundamentals::format_score("Alice", 150), "Alice scored 150 points");
}
@@ -0,0 +1,12 @@
#include "hello_world.hpp"
#include <gtest/gtest.h>
TEST(HelloWorld, GreetsByName) {
EXPECT_STREQ(fundamentals::greet("Ada"), "Hello, Ada!");
EXPECT_STREQ(fundamentals::greet("Bjarne"), "Hello, Bjarne!");
}
TEST(HelloWorld, ExitSuccessIsZero) {
EXPECT_EQ(fundamentals::program_exit_success(), 0);
}
@@ -0,0 +1,25 @@
#include "operators.hpp"
#include <gtest/gtest.h>
TEST(Operators, AbsoluteDifference) {
EXPECT_EQ(fundamentals::absolute_difference(5, 9), 4);
EXPECT_EQ(fundamentals::absolute_difference(-3, 2), 5);
}
TEST(Operators, RangeCheck) {
EXPECT_TRUE(fundamentals::is_in_range(5, 1, 10));
EXPECT_FALSE(fundamentals::is_in_range(0, 1, 10));
}
TEST(Operators, CountSetBits) {
EXPECT_EQ(fundamentals::count_set_bits(0b00001111), 4);
EXPECT_EQ(fundamentals::count_set_bits(0b10101010), 4);
}
TEST(Operators, LogicalOperations) {
EXPECT_TRUE(fundamentals::logical_and(true, true));
EXPECT_FALSE(fundamentals::logical_and(true, false));
EXPECT_TRUE(fundamentals::logical_or(false, true));
EXPECT_FALSE(fundamentals::logical_or(false, false));
}
@@ -0,0 +1,25 @@
#include "variables_and_types.hpp"
#include <gtest/gtest.h>
TEST(VariablesAndTypes, AddsIntegers) {
EXPECT_EQ(fundamentals::add_integers(2, 3), 5);
EXPECT_EQ(fundamentals::add_integers(-4, 10), 6);
}
TEST(VariablesAndTypes, MultipliesDoubles) {
EXPECT_DOUBLE_EQ(fundamentals::multiply_doubles(2.5, 4.0), 10.0);
}
TEST(VariablesAndTypes, DetectsEvenNumbers) {
EXPECT_TRUE(fundamentals::is_even(0));
EXPECT_TRUE(fundamentals::is_even(42));
EXPECT_FALSE(fundamentals::is_even(7));
}
TEST(VariablesAndTypes, DescribesTypes) {
EXPECT_EQ(fundamentals::describe_type(7), "int:7");
EXPECT_EQ(fundamentals::describe_type(3.5), "double:3.5");
EXPECT_EQ(fundamentals::describe_type(true), "bool:true");
EXPECT_EQ(fundamentals::describe_type(false), "bool:false");
}