Thursday, June 6, 2013

More Chapter 2: King

Chapter 2 is huge. Huuuuuge. I had six pages written halfway through section 4...

While working on these notes earlier this week, I was listening to Chopin's Nocturne Op. 9-72. Andrei was merrily doing some creative writing pertaining to our story at the time, and despite the tribulations from the afternoon prior, I felt truly peaceful and content. It was a beautiful, fleeting feeling.

Driving to work, today, too... It was raining because we have a tropical depression hanging over us, and it was dark because it was still early... But I just had this feeling like... "I am so light and happy..." Just in general. Things are just really good.

Anyway, notes are below the break--




Section 2.2: King
General Form of a Simple Program
C programs have the general form of...
     directives
     int main(void)
     {
     statements
     }
The braces show where main begins and ends.
C is very compact, as it is reliant on abbreviations and special symbols.
There are three key language features that C relies on: directives (commands that modify the program prior to compilation); functions (blocks of executable code, like main, that have names); and statements (commands to be performed when the program is run).

Directives
The commands intended for the preprocessor to execute before compilation. The only directive beginners need worry about is #include.
When #include <stdio.h> is seen at the start of a program, it tells the preprocessor to "include" the information contained within the input/output header in C's standard library.
C has a number of these headers, and each contains different information about part of the standard library. We have to include <stdio.h> because C does not have built in "read" and "write" commands. The ability to perform input and output is provided by the functions within the standard library.
Directives always begin with #; always are a single line in length; and never are followed by a semicolon or other special marker.

Functions
These are the building blocks of programs. There are two kinds -- functions written by the programmer and library functions (accessed by the directives).
In mathematics, a function is a rule for computing a value when given one or more arguments:
              f(x) = x + 1
              g(y, z) = y2 - z2
C is less specific -- a function is merely a group of statements grouped together and given a name. Some will compute values, but some do not.
When a function does compute a value, a return statement is used to display the value.
     return x + 1;
will add 1 to x before displaying or using the value.
     return y * y - z * z;
will compute a difference of squares of its arguments.

A C program may consist of many functions, but the main function is the only one that is required. It is case-sensitive, and cannot be substituted.

So if main is a function, does it return a value? Yes, in the form of a status code that is sent to the operating system when the program terminates.
#include <stdio.h>
int main (void)
{
     printf("To C or not to C; that is the question.\n");
     return 0;
}
The word "int" placed before main indicates that main will return an integer value. "void" in parentheses indicates that main has no arguments.
"return 0" has two purposes -- it causes main to terminate, thus ending the program... and it indicates that main returns a value of 0.
The program will still terminate without return at the end, but many compilers will produce a warning message (because the function was supposed to return a value, but failed to).

Statements
These are commands that are executed when the program runs. pun.c only uses 2 kinds of statements; return and a function call.
     --Whenever executing a command that asks for a function's actions, it is referred to as "calling".
     printf("To C or not to C...\n") <--- printf has been "called" to display a string on screen.
