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
5 changes: 3 additions & 2 deletions exercises/00_hello_world/main.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#include "../exercise.h"

using namespace std;
// READ: std streams <https://zh.cppreference.com/w/cpp/io/c/std_streams>
// READ: 流修饰符 <https://zh.cppreference.com/w/cpp/io/manip>
// READ: format in cxx20 <https://zh.cppreference.com/w/cpp/utility/format/format>

int main(int argc, char **argv) {
// TODO: 在控制台输出 "Hello, InfiniTensor!" 并换行
std::cout : "Hello, InfiniTensor!" + std::endl;
// std::cout : "Hello, InfiniTensor!" + std::endl;
std::cout<<"Hello, InfiniTensor!"<<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=5;
std::cout << x << " + " << x << " = " << x + x << std::endl;
return 0;
}
3 changes: 3 additions & 0 deletions exercises/02_function/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

// TODO: 在这里声明函数

int add(int a, int b);

int main(int argc, char **argv) {
ASSERT(add(123, 456) == 123 + 456, "add(123, 456) should be 123 + 456");

Expand All @@ -16,4 +18,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;
}
16 changes: 11 additions & 5 deletions exercises/04_static/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

// READ: `static` 关键字 <https://zh.cppreference.com/w/cpp/language/storage_duration>
// THINK: 这个函数的两个 `static` 各自的作用是什么?

// static修饰func函数,表示这个函数只在这个.cpp文件中可见
// 其作用是防止重复定义,如果在另一个.cpp文件中定义了这个函数,加上static后,这两个函数就不会冲突,编译器不会发生“重复定义”错误

