0% found this document useful (0 votes)
61 views12 pages

The Structure of C Programs: #Include #Include #Include #Include

The document discusses the structure and key components of C programs. It covers the overall layout including comments, preprocessor directives, functions, and main. It also describes variables and data types, scope, flow of control using conditionals and loops, and bounded for loops.

Uploaded by

aznparia3025
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
61 views12 pages

The Structure of C Programs: #Include #Include #Include #Include

The document discusses the structure and key components of C programs. It covers the overall layout including comments, preprocessor directives, functions, and main. It also describes variables and data types, scope, flow of control using conditionals and loops, and bounded for loops.

Uploaded by

aznparia3025
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

The structure of C programs

Let's looks at the high-level structure of the rot.c program from Lab01 (using ellipsis to omit some statements for now). Of note in this example:
#include #include #include #include <stdio.h> <stdlib.h> <string.h> <ctype.h>

Characters such as a space, tab, or newline, may appear almost anywhere - they are stripped out and ignored by the C compiler. We use such whitespace characters to provide a layout to our programs. While the exact layout is not important, using a consistent layout is very good practice. Keywords, in bold, mean very specific things to the C compiler. Lines commencing with a '#' in blue are processed by a separate program, named the C preprocessor. In practice, our program is provided as input to the preprocessor, and the preprocessor's output is given to the C compiler. Lines in green are comments. They are ignored by the C compiler, and may contain (almost) any characters. C99 provides two types of comments 1. /* block comments */ and 2. // comments to the end of a line

/* Compile this program as: gcc -std=c99 -Wall -Werror -pedantic -o rot rot.c */ #define ROT 13 static char rotate(char c) { ..... return c; } int main(int argc, char *argv[]) { // check the number of arguments if(argc != 2) { .... exit(EXIT_FAILURE); } else { .... exit(EXIT_SUCCESS); } return 0; }

CITS1210 C Programming: Lecture 2, Wednesday 4 August.

1/12

The structure of C programs, continued


More to note:
#include #include #include #include <stdio.h> <stdlib.h> <string.h> <ctype.h>

A variety of brackets are employed, in pairs, to group together items to be considered in the same way. Here: angle brackets enclose a filename in a #include directive, round brackets group items in arithmetic expressions and function calls, square brackets enclose the index when access arrays (vectors and matricies...) of data, and curly brackets group together sequences of one or more statements in C. We term a group of statements a block of statements. Functions in C, may be thought of as a block of statements to which we give a name. In our example, we have two functions - rotate and main. When our programs are run by the operating system, the operating system always starts our program from main. Thus, every complete C program requires a main function. The operating system passes some special information to our main function, command-line arguments, and main needs a special syntax to receive these. When our program finishes its execution, it returns some information to the operating system. Our example here exits by announcing either its failure or success.

/* Compile this program as: gcc -std=c99 -Wall -Werror -pedantic -o rot rot.c */ #define ROT 13 static char rotate(char c) { ..... return c; } int main(int argc, char *argv[]) { // check the number of arguments if(argc != 2) { .... exit(EXIT_FAILURE); } else { .... exit(EXIT_SUCCESS); } return 0; }

CITS1210 C Programming: Lecture 2, Wednesday 4 August.

2/12

Variables
Variables are locations in a computer's memory. A typical desktop or laptop computer will have 1GB of memory, or one billion addressible memory locations, and C programs will typically use 4 bytes to hold 1 integer value. Any variable can only hold a single value at any time - they do not maintain a history of past values they once had.

Naming our variables


To make programs more readable, we provide variables with simple names. We should carefully choose names to reflect the role of the variable in our programs. While variable names can be almost anything (but not the same as the keywords in C) there's a simple restriction on the permitted characters in a name they must commence with an alphabetic or the underscore character (_ A-Z a-z), and be followed by zero or more alphabetic, underscore or digit characters (_ A-Z a-z 0-9). C variable names are case sensitive, thus:
MYLIMIT, mylimit, Mylimit

and MyLimit

are four different variable names. Older C compilers may limit variable names to, say, 8 unique characters. Thus, for them,
turn_reactor_coolant_on

and

turn_reactor_coolant_off

are the same variable! Keep this in mind when writing portable code. While not required, it's preferred that variable names do not consist entirely of uppercase characters. We'll consistently use uppercase-only names for constants provided by the C preprocessor, or user-defined type names:
MAXLENGTH, AVATAR, BUFSIZ, and ROT

CITS1210 C Programming: Lecture 2, Wednesday 4 August.

3/12