Statements typically end with a semicolon (99% of the time, unless it's a compound statement). Directives will never end with a semicolon (I repeated this, so its important. Lol).

Printing Strings
It's important to remember that printf will not automatically advance to the next line once it has finished displaying its string. It requires a newline character (\n) to instruct it to do so.
     If the program pun.c were to be rewritten from...
     printf("To C or not to C; that is the question.\n");
     ...to read instead...
     printf("To C or not to C;");
     printf(" that is the question.\n");
     ...the user would see absolutely no difference in output because there is no newline character in the second example.
     Another example: To display...
          Brevity is the soul of wit.
               --Shakespere
     ...the statement could be written...
     printf("Brevity is the soul of wit.\n     --Shakespeare\n");

Section 2.3
Comments
Every program should have some sort of documentation -- program name, date written, writer's name, etc... This can be done with comments.
     /* This is a comment */
Comments come in many styles, but the important thing to keep in mind... Once the program sees /*, it will omit everything until it reaches */. Forgetting to terminate a comment could cause accidental omissions of code, but can also be helpful in bug-testing.

C99 provides a style that terminates automatically at the end of a line.
     // It looks more like this
If a comment needs to be longer than one line...
     // ...more than one line...
     // ...can be used if...
     // ...preceded by the double-slash.

Section 2.4
Variables and Assignment
Variables are the storage areas for data that is calculated by the program before it produces output.

Type
Every variable must have a type -- the type will tell it what kind of data to store. C has many types, but beginners should only be concerned with int and float.
Choosing the right type is important because it determines what can be done to the variable, and how it is displayed.
int is short for integer. It can store any whole number... 0, 1, 315, -2155, etc. The largest typically goes into the billions digits.
float is short for floating-point, and can store MUCH larger numbers than int. The true difference between the two is float's ability to store numbers with digits following the decimal point. float values sometimes take longer to compute, as the value is often just an approximation. Instead of only being .1, it could actually be .09999999999987 due to a rounding error.

Declaration
Compilers need variables to be described before they can be used. To do this, known as declaring a variable, the type of variable must clearly precede the variable's name.
Example:
     int height;
     float profit;
The first declaration states that height is to be stored as an int; the second declares profit as a float. One line can be used for several variables, as below:
     int height, length, width, volume;
     float profit, loss;
Each declaration must end with a semicolon.
In older compilers, declarations must precede statements as well, before the statements can use the variables. As a matter of style, it is typical to leave a blank line between declarations and statements.

In C99, a shift was made to not require the listing of declarations before statements, and they can instead be declared once they are needed (I experienced this in DG Scripts).

Assignments
Variables can be given values in various ways; one of these ways is through assignment.
     height = 8;
     length = 12;
     width = 10;
The above statements assign these specific values to the variables height, length, and width. The values, themselves, are called constants.
Variables must be declared before they can be assigned a value.
     Example: int height;                         height = 8; /* Incorrect */
             height = 8;                         int height;

A constant assigned to a float variable usually contains a decimal point.
     profit = 2150.48;
     It is good practice to include an f at the end of a float that has a decimal point, though.
     profit = 2150.48f;

Mixing types in variables is possible (like assigning an int value to a float variable), but can be tricky and is not advised.

Once a variable has been assigned a value, it can be used to help compute another value.
     height = 8;
     length = 12;
     width = 10;
     volume = height * length * width; /* volume equals 960 */

Printing the Value of a Variable
printf can be used to display the current value of a variable.
     example: To display...
          Height: h
     ...where h is the current value of the variable named height....
          printf("Height: %d\n", height);
%d is a placeholder indicating where the value of height is to be filled in. \n forces the function to move to the next line after printing the value of height.
%d works only for int variables -- to print float variables, we use %f. %f displays six digits past the decimal point by default. To control how many digits are displayed, use %.xf, where .x is the number of digits past the decimal point you wish to show.
     Example:
          printf("Profit: $%.2f\n", profit);
          Profit: $2150.48
          printf("Profit: $%.3f\n", profit);
          Profit: $2150.480

Program Example:
Computing the Dimensional Weight of a Box
This program is based on shipping companies calculating the prices for boxes that are overly large for their weight. They charge by a term called Dimensional Weight, which is a value computed by dividing by the allowable number of cubic inches per pound (in this scenario, 166 is the number of cubic inches per pound).
To start out -- write a program that will calculate the volume and dimensional weight of a box that is 12x10x8.

     weight = volume/166;

Above, weight and volume are integer variables representing the box's weight and volume.
This isn't quite going to get us what we're looking for, however. When C processes division with integers, all answers are truncated, and the decimal points are lost. The volume of the box is 960, and when that is divided by 166, the answer is 5.783. When this is truncated, we are left "rounding down" when we need to be "rounding up". (To me, the solution to this would be to use a float, but for the sake of this example, I'm sticking to int.)
To solve this issue, we can alter the statement as such:

     weight = (volume + 165) / 166;

According to this, a volume of 166 would give a weight of (166 + 165) / 166 = 1, while a volume of 167 would give a weight of (167 + 165) / 166 = 2, solving the issue of appearing to round down.

The entire program for calculating the dimensional weight of this box:

#include <stdio.h>
int main(void)
{
     int height, length, width, weight, volume;
     height = 8;
     length = 12;
     width = 10;
     volume = height * width * length
     weight = (volume + 165) / 166

     printf("Dimensions: %dx%dx%d\n", length, width, height);
     printf("Volume (in cubic inches): %d\n", volume);
     printf("Dimensional Weight (in pounds): %d\n", weight);

     return 0;
}

The output of this program would read:
     Dimensions: 12x10x8
     Volume (in cubic inches): 960
     Dimensional Weight (in pounds): 6

Initialization
Some variables are automatically set to zero, but most are not. If a variable does not have a default value, it is uninitialized. If an uninitialized variable is accessed, it could return unpredictable results or crash a program, so make sure all variables are initialized.

Variables can be assigned values, but they can also be initialized in declarations.
     int height = 8, length = 12, width = 10;
All of the above variables are initialized.
     int height, length, width = 10;
Only width is initialized here.

Printing Expressions
printf is not limited to only displaying values stored in variables, but can also display entire expressions. This can simplify a program by reducing the amount of variables.
Example:
     printf("%d\n", volume)
This can be replaced by...
     printf("%d\n", height*length*width);

printf's ability to do this illustrates perfectly one of C's general principles:

Wherever a value is needed, an expression of the same type will do.

No comments:

Post a Comment