-
Notifications
You must be signed in to change notification settings - Fork 137
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
去除文件空格,添加一些 README 文件,创建 SUMMARY 文件以支持 GitBook
- Loading branch information
Showing
7 changed files
with
293 additions
and
246 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Summary | ||
|
||
* [作业与解析](README.md) | ||
* [C++CoreGuidelines](src/C++CoreGuidelines/README.md) | ||
- [第一章-简介](src/C++CoreGuidelines/第1章-简介.md) | ||
- [第二章-理念](src/C++CoreGuidelines/第2章-理念.md) | ||
- [第三章-接口](src/C++CoreGuidelines/第3章-接口.md) | ||
- [第四章-函数](src/C++CoreGuidelines/第4章-函数.md) | ||
- [第五章-类和类层次结构](src/C++CoreGuidelines/第5章-类和类层次结构.md) | ||
* [卢瑟日经](src/卢瑟日经/README.md) | ||
- [赋值运算符求值顺序的问题](src/卢瑟日经/赋值运算符求值顺序问题.md) | ||
- [函数调用禁止隐式转换](src/卢瑟日经/函数调用禁止隐式转换.md) | ||
- [数组&指针](src/卢瑟日经/数组&指针.md) | ||
- [同步、异步、阻塞](src/卢瑟日经/同步、异步、阻塞.md) | ||
- [为什么优先成员初始化器](src/卢瑟日经/为什么优先成员初始化器.md) | ||
- [重载operator=要不要检查自赋值?](src/卢瑟日经/重载operator=要不要检查自赋值?.md) | ||
- [C&C++伪规则和错误的看法](src/卢瑟日经/C&C++伪规则和错误的看法.md) | ||
- [catch(auto)的问题](src/卢瑟日经/catch(auto)的问题.md) | ||
- [detach的问题](src/卢瑟日经/detach的问题.md) | ||
* [基础性C++题目与答案](src/基础性C++题目/README.md) | ||
- [20231002 基础C++题目](src/基础性C++题目/20231002基础C++题目.md) | ||
- [20231017基础C++题目(转换的使用)](src/基础性C++题目/20231017基础C++题目(转换的使用).md) | ||
- [20231126基础C++题目(数组退化)](src/基础性C++题目/20231126基础C++题目(数组退化).md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# 卢瑟日经 | ||
|
||
一些常见的卢瑟问题。 | ||
|
||
**目录一览**: | ||
|
||
- [赋值运算符求值顺序的问题](赋值运算符求值顺序问题.md) | ||
- [函数调用禁止隐式转换](函数调用禁止隐式转换.md) | ||
- [数组&指针](数组&指针.md) | ||
- [同步、异步、阻塞](同步、异步、阻塞.md) | ||
- [为什么优先成员初始化器](为什么优先成员初始化器.md) | ||
- [重载operator=要不要检查自赋值?](重载operator=要不要检查自赋值?.md) | ||
- [C&C++伪规则和错误的看法](C&C++伪规则和错误的看法.md) | ||
- [catch(auto)的问题](catch(auto)的问题.md) | ||
- [detach的问题](detach的问题.md) |
76 changes: 38 additions & 38 deletions
76
src/基础性C++题目/20231002 基础C++题目.md → src/基础性C++题目/20231002基础C++题目.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,38 @@ | ||
# 20231002 基础 C++题目 | ||
|
||
## 题目 | ||
|
||
下面展示的代码 | ||
|
||
```C++ | ||
#include <iostream> | ||
|
||
struct foo{ | ||
char a[16]; | ||
}; | ||
|
||
int main(){ | ||
foo a {"Hello, World!"}; | ||
auto b = a; | ||
a.a[0] = '\0'; | ||
std::cout << b.a; | ||
} | ||
``` | ||
|
||
其行为是: | ||
|
||
- A. 无法编译/未定义行为 | ||
- B. 可编译,保证无输出 | ||
- C. 可编译,保证输出`"Hello, World!"` | ||
- D. 可编译,输出为实现定义 | ||
|
||
## 答案 | ||
|
||
C | ||
|
||
## 解析 | ||
|
||
虽然数组类型不能直接赋值,但是作为类类型成员的数组类型,默认复制赋值函数的行为是逐元素复制。 | ||
|
||
- 此赋值行为在 C 语言也是成立的。 | ||
- 切忌将 foo::a 理解成指针。 | ||
# 20231002 基础 C++题目 | ||
|
||
## 题目 | ||
|
||
下面展示的代码 | ||
|
||
```C++ | ||
#include <iostream> | ||
|
||
struct foo{ | ||
char a[16]; | ||
}; | ||
|
||
int main(){ | ||
foo a {"Hello, World!"}; | ||
auto b = a; | ||
a.a[0] = '\0'; | ||
std::cout << b.a; | ||
} | ||
``` | ||
|
||
其行为是: | ||
|
||
- A. 无法编译/未定义行为 | ||
- B. 可编译,保证无输出 | ||
- C. 可编译,保证输出`"Hello, World!"` | ||
- D. 可编译,输出为实现定义 | ||
|
||
## 答案 | ||
|
||
C | ||
|
||
## 解析 | ||
|
||
虽然数组类型不能直接赋值,但是作为类类型成员的数组类型,默认复制赋值函数的行为是逐元素复制。 | ||
|
||
- 此赋值行为在 C 语言也是成立的。 | ||
- 切忌将 foo::a 理解成指针。 |
138 changes: 69 additions & 69 deletions
138
src/基础性C++题目/20231017 基础C++题目(转换的使用).md → src/基础性C++题目/20231017基础C++题目(转换的使用).md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,69 +1,69 @@ | ||
# 20231017 基础 C++题目 | ||
|
||
## 题目 | ||
|
||
### 1. 下面展示的代码应当使用 | ||
|
||
```C++ | ||
struct Base { int x; }; | ||
struct Derived : Base { int y; } | ||
|
||
int get_xy(Base * param){ | ||
auto pd = ????_cast<Derived*>(param); | ||
return pd->x * pd->y; | ||
} | ||
``` | ||
- A. static_cast | ||
- B. dynamic_cast | ||
- C. 以上全部 | ||
- D. 不允许转换 | ||
### 2. 下面展示的代码应当使用 | ||
```C++ | ||
void erased_call(void (* pfn)(void), const char * param){ | ||
auto typed_pfn = ????_cast<void(*)(const char *)>(pfn); | ||
typed_pfn(param); | ||
} | ||
``` | ||
|
||
- A. static_cast | ||
- B. reinterpret_cast | ||
- C. 以上全部 | ||
- D. 不允许转换 | ||
|
||
### 3. 下面展示的代码应当使用 | ||
|
||
```C++ | ||
template<typename T> | ||
void foo(T&& i){ | ||
// some implemetion code | ||
} | ||
|
||
void speciallized_foo(int param){ | ||
auto spfoo = ????_cast<void(*)(const double&)>(foo); | ||
spfoo(param); | ||
} | ||
``` | ||
- A. static_cast | ||
- B. reinterpret_cast | ||
- C. 以上全部 | ||
- D. 不允许转换 | ||
## 答案 | ||
1. A | ||
2. B | ||
3. A | ||
## 解析 | ||
1. 此处 `Base` 并非多态类型,因此 `dynamic_cast` 无法进行基类指针到派生类指针的转换,而 `static_cast` 可以,[如](https://godbolt.org/z/8nGEvPTE8)。 | ||
+ 你可以为 `Base` 添加虚函数成员,使其成为多态类型,此时`dynamic_cast` 可以用于基类到派生类的转换。 | ||
+ 注意 `static_cast` 并不像 `dynamic_cast` 那样具有 [RTTI](https://zh.wikipedia.org/zh-hans/%E5%9F%B7%E8%A1%8C%E6%9C%9F%E5%9E%8B%E6%85%8B%E8%A8%8A%E6%81%AF) ,无法转换时不会返回 `nullptr` 或抛出异常。通过不合法的转换得到的指针去访问成员会产生[未定义行为](https://zh.cppreference.com/w/cpp/language/ub)。 | ||
2. `reinterpret_cast`可以用于函数指针的转换,而 `static_cast` 不可以。 | ||
+ 此处 `reinterpret_cast` 并不会产生实际转换代码。 | ||
+ 普通指针 `void *` 和函数指针 `void (*)(void)` 在一些平台上的长度不同,C++ 标准并不保证这两种类型能够以 `reinterpret_cast` 互相转换。 | ||
3. 进行 `static_cast` 转换的时候会发生重载决议,模板函数会实例化为选择到的函数类型,再隐式转换为函数指针。 | ||
# 20231017 基础 C++题目 | ||
|
||
## 题目 | ||
|
||
### 1. 下面展示的代码应当使用 | ||
|
||
```C++ | ||
struct Base { int x; }; | ||
struct Derived : Base { int y; } | ||
|
||
int get_xy(Base * param){ | ||
auto pd = ????_cast<Derived*>(param); | ||
return pd->x * pd->y; | ||
} | ||
``` | ||
- A. static_cast | ||
- B. dynamic_cast | ||
- C. 以上全部 | ||
- D. 不允许转换 | ||
### 2. 下面展示的代码应当使用 | ||
```C++ | ||
void erased_call(void (* pfn)(void), const char * param){ | ||
auto typed_pfn = ????_cast<void(*)(const char *)>(pfn); | ||
typed_pfn(param); | ||
} | ||
``` | ||
|
||
- A. static_cast | ||
- B. reinterpret_cast | ||
- C. 以上全部 | ||
- D. 不允许转换 | ||
|
||
### 3. 下面展示的代码应当使用 | ||
|
||
```C++ | ||
template<typename T> | ||
void foo(T&& i){ | ||
// some implemetion code | ||
} | ||
|
||
void speciallized_foo(int param){ | ||
auto spfoo = ????_cast<void(*)(const double&)>(foo); | ||
spfoo(param); | ||
} | ||
``` | ||
- A. static_cast | ||
- B. reinterpret_cast | ||
- C. 以上全部 | ||
- D. 不允许转换 | ||
## 答案 | ||
1. A | ||
2. B | ||
3. A | ||
## 解析 | ||
1. 此处 `Base` 并非多态类型,因此 `dynamic_cast` 无法进行基类指针到派生类指针的转换,而 `static_cast` 可以,[如](https://godbolt.org/z/8nGEvPTE8)。 | ||
+ 你可以为 `Base` 添加虚函数成员,使其成为多态类型,此时`dynamic_cast` 可以用于基类到派生类的转换。 | ||
+ 注意 `static_cast` 并不像 `dynamic_cast` 那样具有 [RTTI](https://zh.wikipedia.org/zh-hans/%E5%9F%B7%E8%A1%8C%E6%9C%9F%E5%9E%8B%E6%85%8B%E8%A8%8A%E6%81%AF) ,无法转换时不会返回 `nullptr` 或抛出异常。通过不合法的转换得到的指针去访问成员会产生[未定义行为](https://zh.cppreference.com/w/cpp/language/ub)。 | ||
2. `reinterpret_cast`可以用于函数指针的转换,而 `static_cast` 不可以。 | ||
+ 此处 `reinterpret_cast` 并不会产生实际转换代码。 | ||
+ 普通指针 `void *` 和函数指针 `void (*)(void)` 在一些平台上的长度不同,C++ 标准并不保证这两种类型能够以 `reinterpret_cast` 互相转换。 | ||
3. 进行 `static_cast` 转换的时候会发生重载决议,模板函数会实例化为选择到的函数类型,再隐式转换为函数指针。 |
Oops, something went wrong.