读书笔记。
Chapter 1
main函数的返回值非零时,该非零值indicates系统遇到了什么样子的错误。
每个variable都有它的type。
suffix就是后缀的意思。
compilers决定了suffix conventions (.cc, .cxx, .cpp, .cp, and .C)。
cc 是一个C compiler。
windows中executables以exe作为suffix;UNIX中则以out作为suffix。
windows中执行executables时,可以call the name 并省略.exe。
g++是一个GNU compiler。用例:g++ -o prog1 prog1.cc
“-o prog1”是用来命名executables的名字的。UNIX中就是规定了.out文件的名字,但是实际看到却又会省略.out这个suffix,而只有prog1。这个参数缺省时,自动命名为a.out。
c++没有定义IO (input or output)命令,而是依赖于standard library (标准库)实现IO功能。
iostream library有两个type: istream 和ostream。
stream 是向设备写入或者读出的sequence of characters。
iostream library规定了4个 IO objects。
- type istream: cin (standard input)
- type ostream: cout (standard output)
- type ostream: cerr (standard error)
- type osream: clog
上述四个object都是和一个窗口window关联的:从窗口读入,输出到窗口中去。
<< operator 需要两个operands: left-hand operand需要是一个ostream object;right-hand operand则是一个要输出的值。该operator会返回left-hand operand (一个ostream object),因而可以接连使用<< operator。
”“中出现的字符串叫做string literal。
endl叫做manipulator,是一个特殊值。endl可以结束当前line,并flushing相关IO设备的buffer:flushing the buffer保证当前所有的输出内容都确实输出到设备上了,而不是停留在内存中等待输出。
所以debug的时候,如果使用了print statements,一定要flush the stream,否则程序crash时,输出信息可能会停留在内存中,而没有输出到屏幕上 (这个问题我确实遇到过)。
::叫做scope operator。
“>>” operator返回left-hand operand。
”注释“这个概念对应的英文术语叫做comments。约定俗成,相比于文档,comments更加值得信赖。所以没有comments比错的comments要好。
windows上的end-of-file使用:按住Ctrl+z,然后再按Enter键;UNIX系统上则是按住control+d键。
A class defines a type along with a collection of operations that are related to that type.
firle redirection:将输入和输出以文件形式完成,而不是手动从命令行完成。比如
./excutable < infile > outfile。
Chapter 2
- C++ is a statically typed language: type checking is done at compile time.
- a ‘’char’’ is the same size as a single machine byte.
- bit —> byte (8 bits) —> word (4 or 8 bytes):
- The smallest chunk of addressable memory is referred to as a “byte.”
- The basic unit of storage is referred to as a “word.”
- each byte has an “address”.
- Typically, floats are represented in one word (32 bits), doubles in two words (64 bits), and long doubles in either three or four words (96 or 128 bits).
- C++内置的几种types分为integral types (也包括char,bool)和floating-point types (剩下的)。
- In an unsigned type, all the bits represent the value.
- an 8-bit unsigned char can hold the values from 0 through 255 inclusive.
- an 8-bit signed char is guaranteed to be able to hold values from –127 through 127.
- Tips for types:
- 该数不可能为负则用unsigned type。
- 要么用int,要么用long long。
- arithmetic expressions 中别用plain char or bool。这是因为不同的机器上plain char是否带符号不确定。
- 尽量用double。float不够,long double耗时且浪费。
- Type conversions happen automatically when we use an object of one type where an object of another type is expected.
- If we assign an out-of-range value to an object of unsigned type, the result is the remainder of the value modulo the number of values the target type can hold.
- assigning –1, which is 11111111 (-2^8+2^7+…+1=-1), to an 8-bit unsigned char (therefore, 11111111 is interpreted as 2^8+2^7+..+1= 511) gives that object the value 255 (511 % 256 = 255).
- If we assign an out-of-range value to an object of signed type, the result is undefined. The program might appear to work, it might crash, or it might produce garbage values.
- Regardless of whether one or both operands are unsigned, if we subtract a value from an unsigned, we must be sure that the result cannot be negative.
- Two string literals that appear adjacent to one another and that are separated only by spaces, tabs, or newlines are concatenated into a single literal.
- Backspace or control characters, have no visible image. Such characters are nonprintable.
- initialization and assignment are different operations in C++.
- A declaration makes a name known to the program.
- A definition creates the associated entity.
- To obtain a declaration that is not also a definition, we add the extern keyword and may not provide an explicit initializer: extern int i;
- Variables must be defined exactly once but can be declared many times.
- To use a variable in more than one file requires declarations that are separate from the variable’s definition. To use the same variable in multiple files, we must define that variable in one—and only one—file. Other files that use that variable must declare—but not define—that variable.
- Variable names normally are lowercase—index, not Index or INDEX.
- Like Sales_item, classes we define usually begin with an uppercase letter.
- Identifiers with multiple words should visually distinguish each word, for example, student_loan or studentLoan, not studentloan.
- A scope is a part of the program in which a name has a particular meaning. Most scopes in C++ are delimited by curly braces.
- Advice: Define Variables Where You First Use Them.
- Names declared in the outer scope can also be redefined in an inner scope.
- A reference defines an alternative name for an object. a reference must be initialized.
- Once initialized, a reference remains bound to its initial object. There is no way to rebind a reference to refer to a different object.
- a reference may be bound only to an object, not to a literal or to the result of a more general expression.
- Unlike a reference, a pointer is an object in its own right and need not be initialized at the time it is defined.
- We get the address of an object by usin the address-of operator (the & operator).
- Because references are not objects, they don’t have addresses. Hence, we may not define a pointer to a reference.
- When a pointer points to an object, we can use the dereference operator (the * operator) to access that object.
- Key Concept: Some Symbols Have Multiple Meanings.
- In declarations, & and * are used to form compound types. In expressions, these same symbols are used to denote an operator.
- It is illegal to assign an int variable to a pointer, even if the variable’s value happens to be 0.
- A null pointer does not point to any object. The type void* is a special pointer type that can hold the address of any object.
- It can be easier to understand complicated pointer or reference declarations if you read them from right to left.
- Because we can’t change the value of a const object after we create it, it must be initialized.
- To share a const object among multiple files, you must define the variable as extern.
- C++ programmers tend to abbreviate the phrase “reference to const” as “const reference.”
- A temporary object is an unnamed object created by the compiler when it needs a place to store a result from evaluating an expression.
- A Reference to const May Refer to an Object That Is Not const.
- A pointer to const may not be used to change the object to which the pointer points.
- It may be helpful to think of pointers and references to const as pointers or references “that think they point or refer to const.”
- A const pointer must be initialized, and once initialized, its value (i.e., the address that it holds) may not be changed.
- We use the term top-level const to indicate that the pointer itself is a const. When a pointer can point to a const object, we refer to that const as a low-level const.
- A constant expression is an expression whose value cannot change and that can be evaluated at compile time.
- Under the new standard, we can ask the compiler to verify that a variable is a constant expression by declaring the variable in a constexpr declaration. Variables declared as constexpr are implicitly const and must be initialized by constant expressions.
- constexpr imposes a top-level const on the objects it defines.
- Let the compiler figure out the type for us by using the auto type specifier.
- By implication, a variable that uses auto as its type specifier must have an initializer.
- In C++ we define our own data types by defining a class.
- Headers (usually) contain entities (such as class definitions and const and constexpr variables that can be defined only once in any given file.
- #ifdef is true if the variable has been defined, and #ifndef is true if the variable has not been defined. If the test is true, then everything following the #ifdef or #ifndef is processed up to the matching #endif.
- Preprocessor variable names do not respect C++ scoping rules.
Chapter 3
- Headers Should Not Include using Declarations.
- The reason is that the contents of a header are copied into the including program’s text. If a header has a using declaration, then every program that includes that header gets that same using declaration. As a result, a program that didn’t intend to use the specified library name might encounter unexpected name conflicts.
- The string input operator reads and discards any leading whitespace (e.g., spaces, newlines, tabs). It then reads characters until the next whitespace character is encountered.
- The newline that causes getline to return is discarded; the newline is not stored in the string.
- Although we don’t know the precise type of string::size_type, we do know that it is an unsigned type big enough to hold the size of any string.
- Adding two strings yields a new string that is the concatenation of the left-hand
followed by the right-hand operand. - When we mix strings and string or character literals, at least one operand to each + operator must be of string type.
- For historical reasons, and for compatibility with C, string literals are not
standard library strings. It is important to remember that these types differ
when you use string literals and library strings. - The subscript operator (the [ ] operator) takes a string::size_type value that denotes the position of the character we want to access.
- The values we use to subscript a string must be >= 0 and < size(). The result of using an index outside this range is undefined. By implication, subscripting an empty string is undefined. Any time we use a subscript, we must ensure that there is a value at the given location.
- A vector is a collection of objects, all of which have the same type. Every object in the
collection has an associated index, which gives access to that object.