Augustana University College

COMPUTING SCIENCE 370 -- Programming Languages


Notes on C

Notice how I avoided obvious puns such as "Notes in the key of C", "Notes: C", "Let's C", "From C to C++", "The ABC's of C", . . .


NOTE: Sample programs are now available at the bottom of this page.

Program

A program:

A C program typically uses a preprocessor for macro substitution (including header files, substituting literal constants, macros, conditional compilation, etc.)

Typical layout:

    macros
    global variable definitions
    main() {
         :
    }
    additional functions

NOTE: Just because global variable definitions are typical, it doesn't mean they're a good idea.

Comments

Only /* C-style */ comments are mandated by the ANSI C standard. Some compilers support C++ end-of-line comments preceded by //, but not all.

C-style comments do not nest. To comment out large chunks of code use preprocessor commands:

#if 0
	. . . 
#endif

Functions

Function arguments must be enclosed in parentheses ( ) after the function name, even if there are none. The return type of the function (optionally) precedes the function name.

Curly braces { } enclose the block (body of the function).

C does not require function prototypes prior to the call of a function. If no prototype has been encountered by the time a function is called, the compiler assumes that it returns an int, and the caller is responsible to ensure that it is provided with the correct number of parameters. (C programs tend to halt or freeze mysteriously when called with the wrong number of arguments.)

If a function does not return a value (i.e., it is a procedure, not a function), it is preferable to declare it to "return" void instead of letting it default to returning int.

If you want to use a function prior to defining it (e.g., to adhere to the typical program layout shown above, in which the main function precedes the functions which it calls), you can declare a function without defining it (i.e., providing the block) by providing only a prototype or signature:

   char letter_of_alphabet( unsigned index );

If you want to use a function which is defined in another source file, you can include a prototype for the function in the current file, prior to the use of the function, preceded by extern to indicate that the function is defined externally:

    extern double ipow( double base, int expon );

Variables and Data Types

    variable_identifier ::= <letter> [<letter> | <digit> | _ ]*
    variable_declaration ::= <type>  <variable_identifier>+;

Variables may be initialized as part of the declaration.

Examples:

    int lower, upper, step;
    float fahr, celcius;
    char c = 'a';
    short count;
    short int num = 0;
    unsigned cardinal;
    unsigned int nat_num;
    long bignum = 6L;
    long int really_big;
    double bigfloat = 2.0e12;
    int ch = getchar();

In C, variables must be declared prior to use, and may be declared at the beginning of any new block (scope). Once an executable statement is encountered in a block, no further declarations are recognized [unlike C++ and Java].

Loop control variables cannot be declared in the conditional part of a for as they can in C++ and Java.

Variable names are case-sensitive. Only the first 31 characters of a variable identifier are guaranteed to be significant.

Variable declarations may be prefixed with storage class specifiers and type qualifiers, the most common of which are:

Operators and Expressions

Operators and expressions are the same in C and C++ except for the C++ compound operators

    .*   ->*   ::

Control Flow Statements

C uses the same control constructs as C++ and Java. (Actually, it happened the other way around.)

Objects and Classes

C doesn't have any. Instead of classes, you can use the struct as a heterogeneous data aggregation.

	struct nodestruct
	{
	    int data;
	    nodestruct *link;

	} node, *nodeptr;

	node.data = 14;

In essence, a struct is a class with no function members (methods) and public visibility.

Sample Programs

. args.c -- How to access command-line arguments.

Also illustrates the use of 'strncpy()' for secure string copying (no buffer overflow).

. null_str_test.c -- What happens if you print a null string? What if you try to find out its length?

Quiz: What string has a length of zero (according to 'strlen()')?

. ops.c -- A simple demonstration of some C operators.

Note the use of '/' for integer division vs. real division.

. reverse.c -- Reverse a string in place.

. squares.c -- An interesting use of a 'for' loop to generate the perfect squares to 100.

. swap.c -- The standard demonstration of passing pointers as function parameters in order to achieve in/out mode semantics.

Note the use of '&' on the arguments to 'scanf()'.

. table.c -- A Fahrenheit/Celcius equivalence table.

Note the format strings used in 'printf()'.
Copyright © 2000 Jonathan Mohr