// static修饰static_局部变量,其作用是`静态存储期`
// 该变量**只初始化一次**,函数在运行结束后,变量不会被销毁,而是保存在内存中
static int func(int param) {
static int static_ = param;
// std::cout << "static_ = " << static_ << std::endl;
Expand All @@ -10,10 +16,10 @@ static int func(int param) {

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;
}
5 changes: 3 additions & 2 deletions exercises/05_constexpr/main.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "../exercise.h"

// constexpr(constant expression),常量表达式
// 告诉编译器,这是一个常量,需要在编译期间就要进行计算
constexpr unsigned long long fibonacci(int i) {
switch (i) {
case 0:
Expand All @@ -19,8 +21,7 @@ int main(int argc, char **argv) {
// TODO: 观察错误信息,修改一处,使代码编译运行
// PS: 编译运行,但是不一定能算出结果……
constexpr auto ANS_N = 90;
constexpr auto ANS = fibonacci(ANS_N);
auto ANS = fibonacci(ANS_N);
std::cout << "fibonacci(" << ANS_N << ") = " << ANS << std::endl;

return 0;
}
7 changes: 5 additions & 2 deletions exercises/06_array/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

// READ: 数组 <https://zh.cppreference.com/w/cpp/language/array>

// 数组定义
unsigned long long arr[90]{0, 1};
unsigned long long fibonacci(int i) {
switch (i) {
Expand All @@ -11,13 +12,15 @@ unsigned long long fibonacci(int i) {
return 1;
default:
// TODO: 补全三目表达式缺失的部分
return <condition> ? <cache> : (arr[i] = fibonacci(i - 1) + fibonacci(i - 2));
return arr[i]!=0 ? 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");
// std::cout<<sizeof(arr)<<std::endl;
// unsigned long long 为 8 个字节
ASSERT(sizeof(arr) == 720, "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 (; cached<96; ++cached) {
cache[cached] = cache[cached - 1] + cache[cached - 2];
}
return cache[i];
Expand Down
10 changes: 10 additions & 0 deletions exercises/08_pointer/main.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
#include "../exercise.h"

// READ: 数组向指针退化 <https://zh.cppreference.com/w/cpp/language/array#%E6%95%B0%E7%BB%84%E5%88%B0%E6%8C%87%E9%92%88%E7%9A%84%E9%80%80%E5%8C%96>
//bool is_fibonacci(int ptr[], int len, int stride)
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 = 0;i<len-2;++i){
//int current=ptr[i*stride];
int current = *(ptr+i*stride);
int next = *(ptr+(i+1)*stride);
int next_next = *(ptr+(i+2)*stride);
if(current+next!=next_next){
return false;
}
}
return true;
}

Expand Down
14 changes: 13 additions & 1 deletion exercises/09_enum&union/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

// READ: 枚举类型 <https://zh.cppreference.com/w/cpp/language/enum>

// enum(枚举)是一种用户自定义的数据类型,用于为一组`整数常量`分配好听的名字。使用枚举可以让代码更具可读性和可维护性。

// `enum` 是 C 的兼容类型,本质上其对应类型的常量。
// 在 `enum` 中定义标识符等价于定义 constexpr 常量,
// 这些标识符不需要前缀,可以直接引用。
// 因此 `enum` 定义会污染命名空间。

// 不限定作用域枚举,不推荐作法
// 可以实现隐式转换:int x =Red
enum ColorEnum : unsigned char {
COLOR_RED = 31,
COLOR_GREEN,
Expand All @@ -16,6 +21,10 @@ enum ColorEnum : unsigned char {
// 有作用域枚举型是 C++ 引入的类型安全枚举。
// 其内部标识符需要带前缀引用,如 `Color::Red`。
// 作用域枚举型可以避免命名空间污染,并提供类型安全保证。

// 限定作用域枚举,推荐做法
// 使用时必须带上类名(作用域)
// TrafficLight s = TrafficLight::RED;
enum class Color : int {
Red = COLOR_RED,
Green,
Expand All @@ -30,14 +39,17 @@ ColorEnum convert_by_pun(Color c) {
// 但这种写法实际上仅在 C 语言良定义,在 C++ 中是未定义行为。
// 这是比较少见的 C++ 不与 C 保持兼容的特性。
// READ: 类型双关 <https://tttapa.github.io/Pages/Programming/Cpp/Practices/type-punning.html>

//union(联合体/共用体)是 C++ 中一种特殊的类类型。它最显著的特征是:所有成员共享同一块内存地址
//但在同一时刻只能使用其中的一个成员,这就意味着数据会被覆盖,是一种极端节省内存的写法
union TypePun {
ColorEnum e;
Color c;
};

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

pun.c = c;//c值写入,e值被覆盖
return pun.e;
}

Expand Down
19 changes: 14 additions & 5 deletions exercises/10_trivial/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,27 @@ struct FibonacciCache {
};

// TODO: 实现正确的缓存优化斐波那契计算
static unsigned long long fibonacci(FibonacciCache &cache, int i) {
for (; false; ++cached) {
cache[cached] = cache[cached - 1] + cache[cached - 2];
// static unsigned long long fibonacci(FibonacciCache &cache, int i) {
// for (; false; ++cached) {
// cache[cached] = cache[cached - 1] + cache[cached - 2];
// }
// return cache.cache[i];
// }
static unsigned long long fibonacci(FibonacciCache &cache, int i){
if(i>=16){
return 0;
}
for(;cache.cached<=i;++cache.cached){
cache.cache[cache.cached]=cache.cache[cache.cached-1]+cache.cache[cache.cached-2];
}
return cache.cache[i];
}

}
int main(int argc, char **argv) {
// TODO: 初始化缓存结构体,使计算正确
// NOTICE: C/C++ 中,读取未初始化的变量(包括结构体变量)是未定义行为
// READ: 初始化的各种写法 <https://zh.cppreference.com/w/cpp/language/initialization>
FibonacciCache fib;
FibonacciCache fib{{0,1},2};
ASSERT(fibonacci(fib, 10) == 55, "fibonacci(10) should be 55");
std::cout << "fibonacci(10) = " << fibonacci(fib, 10) << std::endl;
return 0;
Expand Down
11 changes: 7 additions & 4 deletions exercises/11_method/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,19 @@ struct Fibonacci {

// TODO: 实现正确的缓存优化斐波那契计算
unsigned long long get(int i) {
for (; false; ++cached) {
cache[cached] = cache[cached - 1] + cache[cached - 2];
if (i>=128){
return 0;
}
return cache[i];
for (; this->cached<=i; ++this->cached) {
this->cache[this->cached] = this->cache[this->cached - 1] + this->cache[this->cached - 2];
}
return this->cache[i];
}
};

int main(int argc, char **argv) {
// TODO: 初始化缓存结构体,使计算正确
Fibonacci fib;
Fibonacci fib{{0,1},2};
ASSERT(fib.get(10) == 55, "fibonacci(10) should be 55");
std::cout << "fibonacci(10) = " << fib.get(10) << std::endl;
return 0;
Expand Down
11 changes: 10 additions & 1 deletion exercises/12_method_const/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,20 @@
struct Fibonacci {
int numbers[11];
// TODO: 修改方法签名和实现,使测试通过
int get(int i) {
// int get(int i) {
// }
int get(int i) const {
if (i<0 || i>=11)
{
return 0;
}

return numbers[i];
}
};

int main(int argc, char **argv) {
//关键字 constexpr 意味着对象 FIB 是编译期常量,它隐含了 const 属性。在 C++ 中,const 对象只能调用 const 成员函数。
Fibonacci constexpr FIB{{0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55}};
ASSERT(FIB.get(10) == 55, "fibonacci(10) should be 55");
std::cout << "fibonacci(10) = " << FIB.get(10) << std::endl;
Expand Down
10 changes: 8 additions & 2 deletions exercises/13_class/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,23 @@
// 因此必须提供构造器来初始化字段。
// READ: 构造器 <https://zh.cppreference.com/w/cpp/language/constructor>
class Fibonacci {
//size_t 无符号整数类型
size_t cache[16];
int cached;

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

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

public:
// TODO: 实现动态设置容量的构造器
DynFibonacci(int capacity): cache(new ?), cached(?) {}
// cache = new size_t[capacity];动态初始化数组
// 成员初始化列表(Member Initializer List):构造函数:函数名(参数) : 成员1(初始化), 成员2(初始化) { 函数体 }
DynFibonacci(int capacity): cache(new size_t[capacity]), cached(2) {
cache[0] = 0;
cache[1] = 1;
}

// TODO: 实现析构器,释放缓存空间
~DynFibonacci();
~DynFibonacci() {
// 使用 delete[]:因为 cache 是用 new[] 分配的数组
// 如果用 delete cache(没有 []),会导致未定义行为
delete[] cache;
}

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

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

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

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

// TODO: 实现正确的缓存优化斐波那契计算
size_t get(int i) {
for (; false; ++cached) {
cache[cached] = cache[cached - 1] + cache[cached - 2];
for (; this->cached <= i; ++this->cached) {
this->cache[this->cached] = this->cache[this->cached - 1] + this->cache[this->cached - 2];
}
return cache[i];
}
Expand Down
Loading