Basic datatypes
Variables are declared to be of a certain datatype, or just type. We use different types to represent the role permissible values that a program's variable has. For example, if we're using a variable to just count things, we'll use an integer variable to hold the count; if performing trigonometry on angles expressed in radians, we'll use floating-point variables to hold values with both an integral and a fractional part. C provides a number of standard, or base types to hold commonly required values, and later we'll see how we can also define our own user-defined types to meet our needs. Let's look quickly at some of C's base datatypes: typename bool char int float double description, and an example of variable initialization Boolean (truth values), which may only hold the values of either true or false e.g. bool finished = false; character values, to each hold a single values such as an alphabetic character, a digit character, a space, a tab... e.g. char initial = 'C'; integer values, negative, positive, and zero e.g. int year = 2006; floating point values, with a typical precision of 10 decimal digits (on our lab machines) e.g. float inflation = 4.1; "bigger" floating point values, with a typical precision of 17 decimal digits (on our lab machines) e.g. double pi = 3.1415926535897932;

Some textbooks will (too quickly) discuss the actual storage size of these basic types, and discuss the ranges of permissible values. We'll examine these later, but for now we'll focus on using these basic types in their most obvious ways. From where does the bool datatype get its name? - the 19th century mathematician and philosopher, George Boole.
CITS1210 C Programming: Lecture 2, Wednesday 4 August. 4/12

The scope of variables


The scope of a variable describes the range of lines in which the variable may be used. Some textbooks may also term this the visibility or lexical range of a variable. C has only 2 primary types of scope: global scope (sometimes termed file scope) in which variables are declared outside of all functions and statement blocks, and block scope in which variables are declared within a function or statement block. The variable count has global scope.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include #include #include #include <stdio.h> <stdlib.h> <string.h> <ctype.h>

It is defined on line 06, and may be used anywhere from line 06 until the end of the file (until line 26). The variable nfound has block scope. It is defined on line 10, and may be used anywhere from line 10 until the end of the block in which it was defined (until line 26). The variable nerrors has block scope. It is defined on line 14, and may be used anywhere from line 14 until line 18. The variable ntimes has block scope. It is defined on line 20, and may be used anywhere from line 20 until line 24. We could define a different variable named nerrors in the block of lines 20-24 - without problems. We could define a different variable named nfound in the block of lines 20-24 - but this would be a very bad practice!

