1. 代码⻛格:
C语⾔的编程规范和编程⻛格对于代码的可读性、可维护性和协作性都⾮常重要。
C++ ⻛格指南 - 内容⽬录 — Google 开源项⽬⻛格指南
Contents
https://zh-google-styleguide.readthedocs.io/en/latest/google-cpp-styleguide/contents/
😉 C++ ⻛格指南 - 内容⽬录: https://zh-googlestyleguide.readthedocs.io/en/latest/google-cpp-styleguide/contents/
要求:请浏览上⽅链接的内容,本门课程已学知识涉及到了哪些内容?请挑出其中3
个,并摘抄下来。重点浏览 「8. 注释」「9.8. 条件语句」「9.9. 循环和开关选择语
句」。
思考:作为⼀名初学者,请描述⼀下什么是代码缩进,你平时是否有严格要求⾃⼰进
⾏代码缩进呢?
4.1. 输入和输出
总述
我们倾向于按值返回, 否则按引用返回。 避免返回指针, 除非它可以为空.
说明
C++ 函数由返回值提供天然的输出, 有时也通过输出参数(或输入/输出参数)提供. 我们倾向于使用返回值而不是输出参数: 它们提高了可读性, 并且通常提供相同或更好的性能.
C/C++ 中的函数参数或者是函数的输入, 或者是函数的输出, 或兼而有之. 非可选输入参数通常是值参或 const 引用, 非可选输出参数或输入/输出参数通常应该是引用 (不能为空). 对于可选的参数, 通常使用 std::optional 来表示可选的按值输入, 使用 const 指针来表示可选的其他输入. 使用非常量指针来表示可选输出和可选输入/输出参数.
避免定义需要 const 引用参数去超出生命周期的函数, 因为 const 引用参数与临时变量绑定. 相反, 要找到某种方法来消除生命周期要求 (例如, 通过复制参数), 或者通过 const 指针传递它并记录生命周期和非空要求.
在排序函数参数时, 将所有输入参数放在所有输出参数之前. 特别要注意, 在加入新参数时不要因为它们是新参数就置于参数列表最后, 而是仍然要按照前述的规则, 即将新的输入参数也置于输出参数之前.
这并非一个硬性规定. 输入/输出参数 (通常是类或结构体) 让这个问题变得复杂. 并且, 有时候为了其他函数保持一致, 你可能不得不有所变通.
6.14. 整型
Tip
C++ 内建整型中, 仅使用 int. 如果程序中需要不同大小的变量, 可以使用 <stdint.h> 中长度精确的整型, 如 int16_t.如果您的变量可能不小于 2^31 (2GiB), 就用 64 位变量比如 int64_t. 此外要留意,哪怕您的值并不会超出 int 所能够表示的范围,在计算过程中也可能会溢出。所以拿不准时,干脆用更大的类型。
定义:
C++ 没有指定整型的大小. 通常人们假定 short 是 16 位, int 是 32 位, long 是 32 位, long long 是 64 位.
优点:
保持声明统一.
缺点:
C++ 中整型大小因编译器和体系结构的不同而不同.
结论:
<stdint.h> 定义了 int16_t, uint32_t, int64_t 等整型, 在需要确保整型大小时可以使用它们代替 short, unsigned long long 等. 在 C 整型中, 只使用 int. 在合适的情况下, 推荐使用标准类型如 size_t 和 ptrdiff_t.
如果已知整数不会太大, 我们常常会使用 int, 如循环计数. 在类似的情况下使用原生类型 int. 你可以认为 int 至少为 32 位, 但不要认为它会多于 32 位. 如果需要 64 位整型, 用 int64_t 或 uint64_t.
对于大整数, 使用 int64_t.
不要使用 uint32_t 等无符号整型, 除非你是在表示一个位组而不是一个数值, 或是你需要定义二进制补码溢出. 尤其是不要为了指出数值永不会为负, 而使用无符号类型. 相反, 你应该使用断言来保护数据.
如果您的代码涉及容器返回的大小(size),确保其类型足以应付容器各种可能的用法。拿不准时,类型越大越好。
小心整型类型转换和整型提升(acgtyrant 注:integer promotions, 比如 int 与 unsigned int 运算时,前者被提升为 unsigned int 而有可能溢出),总有意想不到的后果。
关于无符号整数:
有些人, 包括一些教科书作者, 推荐使用无符号类型表示非负数. 这种做法试图达到自我文档化. 但是, 在 C 语言中, 这一优点被由其导致的 bug 所淹没. 看看下面的例子:
for (unsigned int i = foo.Length()-1; i >= 0; --i) …
上述循环永远不会退出! 有时 gcc 会发现该 bug 并报警, 但大部分情况下都不会. 类似的 bug 还会出现在比较有符合变量和无符号变量时. 主要是 C 的类型提升机制会致使无符号类型的行为出乎你的意料.
因此, 使用断言来指出变量为非负数, 而不是使用无符号型!
7.4. 变量命名
总述
变量 (包括函数参数) 和数据成员名一律小写, 单词之间用下划线连接. 类的成员变量以下划线结尾, 但结构体的就不用, 如: a_local_variable, a_struct_data_member, a_class_data_member_.
说明
普通变量命名
举例:
string table_name; // 好 - 用下划线.
string tablename; // 好 - 全小写.
string tableName; // 差 - 混合大小写
类数据成员
不管是静态的还是非静态的, 类数据成员都可以和普通变量一样, 但要接下划线.
class TableInfo {
…
private:
string table_name_; // 好 - 后加下划线.
string tablename_; // 好.
static Pool* pool_; // 好.
};
结构体变量
不管是静态的还是非静态的, 结构体数据成员都可以和普通变量一样, 不用像类那样接下划线:
struct UrlTableProperties {
string name;
int num_entries;
static Pool* pool;
};
结构体与类的使用讨论, 参考 结构体 vs. 类.
代码缩进
代码缩进是用空格使代码更加规范整洁,同时还能表示逻辑的从属关系。因此平时也会严格要求自己进行代码缩进。
2. 编程题:
分别⽤ for while do-while 实现:计算并输出:n! = 1 × 2 × 3 × ⋯× n
3. 编程题:
模仿PPT的课程内容,计算⾃然数 e = 1 + 1! +1/2! +1/3! + ⋯+1/ n!(直到最后⼀
项的绝对值⼩于 1e-7)的编程思路,计算圆周率 .
著名的莱布尼兹公式:
4. 编程题:
编写⼀个程序,使⽤ while 循环计算斐波那契数列的前20个数字,并将它们输出到
屏幕上。
什么是斐波那契数列?斐波那契数列是⼀个数学上的经典数列,起始于0和1,之后的
每⼀项都是前两项的和。它的前⼋项为:0,1,1,2,3,5,8,13,……
5. 附加题
编写⼀个程序,接受⽤户输⼊的整数,然后按照相反的顺序输出这些数字。例如,输
⼊为 12345,输出应为 54321。
😉 ⾮必做题。建议⼤家积极思考并尝试编程,做完且正确者有加分!