Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions a.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include <iostream>
#include <type_traits> // 用于检查类型
#include <bits/stdc++.h> // 包含所有标准库头文件

// 这是一个简单的帮助函数,用来告诉你一个值是左值还是右值
void print_value_category(int& val) {
std::cout << " -> 接收到一个【左值引用】" << std::endl;
}

void print_value_category(int&& val) {
std::cout << " -> 接收到一个【右值引用】" << std::endl;
}

// 我们的模板函数,使用了 T&& 形参
template <typename T>
void inspect_param(T&& param) {
std::cout << " 在 inspect_param 内部,参数 param 的类型是: ";
// 注意:decltype(param) 会告诉你 param 变量本身的类型
// std::is_lvalue_reference 和 std::is_rvalue_reference 可以确认其引用类型
if (std::is_lvalue_reference<decltype(param)>::value) {
std::cout << "左值引用 (T&)";
} else if (std::is_rvalue_reference<decltype(param)>::value) {
std::cout << "右值引用 (T&&)";
} else {
std::cout << "值类型";
}
std::cout << "。\n";

// param 虽然类型可能是右值引用,但因为它有了名字,在函数内部它本身是【左值】
std::cout << " 现在把 param 传给 print_value_category:";
print_value_category(param); // 注意这里:直接传 param 总是传左值!
}

void example_reference_collapsing() {
std::cout << "--- 场景一:传入一个【右值】(字面量 10) ---" << std::endl;
inspect_param(10); // 传入一个右值字面量

std::cout << "\n--- 场景二:传入一个【左值】(变量 num) ---" << std::endl;
int num = 20; // num 是一个左值
inspect_param(num); // 传入一个左值变量
}

/*
运行 example_reference_collapsing() 的输出会是这样:

--- 场景一:传入一个【右值】(字面量 10) ---
在 inspect_param 内部,参数 param 的类型是: 右值引用 (T&&)。
现在把 param 传给 print_value_category: -> 接收到一个【左值引用】

--- 场景二:传入一个【左值】(变量 num) ---
在 inspect_param 内部,参数 param 的类型是: 左值引用 (T&)。
现在把 param 传给 print_value_category: -> 接收到一个【左值引用】
*/
2 changes: 1 addition & 1 deletion exercises/00_hello_world/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@

int main(int argc, char **argv) {
// TODO: 在控制台输出 "Hello, InfiniTensor!" 并换行
std::cout : "Hello, InfiniTensor!" + std::endl;
std::cout << "Hello, InfiniTensor!" << std::endl;
return 0;
}
1 change: 1 addition & 0 deletions exercises/01_variable&add/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
int main(int argc, char **argv) {
// TODO: 补全变量定义并打印加法运算
// x ?
int x = 1;
std::cout << x << " + " << x << " = " << x + x << std::endl;
return 0;
}
4 changes: 3 additions & 1 deletion exercises/02_function/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
// NOTICE: 补充由内而外读法的机翻解释 <https://learn.microsoft.com/zh-cn/cpp/c-language/interpreting-more-complex-declarators?view=msvc-170>

// TODO: 在这里声明函数