static int count = 0; int main(int argc, char *argv[]) { int nfound = 0; // check the number of arguments if(argc != 2) { int nerrors = 1; .... exit(EXIT_FAILURE); } else { int ntimes = 100; .... exit(EXIT_SUCCESS); } return 0; }

CITS1210 C Programming: Lecture 2, Wednesday 4 August.

5/12

Flow of control in a C program


A program's control flow describes how sequences of statements are executed. As we've seen, C programs commence ther execution at their main function, execute their statements, and exit (return the flow of control) to the operating system. It's fairly obvious that statements need to be executed in a well-defined order, as we expect programs to always behave the same way (unless some randomness is introduced, as in computer games). Default flow of control executes each statement in order, top-to-bottom. Programs that only execute from top-to-bottom are pretty boring, and we need to control their flow with a variety of conditional statements and loops.

Conditional execution
Conditional statements first evaluate a Boolean condition and then, based on whether it's true or false, execute other statements. The most common form is: Sometimes, the else clause is omitted: Often, the else clause itself provides further if statements:

if(condition) { more statements; ..... } else { more statements; ..... }

if(condition) { more statements; ..... }

if( condition1) { more statements; ..... } else if(condition2) { more statements; ..... } else { more statements; ..... }

CITS1210 C Programming: Lecture 2, Wednesday 4 August.

6/12

Flow of control in a C program - bounded loops


One of the most powerful features of computers, in general, is to perform thousands, millions, of repetitive tasks quickly (in fact, one of the first uses of computers in the 1940s was to calculate trigonometric tables for the firing of artillery shells). C provides its for control statement to loop through a sequence of statements, a block of statements, a known number of times: The most common form appears below, in which we introduce a loop control variable, i, to The loop control variable does not always have to be an integer: count how many times we go through the loop:

// here, variable i holds the values 1,2,...10 for(int i = 1 ; i <= 10 ; i = i+1) { // the above introduced a loop-control variable, i ..... printf("loop number %d\n", i); ..... // variable i is available down to here } // but variable i is not available from here

// here, variable ch holds each lowercase value for(char ch = 'a' ; ch <= 'z' ; ch = ch+1) { ..... printf("loop using character '%c'\n", ch); ..... }

Notice that in both cases, above, we have introduced new variables, here i and ch, to specifically control the loop. The variables may be used inside each loop, in the statement block, but then "disappear" once the block is finished (after its bottom curly bracket). It's also possible to use any other variable as the loop control variable, even if defined outside of the for loop. In general, we'll try to avoid this practice - unless the value of the variable is required outside of the loop.
CITS1210 C Programming: Lecture 2, Wednesday 4 August. 7/12

Flow of control in a C program - unbounded loops


The for loops that we've just seen should be used when we know, ahead of time, how many times we need to loop (i.e. 10 times, or over the range 'a'..'z'). Such loops are termed bounded loops and, unless we've made a silly coding error will always terminate after a fixed number of iterations. There are also many occasions when we don't know, ahead of time, how many iterations may be required. Such occasions require unbounded loops. C provides two types of unbounded loop: The most common is the while loop, where zero or more iterations are made through the Less common is the do....while loop, where at least one iteration is made through the loop: loop:

i = 1; n = 0; while(i <= 20) { printf("iteration number %d\n", i); ..... ..... i = some_calculation_setting_i; n = n + 1; } printf("loop was traversed %d times\n", n);

i = 1; n = 0; do { printf("iteration number %d\n", i); ..... ..... i = some_calculation_setting_i; n = n + 1; } while(i <= 20); printf("loop was traversed %d times\n", n);

Notice that in both cases we still use a variable, i, to control the number of iterations of each loop, and that the changing value of the variable is used to determine if the loop should "keep going". However, the statements used to modify the control variable may appear almost anywhere in the loops. The can provide flexibility, but can also be confusing when loops become severals tens or hundreds of lines long. Notice also that while, and do....while loops cannot introduce new variables to control their iterations, and so we have to use "more global" variables.
CITS1210 C Programming: Lecture 2, Wednesday 4 August. 8/12

Writing loops within loops


There's a number of occassions when we wish to loop a number of times (and so we use a for loop) and within that loop we wish to perform another loop. While a little confusing, this construct is often quite common. It is termed a nested loop.

for(int i = 1 ; i <= 6 ; i = i+1) { for(int j = 1 ; j <= 4 ; j = j+1) { printf("(%d,%d) } printf("\n"); } ", i, j); // print i and j as if "coordinates" // finish printing on this line

The resulting output will be:


(1,1) (2,1) (3,1) (4,1) (5,1) (6,1) (1,2) (2,2) (3,2) (4,2) (5,2) (6,2) (1,3) (2,3) (3,3) (4,3) (5,3) (6,3) (1,4) (2,4) (3,4) (4,4) (5,4) (6,4)

Notice that we have two distinct loop-control variables, i and j. Each time that the inner loop (j's loop) starts, j's value is initialized to 1, and advances to 4. As programs become more complex, we will see the need for, and write, all combinations of: for loops within for loops, while loops within while loops, for loops within while loops, and so on....
CITS1210 C Programming: Lecture 2, Wednesday 4 August. 9/12

Changing the regular flow of control within loops


There are many occasions when the default flow of control in loops needs to be modified. Sometimes we need to leave a loop early, using the break statement, possibly skipping some iterations and some statements: Sometimes we need to start the next iteration of a loop, even before executing all statements in the loop:

for(int i = 1 ; i <= 10 ; i = i+1) { // Read an input character from the keyboard ..... if(input_char == 'Q') // Should we quit? break; ..... ..... } // Come here after the 'break'. i is unavailable

for(char ch = 'a' ; ch <= 'z' ; ch = ch+1) { if(ch == 'm') // skip over the character 'm' continue; ..... ..... statements that will never see ch == 'm' ..... ..... }

In the first example, we iterate through the loop at most 10 times, each time reading a line of input from the keyboard. If the user indicates they wish to quit, we break out of the bounded loop. In the second example, we wish to perform some work for all lowercase characters, except 'm'. We use continue to ignore the following statements, and to start the next loop (with ch == 'n').
CITS1210 C Programming: Lecture 2, Wednesday 4 August. 10/12

The equivalence of bounded and unbounded loops


We should now be able to see that the for, while, and do ... while control flow statements are each closely related. To fully understand this, however, we need to accept (for now), that the three "pieces" of the for construct, are not always initialization, condition, modification. More generally, the three pieces may be C expressions - for the moment we'll consider these as C statements which, if they produce a value, the value is often ignored. The following loops are actually equivalent:

for( expression1 ; expression2 ; expression3 ) { statement1; .... }

expression1; while(expression2) { statement1; .... expression3; }

In both cases, we're expecting expression2 to produce a Boolean value, either true or false, as we need that truth value to determine if our loops should "keep going". You should think about these carefully, perhaps perform some experiments, to determine where control flow really goes when we introduce break and continue statements.
CITS1210 C Programming: Lecture 2, Wednesday 4 August. 11/12

Some unusual loops you will encounter


As you read more C programs, you'll see some statements that look like for or while loops, but appear to have something missing. In fact, any (or all!) of the 3 "parts" of a for loop may be omitted. For example, the following loop initially sets i to 1, and increments it each iteration, but it doesn't have a "middle" test to see if the loop has finished:

for(int i = 1 ; ; i = i+1) { ..... ..... }

And this loop doesn't even have a loop-control variable, and doesn't test for its termination. This loop will run forever, until we interrupt or terminate the operating system process running the C program. We term these infinite loops :

for( ; ; ) { ..... ..... }

While we often see and write such loops, we don't usually want them to run forever! We will typically use an enclosed condition and a break statement to terminate the loop, either based on some user input, or the state of some calculation.
CITS1210 C Programming: Lecture 2, Wednesday 4 August. 12/12

You might also like