Chapter 2 : Elementary programming

Chapter 2 : Elementary programming

We will now concentrate exclusively on the content of programs.

Contents

2.1. A simple program

We return to the elementary program used in the previous chapter, and discuss its features.

Notes:

The earlier example program could be written

DO NOT WRITE LIKE THIS!

2.2. Output from the program

The identifier printf is used in combination with the parameters following it in printing instructions as follows.

Text between double quotes is printed exactly as given, arithmetic values are evaluated and printed as numbers where a "%" appears in the format string , see details below.

2.3. Variables

We will wish to have identifiers to represent variables which will be used for storing intermediate results during the running of the program.

For each identifier that we use, we must tell the computer the type of object which we wish to use it for.

The first "printf" instruction will print the text

The second prints

The third will print

Each print instruction in the above examples ends with a newline character. You will generally want to end with a newline, unless you are printing a prompt requesting the user to enter a reply.

Identifiers

The identifiers you choose to represent variables or #define items must satisfy various rules and recommendations.

  • They must start with a letter, which can be followed by any number of letters, digits and underscores.
  • They should be meaningful. In general, you should not use single characters such as "x", "y", "i" and "j"; these terse identifiers give no feel for the significance of the values they represent.
  • Your identifiers must not clash with certain special words. If you use "float", for example, the compiler will become very confused.
  • Upper and lower case characters (capital and small letters) in identifiers are distinct.

    Examples of identifiers are:

    It is common practice to use the underscore symbol to separate the component parts of an identifier.

    Declarations

    Declarations are program statements which tell the compiler which identifiers we intend to use. If an identifier occurs which we have not declared (either we forgot to declare it, or, more likely, we mistyped an identifier) the compiler will print an error message. Declarations such as those in the above program do two things:

  • They tell the compiler about an identifier/type pair, so that the compiler can interpret later statements correctly.
  • At run time, the running program must set aside the necessary space to store the specified type of object.

    At a later stage, we may need to distinguish between these two effects by separating a declaration into two parts.

    You may combine a declaration with the assignment of an initial value. If you do not initialise a variable, you cannot rely on it containing any particular value before you use it.

    At this stage, we will insist that you put #define lines before the main() line, and variable declarations after it, before any executable program code.

    2.4. Basic types

    The basic variable types in C are given below, together with their sizes in bytes on some implementations.

    type PDP 68000 VAXVMS
    char 1 1 1
    int 2 4 4
    long int 4 8 4
    short int 2 2 2
    float 4 4 4
    double 8 8 8

  • char: This can contain one character, a letter or digit or punctuation character.
  • int: This can contain integral (whole-number) values. There is a limit to the size of the largest positive and negative numbers which can be stored, which depends on how many bytes are occupied.
  • long int: This also contains integral values, and may use more space than, and hence be able to store larger numbers than, an int variable. It may actually be no larger than an ordinary int variable.
  • short int: This also contains integral values, and may use less space than, and hence be able only to store smaller numbers than, an int variable. It may actually be no smaller than an ordinary int variable, but you may need to conserve space if possible.
  • float: This type of variable can store all numeric values, not just integral values. The accuracy to which they are stored, and the maximum and minimum values, depend of the particular hardware/software being used.
  • double: This type of variable is intended for storing more accurate numeric values than float variables.

    2.5. Denotations

    A denotation is a representation of a particular value. Typical denotations for constants of various types are as follows.

  • int: Typical denotations might be

  • long int: The integer denotations must be followed by the letter "L" to indicate a "long int" denotation.

  • char: Single character as values are always written between prime symbols, so that they are not confused with identifiers.

  • float: Float values are typed as numbers with a decimal point, and can be optionally followed by the letter "E" (for exponent) and an integer. The value before the "E" is assumed to be multiplied by 10 raised to the power of the integer after the "E".

    The latter denotations represents the values -1234500, 1000000 and -0.000001 respectively.

    2.6. Comments

    Comments are from "/*" to the next "*/".

    For long comments, some people use

    to look pretty.

    2.7. Program layout

    Lay out your program carefully, with plenty of white space, indented as appropriate. I don't mind which convention you use, but be consistent! As programs become larger, program layout becomes more and more important.

    2.8. Input to the program

    We use printf for program output, and a similar function scanf for input to the program.

    Example

    Note that the prompt does not have a newline character, and has a space before the final closing quote.

    The scanf has a format string as its first parameter, and a variable name preceded by an ampersand (&) sign as its second argument. The ampersand sign is essential, its omission may cause strange failures with messages such as

    which leaves a (possibly huge) file called core in your directory. You should remove this with the UNIX command

    Example

    This second program reads two values.

    The escaped end-of-line causes the end-of-line to be ignored.

    You could avoid the variable "area" all together, and print the results with

    but this is not good practice.

    It is good practice at this stage of your course to print out all of the values you have read in, so that the output gives a complete picture of what has been calculated.

    You may loose a few marks on the dynamic testing if you do not do this. You will certainly loose marks if you do not put explanatory text into your output.

    You can now write simple programs to read in some values, evaluate a formula, and print the result.

    Formatted output

    You can use formatted output to print output more nicely. Above we used "%d" for decimal printing, and "%f" for floating. You can also use:

    The last statement would print in the format

    2.9. Operators in more detail

    We will now have a thorough tour of all of the available operators and their significance.

    2.9.1. Arithmetic operators

    The simple arithmetic operators you would expect to see are

    representing addition, subtraction, multiplication and division, respectively. As everywhere in C, types are important here. Between two "int"s the result is an "int", otherwise (between two "float"s, or between an "int" and a "float") the result is a "float". This is fairly obvious for addition, subtraction and multiplication.

    Beware of "/" between integers; the result is an "int", which may not be what you expected. It gives the quotient as an integer rounded down towards zero if the result is positive. If you type

    you may not get the expected result; both x and y will be set to zero! If the result would be negative, the language does not define exactly what will happen, for example whether "10 / -7" is -1 (which you would get if you rounded towards zero) or -2 (if you rounded down).

    The operator "%" between integers gives the remainder when the first is divided by the second. Thus "72 % 10" evaluates to 2, and "30 % 13" evaluates to 4. If either of the operands are negative there are ambiguities similar to those in division. The value of "10 % -7" might be -3 or +4. The official definition says that the value of the expression

    must always equal the value of "a."

    There is no operator in C for exponentiation (for raising any number to a given power).

    Example programs

    In the example programs given from now on, we may give only the text within the "{" and "}" of the main program. To run the program, you would have to add the lines up to main(){ and the final "}". Further, we may not include the niceties of prompts and input/output if we are really demonstrating other types of statement.

  • (i) Convert Fahrenheit temperature to Celsius

  • (ii) I have a certain number of bicycle spokes; I need 44 to make one wheel; how many wheels can I make? How many spokes will I have left over?

  • (iii) We know the number of football matches won, drawn and lost by a given team; how many points do they have (3 for a win, 1 for a draw)?

    2.9.2. Comparison operators

    There are many other operators besides those used for arithmetic evaluations. We will need these in the next chapter for use in "if ... then" constructs.

    These can be between (almost) any types of object. The result delivered is zero for FALSE, one for TRUE. In appropriate places in C generally, zero is always interpreted as meaning FALSE, while non-zero is interpreted as TRUE.

    Note that testing for equality "==" between floats or doubles is not sensible, because of the possibility of rounding errors. The compiler will permit you to do it, but it is considered bad practice. You should instead look for a small absolute difference between the two values.

    Examples

  • (i) Is the Fahrenheit temperature above freezing point?

  • (ii) Do I have enough spokes for 2 bicycle wheels?

    2.9.3. Logical operators

    For combining the results of comparisons, we need general logical operators. In fact, we are not limited to combining the results of comparisons; we can combine any values, and any zero value will be interpreted as FALSE, and non-zero value as TRUE. We use "&&" for the logical "and" and "||" for "or".

    Examples

  • (i) Is the Celsius temperature today within the expected band for this time of year, say 5 to 15 degrees?

  • (ii) Can I construct at least 2 wheels with less than 10 spokes left over?

    2.9.4. Incremental operators

    These are unique to C and C++. Their real significance and use will become apparent later.

    The word "increment" means "increment by a suitable value". Compare

    which prints the value 0, with

    which prints the value 1. In both cases, "i" takes the value 1 after the instruction.

    Note that

    is equivalent to

    where

    or

    is equivalent to

    You will often see the free-standing increment

    to add 1 to i, used instead of writing

    You will see examples of these operators later.

    2.9.5. Assignment

    The values being assigned will be cast or coerced (their types will be changed and their values converted between types) as required. Examples of assignments include the following.

    Delivered Result

    Assignment is an operator, and delivers as its result the value just assigned. Thus

    is equivalent to

    To assign the same value to several variables use

    Note that in initialising declarations, you MUST still write in full

    Examples

    These operations could all be performed as two separate instructions; express them as two statements if you feel happier that way.

  • (i) How many bicycle wheels can I make, and how many spokes will I have used?

    A warning

    Beware of using "=" instead of "==", such as writing accidentally

    with a single equals sign. This copies the value in "j" into "i", and delivers this value, which will then be interpreted as TRUE if is is non-zero.

    2.9.6. The comma operator

    The real significance and use of this operator will appear later. An expression consisting of statements separated by commas, as in

    causes each statement to be executed in turn; the result finally delivered is that delivered by the last statement. Thus you can write

    or

    The effect of this last statement is exactly the same as if you had typed

    2.9.7. Operator precedence

    It is necessary to define carefully the meaning of such expressions as

    to define the effect as either

    or

    All operators have a priority, and high priority operators are evaluated before lower priority ones. Operators of the same priority are evaluated from left to right, so that

    is evaluated as

    as you would expect.

    Exact details are in any book on C. There are many operators here that we have not yet met, but they are all entered here for completeness.

    If you are ever in doubt, use extra parentheses to ensure the correct order of evaluation, and (equally important) to ensure the easy readability of the program.

    From high priority to low priority the order is

    Thus

    is interpreted as

    and

    as

    Coursework exercise marking

    The exercises in this unit are marked partly on dynamic correctness and partly on Typographic layout. For dynamic correctness we run the program against samples of test data, and look in the output for the correct results; we also check for words in your output, so that you should print for example

    rather than merely print a few numbers. In general you should also at this stage print out the values you have just read in, so that the output is complete in itself.

    Your program itself should be easily "readable" to others. The "typographic" marker checks that your program is laid out as suggested above and in lectures; that it is indented correctly, that it contains a reasonable amount of "white space" (blank lines and spaces within lines), that you have a reasonable number of comments in the program, that the identifiers you have chosen are meaningful, and that you have done all the other things mentioned above to make a program readable to others.

    The exact typographic marking metrics vary from exercise to exercise, but as a rough guide the typographic mark is formed as follows. The marking looks for correct indentation, approximately 20 to 30 characters per line, 30 to 60% comment in the program with comments after every "}", 20 to 50% blank lines, 20 to 30% white space in a line, and an average identifier length between 5 and 10.

    Copyright Eric Foxley 1996


    Notes converted from troff to HTML by an Eric Foxley shell script, email errors to me!