"Accelerated C++" Ch. 0, 1, 2, 3, 4

Tags:

Gee, it is a lot of work to transfer my book notes from paper page to digital internet, but it does help me to understand and recall everything better. I won’t be summarizing everything as I had with the Python book(before I returned it to the MSU library at the end of spring, anyway), and everything is much more chaotic. Terms and ideas are listed in a long list below; some are defined/otherwise elucidated, and others are not.

Chapter 0 / Getting started

Abstraction
As discussed in the blog post introducing my C++ book, this book first teachers readers how to use libraries rather than write their own libraries. I love this approach, and later chapters will also instruct on writing my own abstractions/libraries. A couple of cool quotes from the book:

The ability to ignore details is characteristic of maturing technologies.”
“Much of the C++ language—especially the harder parts—exists mostly for the benefit of library authors. Library users don’t need to know those parts of the language at all.”

Standard Library
…is a standard set of library files included with the C++ implementation?
Braces & Scope
Braces, { or }, indicate scope and are used for functions and various statements. Objects defined inside braces are limited in scope to the function or statement defined with the braces… At the terminating brace, the object is destroyed and lost forever. Obviously, it is possible to define objects that are global in scope…
std::ostream
This is the data type for the output stream, frequently called with the std::cout operand.
Manipulators
Manipulators are an operand that alters or modifies an adjacent operand/object … just some jargon I picked up.
Scope operator ::
To be safe, functions or types defined within the scope of a library have two parts to their nomenclature — the library name, followed by the :: scope operator, and the function or type name… For example: std::vector.
String
A string is a data type for any contiguous string of characters, excepting whitespace characters. Defined in <string>
String literal
A string literal is any contiguous string of characters enclosed in double-quotation marks.

Chapter 1 / Working with strings

Variable / object
Simply, and portion of memory with a specified type.
“Interface” for an type
Jargon for the collection of operations that are possible on a given type — arithmetic operators, library functions, methods, etc.
On istream whitespace:
Whitespace is discarded from any istream input.
On displaying ostream buffer:
There are 3 times that an ostream buffer is flushed: 1) when it is full, 2) when input is called, 3) std::endl is called.
Overoaded operators
Overloading is jargon for when the same literal operator or function performs multiple tasks… An example of an overloaded operator is the + symbol, which can be used for addition arithmetic or for concatenating strings together.
const
const is used when initiating a variable/object and declares that a variable cannot be modified… It will remain constant. Example: const int xyz = 5; // this will always equal 5
Character literal
A character literal is a single character enclosed by single-quotes. It differs from a string, which is multiple characters enclosed by double-quotes.

Chapter 2 / Looping and counting

while() statement
A while statement continues to run as long as the given condition remains true. Syntax: while ( condition ) { ... } It works as in any other language…
Loop invariant
Jargon for a property that must be true for each iteration of a loop… For example, if you are looping through rows of output: while ( rows < 10 ) { ... rows += 1; } …then the loop invariant would be the property: I have looped through rows rows of data so far… Pretty straightforward, but determining it and commenting it out makes program that much easier to understand and write. The final task of any loop must be to modify objects to make the loop invariant true for the subsequent iteration.
std::string::size_type
This is a data type from the standard library that is guaranteed to hold the size of a string variable. An integer or other data type may not be sufficient to hold a very large number for the size a very large string of data, but the size_type data type dynamically changes to allocate enough memory for the job. Less work for the library user, me.
On operators’ precedence:
Arithmetic operators have higher precedence in the order of operations than relational operators; math trumps equality, basically!
using x::y
It is possible to abbreviate names comprising a scope operator with the using x::y declaration. For the rest of the scope that the declaration is made within, you can call the name by just calling y.
On asymmetric ranges:
Looping for asymmetric ranges, i.e. [x, y), is more useful than symmetric ranges … because 1) the range is defined easily by y-x, 2) it necessarily means you are counting from 0, which makes loop invariants easier to express and therefore your program easier to understand and write, and 3) can use the != inequality operator instead of greater-than or less-than operators to terminate the loop, which consequently tells us the explicit value of the sentry variable at the end of a loop(infinite quantity of values may be greater or less than, but only one explicit value is not equal to…)

Chapter 3 / Working with batches of data

setprecision(x)
setprecision(x) is an ostream manipulator that sets the amount of significant digits to display for a floating-point number in an ostream output stream.
On Memory and Floating-Point Types:
Author instructs to always use double. It isn’t as crucial to conserve RAM as it once was; at least, the difference today between float and double is negligible. And according to the author, on some implementations double is even faster? A double typically saves fifteen significant digits to the float’s six.
Whitespace
You can break up string literals across lines, as long as each line is enclosed in double-quotes. Helps with readability.
istream Type as a Condition
It is possible to use an istream as a condition in a while() statement. Example: while(cin >> x) { ... } This is because the istream class provides a conversion for the type to true or false… Any class type or method that likewise provides a true or false conversion may be used as the condition in a statement.
vector Type
A vector is a container that can store a list of values of any single type, and dynamically grows to accomodate the memory demand(very useful abstraction).

A vector holds a sequence of values of a given type, grows as needed to accomodate additional values, and lets us get at each individual value efficiently.”
“All the values in an individual vector are the same type, but different vectors can hold objects of different types.”
For chapter exercise, on utility of this vector abstraction: “…even though our homework vector will grow as needed to accomodate grades for as many homework assignments as our students can tolerate, our program doesn’t need to worry about obtaining the memory to store all those grades. The standard library does all that work for us.”

