-
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.
Remove PDFs. move basic to src folder
- Loading branch information
Showing
10 changed files
with
406 additions
and
406 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
76 changes: 38 additions & 38 deletions
76
基础性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
基础性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.