Initial Course
This commit is contained in:
@@ -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
|
||||
)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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");
|
||||
}
|
||||
Reference in New Issue
Block a user