vector<double>::size_type Type
This data type is useful because it will always give us an appropriate data type to store the size of a vector of given type… Otherwise, different implementations may handle alternative types disasterously… I guess…?
typedef
typedef is used to create synonyms for a specific data type. Example: typedef vector<double>::size_type vec_sz; Following this declaration, I can use vec_sz to refer to the type of `vector::size_type. Much shorter and easier to type. Limited by scope.
Remainder operator
The remainder operator, %, returns the remainder of a division operation. For example, randomInteger % 2 will return zero if the integer is divisible by 2 — aka an even number.
Conditional operator
The conditional operator is basically shorthand for a much longer if-else statement. Example: int myAge = ( myName == "Patrick" ) ? 20 : 65; If myName is Patrick, then myAge will be declared to be 20, else if myName is not Patrick, it will be declared to be 65…
vectorName.begin()
Returns the first item in a vector container.
vectorName.end()
Returns the last value in a vector container.
vectorName.push_back(newData)
Appends newData to the end of a vector container.
vectorName[i]
Returns value indexed at i location in vector container.
vectorName.size()
Returns total number of elements in a vector container.
sort(begin, end, [comparison] )
For numbers, only the first two parameters are necessary. This function is defined in <algorithm> and rearranges a container ascendingly(lowest to highest). If you supply a comparison which returns one of two values supplied from a container, you can pass types other than integer. You can write your own comparison function which takes the two values and returns the “greater” value to sort ascendingly.
max(a, b)
Returns the larger value. Values must be of identical type.
ostreamName.precision(x)
Sets ostream’s precision for significant digits to x, AND returns former value.

Chapter 4 / Organizing programs and data

Functions
Chapter 4 introduces writing functions to encapsulate specific tasks… Ever true to the goal of abstraction, the author writes:

If we name a computation [when declaring a function], we can think about it more abstractly—we can think more about what it does and less about how it works. If we can identify important parts of our problems, and create named pieces of our programs that correspond to those parts, then our programs will be easier to understand and the problems easier to solve.”

Much of the chapter is then spent paring computations from the main source file, and re-writing them as stand-alone functions that take in parameters and return a value(the result of the task of the function).

References
To declare a reference, you place an ampersand & after the data type name, and before the name of the object. A reference object becomes a synonymous name for the object you reference, and any operations on the reference object will modify the original object. It is possible to declare constant references; for example: const double& midtermGrade As a constant, you will have a new name to identify the referenced object with, and when used as a parameter for a function, a new space in memory is never allocated to duplicate the object passed as a parameter because it is only referencing the already-existing spot in memory… Long-winded explanation. Lots of cool things can be done with references(and later, pointers as well, I imagine)—but can’t discuss it all in one post, let alone one definition in this quasi-glossary I’ve written!
Overloading functions
As with operators, it is possible to overload functions that you create… You can create multiple functions name grade() that only differ in the parameters they take. In fact, the C++ implementation will know which grade() function to call depending on the parameters you pass. This is very useful—especially if you can arrive at the same result from computations on different parameters, but don’t want the programmer overhead and naming separate functions for the different computations; you can name your functions based on the result they give and not the ingredients they take(in this chapter’s exercise, grade() returns a computed grade).
x.clear()
clear() is an overloaded function from the standard library. For vectors, it clears or discards the entire list—all values stored are erased. For an input stream istream type, it resets the error state and any exceptions thrown.
More on references
Whenever possible, it is good programming practice to declare a function parameter as a const reference, so that no new memory is spent to pass the value. Obviously, this is only useful if you only need to read the parameter and not operate on it.
try { ... } catch ( exception ) { ... return 1; }
A try/catch statement will try to run all of the computations within the first set of braces adjacent to try, and if these fail it will stop and skip to run the second set of braces following catch. Useful for handling exceptions.
Order of functions
Functions must already be declared when they are used in int main() or any source file, so there must be some thought to declaring functions ahead of time — typically in a header file.
struct structName { ... }
Structures are cool objects that comprise of zero or many individual member variables. Any declared structure must have values given for ALL of the member values that exist in the structure type. When passed as a reference, it is possible to read or modify any of the member variables.
exceptionName.what()
what() is a method function that returns any of the string argument passed when an exception is thrown. This is a string the programmer usually writes when handling errors in his code, so should tell you precisely where the problem is occuring.
using library::function declarations in a header?
The author cautions against using using declarations in a header file because they may clash with existing declared functions in the source. So no.
Guarding a header file
Header files should be guarded from being compiled twice… This is accomplished using #ifndef, #define, and #endif.
Relationship between headers and source files?
Functions must be declared at the header of any source file that uses the functions, but they can only be defined once in one source file. When the implementation compiles source and header files, it will retain a copy of the defined function, but it must be declared once in each source file that uses the function.

A function must be declared in every source file that uses it [e.g. by means of a header file], and defined only once [e.g. once in the relevant source file].” (72)

Computing student grades

[blah blah exercise here’s the quote:]

Imagine a course in which each student’s final exam counts for 40% of the final grade, the midterm exam counts for 20%, and the average homework grade makes up the remaining 40%. Here is our first try at a program that helps students compute their final grades…”(35)