int add(int a, int b);
int main(int argc, char **argv) {
// 断言add(123, 456)的返回值等于123 + 456
ASSERT(add(123, 456) == 123 + 456, "add(123, 456) should be 123 + 456");

auto x = 1, y = 2;
Expand All @@ -16,4 +17,5 @@ int main(int argc, char **argv) {

int add(int a, int b) {
// TODO: 补全函数定义,但不要移动代码行
return a + b;
}
8 changes: 4 additions & 4 deletions exercises/03_argument&parameter/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ void func(int);
// TODO: 为下列 ASSERT 填写正确的值
int main(int argc, char **argv) {
auto arg = 99;
ASSERT(arg == ?, "arg should be ?");
ASSERT(arg == 99, "arg should be 99");
std::cout << "befor func call: " << arg << std::endl;
func(arg);
ASSERT(arg == ?, "arg should be ?");
ASSERT(arg == 99, "arg should be 99");
std::cout << "after func call: " << arg << std::endl;
return 0;
}

// TODO: 为下列 ASSERT 填写正确的值
void func(int param) {
ASSERT(param == ?, "param should be ?");
ASSERT(param == 99, "param should be 99");
std::cout << "befor add: " << param << std::endl;
param += 1;
ASSERT(param == ?, "param should be ?");
ASSERT(param == 100, "param should be 100");
std::cout << "after add: " << param << std::endl;
}
12 changes: 6 additions & 6 deletions exercises/04_static/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
// THINK: 这个函数的两个 `static` 各自的作用是什么?
static int func(int param) {
static int static_ = param;
// std::cout << "static_ = " << static_ << std::endl;
std::cout << "static_ = " << static_ << std::endl;
return static_++;
}

int main(int argc, char **argv) {
// TODO: 将下列 `?` 替换为正确的数字
ASSERT(func(5) == ?, "static variable value incorrect");
ASSERT(func(4) == ?, "static variable value incorrect");
ASSERT(func(3) == ?, "static variable value incorrect");
ASSERT(func(2) == ?, "static variable value incorrect");
ASSERT(func(1) == ?, "static variable value incorrect");
ASSERT(func(5) == 5, "static variable value incorrect");
ASSERT(func(4) == 6, "static variable value incorrect");
ASSERT(func(3) == 7, "static variable value incorrect");
ASSERT(func(2) == 8, "static variable value incorrect");
ASSERT(func(1) == 9, "static variable value incorrect");
return 0;
}
2 changes: 1 addition & 1 deletion exercises/05_constexpr/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ int main(int argc, char **argv) {

// TODO: 观察错误信息,修改一处,使代码编译运行
// PS: 编译运行,但是不一定能算出结果……
constexpr auto ANS_N = 90;
constexpr auto ANS_N = 30;
constexpr auto ANS = fibonacci(ANS_N);
std::cout << "fibonacci(" << ANS_N << ") = " << ANS << std::endl;

Expand Down
4 changes: 2 additions & 2 deletions exercises/06_array/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ unsigned long long fibonacci(int i) {
return 1;
default:
// TODO: 补全三目表达式缺失的部分
return <condition> ? <cache> : (arr[i] = fibonacci(i - 1) + fibonacci(i - 2));
return arr[i] ? arr[i] : (arr[i] = fibonacci(i - 1) + fibonacci(i - 2));
}
}

int main(int argc, char **argv) {
// TODO: 为此 ASSERT 填写正确的值
ASSERT(sizeof(arr) == ?, "sizeof array is size of all its elements");
ASSERT(sizeof(arr) == 90 * sizeof(unsigned long long), "sizeof array is size of all its elements");
// ---- 不要修改以下代码 ----
ASSERT(fibonacci(2) == 1, "fibonacci(2) should be 1");
ASSERT(fibonacci(20) == 6765, "fibonacci(20) should be 6765");
Expand Down
4 changes: 2 additions & 2 deletions exercises/07_loop/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
// READ: 纯函数 <https://zh.wikipedia.org/wiki/%E7%BA%AF%E5%87%BD%E6%95%B0>
static unsigned long long fibonacci(int i) {
// TODO: 为缓存设置正确的初始值
static unsigned long long cache[96], cached;
static unsigned long long cache[96] = {0, 1}, cached = 2;
// TODO: 设置正确的循环条件
for (; false; ++cached) {
for (; (int)cached <= i; ++cached) {
cache[cached] = cache[cached - 1] + cache[cached - 2];
}
return cache[i];
Expand Down
9 changes: 9 additions & 0 deletions exercises/08_pointer/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ bool is_fibonacci(int *ptr, int len, int stride) {
ASSERT(len >= 3, "`len` should be at least 3");
// TODO: 编写代码判断从 ptr 开始,每 stride 个元素取 1 个元素,组成长度为 n 的数列是否满足
// arr[i + 2] = arr[i] + arr[i + 1]
for (int i = 2; i < len; i++) {
int* index1 = ptr + stride * (i - 2);
int* index2 = ptr + stride * (i - 1);
int* index3 = ptr + stride * i;
if (*index3 != *index1 + *index2) {
return false;
}

}
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion exercises/09_enum&union/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ ColorEnum convert_by_pun(Color c) {

TypePun pun;
// TODO: 补全类型双关转换

pun.c = c;
return pun.e;
}

Expand Down
8 changes: 4 additions & 4 deletions exercises/10_trivial/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
// READ: Trivial type <https://learn.microsoft.com/zh-cn/cpp/cpp/trivial-standard-layout-and-pod-types?view=msvc-170>

struct FibonacciCache {
unsigned long long cache[16];
int cached;
unsigned long long cache[16] = {0, 1};
int cached = 2;
};

// TODO: 实现正确的缓存优化斐波那契计算
static unsigned long long fibonacci(FibonacciCache &cache, int i) {
for (; false; ++cached) {
cache[cached] = cache[cached - 1] + cache[cached - 2];
for (; cache.cached <= i; ++cache.cached) {
cache.cache[cache.cached] = cache.cache[cache.cached - 1] + cache.cache[cache.cached - 2];
}
return cache.cache[i];
}
Expand Down
6 changes: 3 additions & 3 deletions exercises/11_method/main.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#include "../exercise.h"

struct Fibonacci {
unsigned long long cache[128];
int cached;
unsigned long long cache[128] = {0, 1};
int cached = 2;

// TODO: 实现正确的缓存优化斐波那契计算
unsigned long long get(int i) {
for (; false; ++cached) {
for (; cached <= i; ++cached) {
cache[cached] = cache[cached - 1] + cache[cached - 2];
}
return cache[i];
Expand Down
3 changes: 2 additions & 1 deletion exercises/12_method_const/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
struct Fibonacci {
int numbers[11];
// TODO: 修改方法签名和实现,使测试通过
int get(int i) {
int get(int i) const {
return numbers[i];
}
};

Expand Down
8 changes: 6 additions & 2 deletions exercises/13_class/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@ class Fibonacci {

public:
// TODO: 实现构造器
// Fibonacci()
Fibonacci() {
cache[0] = 0;
cache[1] = 1;
cached = 2;
}

// TODO: 实现正确的缓存优化斐波那契计算
size_t get(int i) {
for (; false; ++cached) {
for (; cached <= i; ++cached) {
cache[cached] = cache[cached - 1] + cache[cached - 2];
}
return cache[i];
Expand Down
9 changes: 6 additions & 3 deletions exercises/14_class_destruct/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@ class DynFibonacci {

public:
// TODO: 实现动态设置容量的构造器
DynFibonacci(int capacity): cache(new ?), cached(?) {}
DynFibonacci(int capacity): cache(new size_t[capacity]), cached(2) {
cache[0] = 0;
cache[1] = 1;
}

// TODO: 实现析构器,释放缓存空间
~DynFibonacci();
~DynFibonacci() = default;

// TODO: 实现正确的缓存优化斐波那契计算
size_t get(int i) {
for (; false; ++cached) {
for (; cached <= i; ++cached) {
cache[cached] = cache[cached - 1] + cache[cached - 2];
}
return cache[i];
Expand Down
17 changes: 13 additions & 4 deletions exercises/15_class_clone/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,26 @@ class DynFibonacci {

public:
// TODO: 实现动态设置容量的构造器
DynFibonacci(int capacity): cache(new ?), cached(?) {}
DynFibonacci(int capacity): cache(new size_t[capacity]), cached(2) {
cache[0] = 0;
cache[1] = 1;
}

// TODO: 实现复制构造器
DynFibonacci(DynFibonacci const &) = delete;
DynFibonacci(DynFibonacci const &T) {
this->cached = T.cached;
this->cache = new size_t[T.cached];
for (int i = 0; i < T.cached; ++i) {
this->cache[i] = T.cache[i];
}
}

// TODO: 实现析构器,释放缓存空间
~DynFibonacci();
~DynFibonacci() = default;

// TODO: 实现正确的缓存优化斐波那契计算
size_t get(int i) {
for (; false; ++cached) {
for (; cached <= i; ++cached) {
cache[cached] = cache[cached - 1] + cache[cached - 2];
}
return cache[i];
Expand Down
33 changes: 28 additions & 5 deletions exercises/16_class_move/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,44 @@ class DynFibonacci {

public:
// TODO: 实现动态设置容量的构造器
DynFibonacci(int capacity): cache(new ?), cached(?) {}
DynFibonacci(int capacity): cache(new size_t[capacity]), cached(2) {
cache[0] = 0;
cache[1] = 1;
}

// TODO: 实现移动构造器
DynFibonacci(DynFibonacci &&) noexcept = delete;
DynFibonacci(DynFibonacci && T) noexcept {
cache = std::move(T.cache);
cached = std::move(T.cached);
delete[] T.cache;
T.cache = nullptr;
T.cached = 0;
}

// TODO: 实现移动赋值
// NOTICE: ⚠ 注意移动到自身问题 ⚠
DynFibonacci &operator=(DynFibonacci &&) noexcept = delete;
DynFibonacci &operator=(DynFibonacci && T) noexcept {
if (this == &T) {
return *this;
}
cache = std::move(T.cache);
cached = std::move(T.cached);
delete[] T.cache;
T.cache = nullptr;
T.cached = 0;
return *this;
}

// TODO: 实现析构器,释放缓存空间
~DynFibonacci();
~DynFibonacci() {
delete[] cache;
cache = nullptr;
cached = 0;
}

// TODO: 实现正确的缓存优化斐波那契计算
size_t operator[](int i) {
for (; false; ++cached) {
for (; cached <= i; ++cached) {
cache[cached] = cache[cached - 1] + cache[cached - 2];
}
return cache[i];
Expand Down
6 changes: 3 additions & 3 deletions exercises/17_class_derive/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ int main(int argc, char **argv) {
B b = B(3);

// TODO: 补全三个类型的大小
static_assert(sizeof(X) == ?, "There is an int in X");
static_assert(sizeof(A) == ?, "There is an int in A");
static_assert(sizeof(B) == ?, "B is an A with an X");
static_assert(sizeof(X) == sizeof(int), "There is an int in X");
static_assert(sizeof(A) == sizeof(int), "There is an int in A");
static_assert(sizeof(B) == sizeof(int) * 2, "B is an A with an X");

i = 0;
std::cout << std::endl
Expand Down
Loading