[IC210] Resources/C++ Programming Guide and Tips
所有提交的评分作业(作业、项目、实验、考试)都必须使用本风格指南。本指南的目的不是限制你的编程,而是为你的程序建立统一的风格格式。
* 这将有助于你调试和维护程序。
* 有助于他人(包括指导教师)理解您的程序。
This style guide is mandatory for all submitted work for grading (homework, projects, labs, exams). The purpose of the guide is not to restrict your programming but rather to establish a consistent style format for your programs.
* This will help you debug and maintain your programs.
* It will help others (including your instructor) to understand them.
Whitespace and Visual Layout
"空白 "指换行符、空格字符和制表符。在源代码中,我们一般不使用制表符。事实上,emacs 会用适当数量的空格字符替换制表符。
"Whitespace" refers to newlines, space characters and tabs. In source code we do not generally use tabs. In fact, emacs replaces tab characters with an appropriate number of space characters.
在很多情况下,为了让编译器正确编译源代码,我们并不需要空格,尽管编译出来的结果我们无法阅读。我们主要通过三种方式使用空格来格式化代码,以达到最清晰的效果:
In many circumstances whitespace is not required in order for compilers to correctly compile source code, even though the result is unreadable to us. There are three major ways we use whitespace to format code for maximum clarity:
* 缩进: 每一级块嵌套必须缩进一致的空格数(通常为两空格)。
* 空行: 在源代码中,使用空行来分隔完成不同任务的代码块。虽然在某种程度上这是一种品味和艺术,但你应该期望用空行来分隔不同的函数,而一个长的函数体通常也应该用空行来分割成若干块。
* 用空格分隔代码元素: 我们建议在运算符和操作数之间使用空格,除非通过省略空格来突出优先级。
* Indentation: Each level of block nesting must be indented by a consistent number of spaces (usually two spaces).
* Blank Lines: In source code, use blank lines to separate chunks of code that accomplish distinct tasks. While to some extent this is taste and art, you should expect distinct functions to be separated by blank lines, and a long function body should usually be broken into chunks by blank lines as well.
* Whitespace separating elements of code: We recommend using whitespace between operators and operands, except where precedence is highlighted by leaving out spaces.
Comments
注释的缩进应与其描述的代码块一致。注释可分为战略和战术两大类。
-
应在代码开头给出文件名和作者。
-
策略性注释用于向读者概述正在发生的事情。这些注释出现在文件开头、重要函数之前和重要代码块之上。策略性注释通常以句子的形式编写,重点是解释代码块设计的全貌。
-
战术性注释旨在解释代码中棘手的地方、参数的作用以及有关程序控制流程的提示。这些注释应在需要时混合在代码中。这些注释应比策略性注释短,采用项目符号格式,并可采用内联格式。例如,应在给变量分配固定的、非显而易见的值的语句旁边加上战术性注释。
下面的示例展示了良好的注释。注意战术性注释,说明为什么使用 "9.0 "而不是 "9"。
Comments should be indented consistently with the block of code they describe. Comments can be divided into two general categories, strategic and tactical.
* Filename and Author should be given in the beginning of your code.
* Strategic comments are used to give the reader a general overview of what is going on. These comments appear at the beginning of files, before important functions, and above important blocks of code. Strategic comments tend to be written in sentences with an emphasis on explaining the big picture of what the block of code is designed to do.
* Tactical comments are designed to explain tricky areas of code, what parameters do, and hints about the control flow of the program. These comments should be intermixed in the code when needed. They should be shorter than strategic comments, in bullet format, and may be in inline format. One should, for instance, place a tactical comment next to the statement that assigns a fixed, non-obvious value to a variable.
The following example shows good commenting. Note the tactical comment about why "9.0" is used instead of "9".
Naming
* 变量应有有意义的名称。
例如,在一个程序中使用一个变量来跟踪足球比赛中的每次带球码数。为了程序的可读性,这样的变量应该叫做 yardsPerCarry,而不是仅仅 x。这必须与使用过长的名称相平衡。(15 个字符左右已接近 "过长 "限制)。
* Variables should have meaningful names.
For example, consider a program that uses a variable to track the yards per carry of a football game. Such a variable should be called yardsPerCarry rather than just x for program readability. This must be balanced against using names which are too long. (Fifteen or so characters approaches the "too long" limit.)
Curly Braces, i.e. { }'s
在 C++ 中,大括号(即 { })用于从一个或多个语句中创建一个 "块"。它用于划分函数体、循环和switch语句、结构体定义以及 if 语句中的 then 和 else 块。
-
一般情况下,要么始终将开头的大括号放在新的一行(本课程的首选),要么始终将其放在上一行的最后。一致性再次成为关键。
-
如果将开头的大括号放在新行,本课程的首选是保留上一行的缩进,即不缩进大括号。一般来说,除了极少数情况下将整个代码块放在一行外,任何一种大括号都会占用自己的行。例外情况是,注释可以跟在开大括号或闭大括号后面。
-
新建代码块内的代码块应缩进。
Curly Braces, i.e. { }'s in C++ are used to create a "block" from one or more statements. The delineate the bodies of functions, loops and switch statements, struct definitions, and the then and else blocks of if statments.
* Generally, one should either always put the opening curly brace on a new line (preferred for this course) or always but it last on the previous line. Once again consistency is key.
* If the opening brace goes on a new line, the preference for this course is to keep the previous line's indentation — i.e. do not indent the curly brace. Generally, curly braces of either kind will occupy their own line, except for rare occasions when an entire block is put on one line. The exception is that comments may follow either opening or closing braces.
* The chunk of code inside the newly created block should be indented.
Other Tips on Naming
-
不应使用单字母变量或常量。
但在通常情况下,用单个字母来标识某些变量或常量是例外情况。坐标系(x、y 和 z)就是一个例子。第二个例外情况出现在循环计数器变量的使用上,通常的做法是在 for 循环中使用 i 和 j 这样的变量作为计数器。
-
函数名和变量名应以小写字母开头。
由多个名称组成的标识符应将每个名称的第一个字母(在第一个字母之后)改为大写(如 yardsPerCarry)或使用下划线(yards_per_carry)。强烈建议使用前一种方法。
-
常量的命名应全部使用大写字母。
例如
const int PI = 3.14;
一般来说,除非是正常单词的一部分,否则最好避免在名称中使用小写字母 "L "或字母 "O"。例如,"cell" 是 c- e - 1- ONE 还是 c- e- 1-1?
-
避免使用大小写不同、外观相似或仅有细微差别的名称。
例如,如果在同一个程序中使用 InputData、InData 和 DataInput,肯定会引起混淆。
-
函数名称应反映函数的作用(printArray)或返回值(getAge)。
-
布尔变量名应该听起来像 "是/否"类的意思,例如 "isEmpty "和 "isFinished"。
* Single letter variables or constants should not be used.
An exception to this rule is when it is common practice to identify something with a single letter. An example of this is the coordinate system (x, y, and z). A second exception occurs in the use of loop counter variables where it is common practice to use variables like i and j as counters in for loops.
* Function names and variable names should begin with a lower case letter.
An identifier consisting of multiple names SHALL have each name distinguished by making the first letter of each name part (after the first) upper case (e.g. yardsPerCarry) or by using underscores (yards_per_carry). The former method is strongly encouraged.
* Constants should be named in all upper case letters.
Example:
const int PI = 3.14;
It's generally good to avoid lower case letter 'L', or the letter 'O' in names unless they are part of normal words. This is to avoid confusion with the numbers 1 and 0. For example, is "cell" c- e - 1- ONE or c- e- 1-1?
* Avoid names that differ only in case, look similar, or differ only slightly.
For example, InputData, InData and DataInput will certainly be confusing if used in the same program.
* Names of functions should reflect what they do (printArray), or what they return (getAge).
* Boolean variable names should sound like Yes/No things — "isEmpty" and "isFinished" are possible examples.
Miscellaneous but Important Stuff
-
任何一行代码都不得超出右边距。如果一行代码过长,应将其分割成若干段。请记住,编译器在很大程度上会忽略程序中多余的空白(但在处理字符串时要小心)。
-
始终使用最合适的运算符或结构来完成你希望它完成的工作。良好的设计和清晰度比优化更重要。不要声明或使用超过需要的变量。
-
数字常量("神奇数字")不得直接编码。唯一允许的例外是 0、1 或 -1,以及那些不可能发生变化的常数;例如,确定一个数字是否为偶数的代码可以使用数字 2,因为它不可能发生变化。如果从名称中看不出数值,数字常量必须有注释来解释其值。
* No line of code should wrap beyond the right margin. If a line of code becomes too long, break it up into pieces. Remember the compiler largely ignores extra whitespace in your programs (but be careful with strings).
* Always use the most appropriate operator or construct for the work you want it to do. Good design and clarity take precedence over optimization. Do not declare or use more variables than are necessary.
* Numerical constants ("magic numbers") must not be coded directly. The only allowable exceptions are for 0, 1 or -1, and those which are not likely to change; for example code determining if a number is even can use the number 2 since it is not likely to change. Numerical constants must have a comment explaining the value if it is not evident from the name.
Practical tips for tackling programming problems
以下是一些实用技巧,可以提高你的编程技巧。
-
程序员越独立越好。当然,在编写程序时,你需要查看讲义、示例程序和其他资料。不过,要在编写代码之前进行,但尽可能避免在编写代码时看这些资料。特别是,如果你真的是编程新手,至少在前三周,尽量从头开始写代码,不要做任何复制粘贴的工作。我知道这是不可能做到的,但酌情尝试。
这种方法有一些好处:
-
你会更清楚自己遗漏了哪些概念(或不太重要的细节)。这样,你就能更容易地发现自己的误解并加以纠正。
-
你会更快地写出代码。在你的大脑中访问某些东西要比在任何其他存储器中访问快得多。记忆层次很重要。
-
你的大脑似乎会进行创造性的综合。如果在大脑中存储更多内容,你可能会获得更多关于编程的基本观点。然而,大脑之外的东西对你来说始终是不变的。
-
-
细节决定成败。不要忘记,作为程序员,你要对程序中的每个字符负责。乍一看,事情可能很简单,但通常要花费比预期更多的时间和精力才能完成。
再举个例子,在线帮助手册有时会解释技术细节。在这种情况下,阅读一个段落可能需要 5 分钟或更长时间才能在大脑中理清所有细节。不要跳过细节。细节决定成败。
-
退一步,再思考。当你完成一项任务时,花一点时间退后一步。检查你是否同时掌握了大的逻辑和实现逻辑的小细节。看看是否有一些不一致的地方,如果有,就加以修正。
-
一辆无法行驶的汽车有多大价值?没用,我不会买这辆车。同样,无论你的源代码有多少行,如果它不能运行,它就是无用的,我也不会买你的程序。试着做一个好的、能用的产品。如果你的代码不能工作,你就缺少了一些东西;是什么呢?
Here are a few practical tips that will improve your programming skills.
* The more independent a programmer is, the better. Of course, you need to look at lecture notes, sample programs, and other materials to write your program. However, do this before writing the code, but try to avoid looking at them if possible while writing your code. In particular, if you are really new to programming, try to write your code from scratch without doing any copy-and-paste, at least for the first three weeks. I know it's impossible to do so; try with your discretion.
There are some benefits to this approach:
* You will become more conscious which concepts (or less important details) you miss. This way, you can identify your misunderstandings and fix them with more ease.
* You will write a code faster. Access to something in your brain is much faster than in any other storage. Memory hierarchy matters.
* Your brain seems to do creative synthesis. You may gain more fundamental perspectives on programming if you put more in your brain. However, things outside your brain always stay the same to you.
* The devil is in the details. Don't forget that is it you as a programmer who are responsible for all the bits and pieces of your program. Things may seem simple at a first look, but usually they will take more time and effort to complete than expected.
As one more example, the online notes sometimes explain technical details. In this case, reading one paragraph may take even 5 minutes or more to work out all the details in your brain. Don't skip through the details. The devil is in the details.
* Step back, and think again. When you finish a task, take a brief moment and step back. Check if you get both the big picture logic and the small details to implement the logic. See if there are some inconsistencies and fix them if any.
* How valuable is a car that doesn't run? It's useless, and I won't buy the car. Likewise, however many lines your source code may have, if it doesn't work, it's useless, and I won't buy your program. Try to make a good, working product. If your code doesn't work, you are missing something; what is it?
参考:
https://www.usna.edu/Users/cs/choi/ic210/resources/style.html