52.223 low level programming lecturer: duncan smeed overview of the c programming language part 1

139
52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Upload: elaine-clark

Post on 28-Dec-2015

226 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

52.223 Low Level Programming Lecturer: Duncan Smeed

Overview of the C Programming Language

Part 1

Page 2: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/2

Nature of C

The C programming language has acquired the reputation for being a mysterious and messy language that promotes bad programming habits.

Part of the problem is that C gives special meanings to many punctuation characters, such as asterisks, plus signs, braces and angle brackets.

Once a programmer has learnt the C language, these symbols look quite commonplace, but there is no denying that a typical C program can be intimidating to the uninitiated.

Page 3: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/3

Trust the programmer

The other, more serious, complaint levelled against C concern the relative dearth of rules.

Other programming languages have very strict rules to protect programmers from making accidental blunders.

The C language was designed by experienced programmers for experienced programmers. The compiler, therefore, assumes little about what the programmer does or does not intend to do. This can be summed up by the C tenet:

"Trust the programmer"

Page 4: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/4

…Trust the programmer

C programmers have tremendous liberty to write unusual code.

In may instances, this freedom allows programmers to write useful programs that would be difficult to write in other languages.

However, the freedom can be, and is, abused by inexperienced programmers who delight in writing needlessly tricky code.

C is a powerful language, but it requires self-restraint and discipline.

Page 5: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/5

…Trust the programmer

“...there is a huge difference between good and working programs. A good program not only works, but is easy to read and maintain. Despite what some people claim, it is very possible to write good programs in C. Unfortunately, many C programmers are content to write programs that merely work.”

Excerpted from C: A Software Engineering Approachby Darnell and Margolis

Page 6: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/6

The Background of C

C was originally designed for and implemented on the Unix operating system on the DEC PDP-11, by Dennis Ritchie.

Unix, the C compiler, and virtually all Unix applications programs are written in C.

C is not tied to any particular hardware or system, however, and it is easy(!) to write programs that will run without change on any machine that supports C.

Page 7: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/7

…The Background of C

C is a general purpose programming language which features economy of expression, modern control flow and data structures, and a rich set of operators.

C is not a 'very high level' language, nor a 'big' one, and is not specialised to any particular area of application.

Its absence of restrictions and its generality make it more convenient and effective for many tasks than supposedly more powerful languages.

Page 8: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/8

…The Background of C

C has been closely associated with the Unix system. It is, however, available on a large number of

machines under a variety of operating systems; and although it has been called a "systems programming

language" because it is useful for writing operating systems, it has been used equally well to write numerical, text-processing, and database programs.

Page 9: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/9

…The Background of C

C is a relatively "low level" language which means that it deals with the same sort of objects that most computers do, namely characters, numbers and addresses. These may be combined and moved about with the usual arithmetic and logical operators implemented by actual machines.

C provides no operations to deal directly with composite objects such as character strings, sets, lists, or arrays considered as a whole.

C also provides no input-output facilities such as READ or WRITE. Such high-level mechanisms must be provided by explicitly called functions.

Page 10: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/10

…The Background of C

The absence of such features keep the language down to modest dimensions so that it can be described easily, and learned quickly.

A compiler for C can be simple and compact and are easily written with, typically, 80% of the code common to existing ones. This provides a high degree of language mobility.

Page 11: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/11

…The Background of C

Because the data types and control structures provided by C are supported directly by most existing computers, the run-time library required to implement self-contained programs is tiny.

Of course, each implementation provides a comprehensive, compatible, library of functions to carry out I/O, string handling, and storage allocation operations, but since they are called only explicitly, they can be avoided if required; they can also be written portably in C itself.

Page 12: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/12

…The Background of C

C programs tend to be efficient enough that there is no compulsion to write assembly language instead.

The most obvious example of this is Unix itself, the kernel of which is written almost entirely in C.

Of the 13000 lines of system code in early versions of Unix, only about 800 lines at the very lowest level were in assembler.

Since C is independent of any particular machine architecture it is possible, with a little care, to write "portable" programs that can be run without change on a variety of hardware.

Page 13: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/13

C as a Programming Language

Many of the most important ideas of C stem from the considerably older language BCPL.

Although it shares several characteristic features with BCPL, C is in no sense a dialect of it. BCPL was a "typeless" language: the only data type is the machine word, and access to other kinds of objects is by special operators or function calls.

In C, the fundamental data objects are characters, integers of several sizes, and floating point numbers. In addition there is a hierarchy of derived data types created with pointers, arrays, structures, unions and functions.

Page 14: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/14

C Flow-Control Constructions

C provides the fundamental flow-control constructions required for well-structured programs:• statement grouping;• decision making (if);• looping with the termination test at the top (while,

for) or at the bottom (do);• and selecting one of a set of possible cases (switch).

Page 15: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/15

C Call By ‘Value’ & Call By ‘Reference’

C provides pointers and the ability to do address arithmetic.

The arguments to functions are passed by copying the value (call by value) of the argument, and it is impossible to change the actual argument in the caller.

However, call be reference can be achieved by passing a pointer explicitly, and the function may change the object to which the pointer 'points'.

Array names are passed as the location (address) of the array origin, so array arguments are effectively call by reference.

Page 16: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/16

C Variables

Any function may be called recursively, and its local variables are typically "automatic" - created anew with each invocation.

Functions may be compiled separately. Variables may be (a) internal to a function, (b) external

but known only within a single source file, or (c) completely global.

Internal (local) variables may be placed in registers for efficiency, but the register declaration is only a hint to the compiler and cannot specify actual registers.

Page 17: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/17

Summary of C language structure

Notes• letter case is NOT ignored by the compiler.• a newline (carriage return) in the C source is

equivalent to a space, it does not indicate the end of a statement except in the case of pre-processor directives.

Page 18: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/18

Strings and Character Constants

Strings are normally terminated by a null character, i.e. the value 0.

A string literal (constant) is specified between double quotes, e.g. "this is a string". The compiler appends the null byte to the end of a string literal.

A character literal is specified between single quotes, e.g. 'A'. No null is appended. Character literals are integers.

Page 19: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/19

Control Characters

Control characters are entered in literals following a backslash character (\), as follows:

newline \n

tab \t

backspace \b

formfeed \f

backslash \\

single quote \'

double quote \"

null \0

other control chars \N (where N is octal no.)

Page 20: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/20

Integer and Floating Point Constants

Integer Constants

nnn decimal constant, e.g. 123

0nnn octal constant, e.g. 037

0xnnn hexadecimal constant, e.g. 0x1a3

nnnL a long decimal constant

Floating Point Constants

FP constants are always double precision. Examples:

1.23, 1., .23, 1.23e4, 1.23E4, 3e4

Page 21: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/21

Comments

/* This is a comment */ They may appear wherever a space or newline is

allowed. Comments are not allowed to nest (caveat: some

compilers allow nesting). So:someVar = 1; /* some comment *//* someVar = 1; */ /* still legal *//* but this attempt to comment out ...someVar = 1; /* some comment */...is illegal in most compilers. */

Page 22: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/22

Identifiers

An identifier is a sequence of letters and digits; the first character of which must be a letter.

The underscore, _ , counts as a letter. UPPER and lower case letters are different. To conform to the C standard, a compiler must treat at

least the first 31 characters as significant in the names of functions and global variables (i.e. identifiers with external linkage), and at least the first 63 characters in all other identifiers.• External identifiers, which are used by various assemblers

and linker/loaders, may be more restricted.

Page 23: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/23

Variable Types

The sizes of the following variable types are implementation dependent. Typical values (in bits) for ANSI C are given:

Type Size Usechar 8 ASCII characters - may be signedshort 16 Same as intint 32 2's complement (signed) integerunsigned int 32 unsigned integerlong 32 2's complement (signed) integerfloat 32 Floating point numberdouble 64 Floating point number

Page 24: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/24

Storage Classes

Definitions outside of a function are external definitions. There are two classes:extern global to all files (default)

static local to this file, but global to all functions in this file

auto local to the function, lost on exit (default)

static local to the function, but not lost on exit

extern declares a variable that is to be found in an external definition

register Similar to auto, but hints to the compiler that the variable is heavily used and should be held in a register

Within a function:

Page 25: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/25

Program Structure

A C program is a series of external definitions and pre-processor directives.

External definitions are storage definitions and function definitions.

The executable part of the program is made up of the functions, which may call each other, passing parameters as required.

There must be one function whose name is main. It is this function that is called when the program is run. Functions cannot be defined within functions.

Page 26: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/26

The First C Program

#include <stdio.h>

int main(){

printf("Hello, world\n");return (0);

}

Page 27: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/27

Function Definition

A function definition has three parts:a) the function declaration

b) the parameter declarations

c) the function body - a compound statement

/* Declare the function max that returns an int... */int max(int a,int b,int c)/* ...with the parameters a, b, and c of type int */{ /* start of the compound statement */ int m; /* auto storage decl'n (local var.) */ m = (a>b) ? a : b; /* m = max of a,b */ return ((m>c) ? m : c); /* return max of m,c */} /* end compound statement */

Page 28: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/28

Compound Statement

A compound statement may be used wherever a simple statement is permitted. It has two parts:

a) storage declarations and definitions (optional)

b) executable statements

The compound statement is enclosed in braces {curly brackets such as these}.

Page 29: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/29

Simple Statement

A simple statement has the form:

label: statement;

The label is optional - it's only use is the target of a goto ({over}use of which is to be strongly discouraged). A label takes the same form as an identifier.

Page 30: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/30

Pointers and Addresses

An identifier may be declared as a pointer to a particular type of data. This is frequently used in string manipulation, using a pointer to type char, and in buffered files, using a pointer to type FILE. Example declarations:

char *a; /* a declared to be a pointer to char */int *b[5]; /* b declared as an array of 5 pointers to int */

Page 31: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/31

Address Operator &

The address operator & yields the address of its operand.

If the operand x has the type T, then the expression &x has the type ‘pointer to T’.

The operand of the address operator must have an addressable location in memory. I.e. the operand must designate either a function or an object (i.e. an lvalue) that is not a bit-field, and has not been declared with the storage class register

Page 32: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/32

Pointer Variables

A pointer variable contains the address of a storage element. The address of a variable can be put in a pointer:

int x; /* defines an integer */int *p; /* defines a pointer to int */p = &x; /* place address of x in p */x = *p; /* places the value pointed at by p in x */

Pointers can have integers added or subtracted, which moves them by that number of storage elements. E.g., adding 5 to a pointer to int moves it forward by 5 integer 'elements' - 20 bytes in the case where an int is 32-bits in size.

A pointer can have the constant value 0 (null) assigned to it. It is then a null pointer and is guaranteed to be different to any pointer to an actual value.

Page 33: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/33

main()

Every executable program must contain a special function called main(), which is where program execution begins. For example, to invoke max(), you could write:

int main(){ int maximum; maximum = max(3,4,5); /* rest of main() ... */}

Page 34: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/34

printf()

The printf() function is the most versatile runtime routine for display output.

This function can take any number of arguments, the first of which - the format string - is special as it specifies how many data arguments are to follow and how they are to be formatted.

The format string is enclosed in double quotes, and may contain text and format specifiers.

Page 35: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/35

printf() Format Specifier

A format specifier is a special character sequence that begins with a percent sign (%) and indicates how to write a single data item. For example:

printf("The maximum of %d %d & %d is %d\n”,\ 3,4,5,max(3,4,5));

The %d specifiers indicate that the data items are decimal integers. Other similar specifiers are:

%c character data item%f floating point data item%s null-terminated character array (string)%o octal integer%x hexadecimal integer

Page 36: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/36

scanf()

The scanf() function is the mirror image of printf() - it reads data entered form standard input (i.e. the keyboard). The major difference is that scanf() must have the address of a data item passed as the argument. For example:

scanf("%d %d %d",&num1,&num2,&num3);

directs the system to read integer input and store the values in num1, num2 and num3. The ampersand (&) is a special character that yields the address of a variable.

The best way to learn how to use printf() and scanf() is to experiment with them and, of course, to read complete descriptions of them in the manual pages or from a text book.

Page 37: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/37

The Preprocessor

The preprocessor can be thought of as a separate program that runs before the compiler.

The preprocessor directives begin with a hash (#) sign, which must be the first character on the line.

Unlike C statements, a preprocessor directive ends with a newline, not a semicolon.

Page 38: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/38

#include

The #include directive causes the compiler to read source text from another files as well as the file it is currently compiling. This is useful when identical information is to be shared by more than one source file. It has two forms:

#include <filename>

#include "filename" The <...> form causes the preprocessor to look in a special

directory which contains all the system include files, such as header files for the runtime library - e.g. <stdio.h>.

The "..." form causes the preprocessor to look in the directory containing the source file and, if it can't find it there, it'll revert back to the special directory.

Page 39: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/39

#define

The #define directive associates a name with a constant (among other thing). For instance:

#define MAX_PAGE_WIDTH 80#define LOOPS 100000000

Naming constants has two important benefits.• Firstly, it enables the programmer to give a

descriptive name to a nondescript constant thus making the program easier to read and understand (hopefully!).

• Secondly, they make the program easier to change!

Page 40: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 152223_05/40

References & Bibliography

C in a Nutshell<http://www.oreilly.com/catalog/cinanut/>

The C Book (online e-book)<http://publications.gbdirect.co.uk/c_book/>

Standard C<http://www-ccs.ucsd.edu/c/>

C: A Software Engineering Approach (print on demand?)<http://tinyurl.com/ay58v>

Page 41: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

52.223 Low Level Programming Lecturer: Duncan Smeed

Overview of the C Programming Language

Part 2

Page 42: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/42

Scalar Data Types

The ability to divide data into different types is one of the most important features of modern programming languages.

The programmer can work with integers, characters, floating point numbers, etc., without having to be concerned with the underlying representations.

It is up to the compiler, therefore, to make sure that the computer handles bits and bytes in a way consistent with their data type.

Page 43: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/43

…Scalar Data Types

The C language offers a small but useful set of data types:

Arithmetic types: Integers and floating-point entities. Scalar types: arithmetic types plus pointers and

enumerated types. Known as the scalar types because all of the values lie along a linear 'scale'.

Aggregate types: a combination of one or more scalar types including:• arrays, structures and unions• useful for organising logically-related variables into

physically-adjacent groups. Void type: neither scalar or aggregate.

Page 44: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/44

Hierarchy of C Data Types

Data Types

Scalar Types

Aggregate

Types

Arithmetic

Types

Pointers enum

Void

Integral

Types

Floating

Types

Page 45: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/45

Standard Signed Integer Types

Type Synonyms

signed char

int signed, signed int

shortshort int, signed short, signed short int

longlong int, signed long, signed long int

long long (C99)long long int, signed long long, signed long long int

Page 46: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/46

Standard Unsigned Integer Types

Type Synonyms

unsigned char

unsigned int unsigned

unsigned short unsigned short int

unsigned long unsigned long int

unsigned long long unsigned long long int

Page 47: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/47

char

The type char is one of the standard integer types but can be signed or unsigned depending on the implementation. So,

char, signed char and unsigned char are formally three different types.

Type Synonyms

char signed char or unsigned char

Page 48: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/48

Floating-point Types

The standard floating-point types for calculating with real numbers are as follows:

floatSingle precision

doubleDouble precision

long doubleExtended precision

Page 49: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/49

Typedefs

Names for data types can be created with a typedef keyword. Syntactically, a typedef is exactly like a variable declaration

except that the declaration is preceded by the typedef keyword. Semantically, the variable name becomes a synonym for the

data type rather than a variable that is allocated memory. E.g.:

typedef long int DOUBLE_WORD; The following declarations are now identical:

long int j;

DOUBLE_WORD j; By convention, typedef names are capitalised so that they are

not confused with variable names.

Page 50: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/50

Uses of Typedefs

Typedefs are especially useful for abstracting global types that can be used throughout a program.

Another use for typedefs is to compensate for differences in C compilers:

For example, some non-ANSI C compilers do not support the unsigned short type. Using typedefs, you can write the program so that it uses unsigned short if it's available, or unsigned int if not.

• ANSI-conforming:

typedef unsigned short USHORT;• non-ANSI:

typedef unsigned int USHORT;

Page 51: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/51

BUG ALERT - Confusing typedef with #define

It may seem that typedef duplicates functionality provided by the #define directive. E.g.:

#define USHORT unsigned intwhich seems to serve the same effect as:

typedef unsigned int USHORT; However, for complex type declarations #define is

inadequate. E.g.:#define PTR_TO_INT int *

to declare two pointers to int:PTR_TO_INT p1,p2;

which expands to:int * p1, p2; /* I.e. p2 is an int

*/

Page 52: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/52

Enumeration Types

Enumeration types are particularly useful for creating a unique set of values that may be associated with a variable. The compiler reports an error if you attempt to assign a value that's not part of the declared set of legal values. For example, given:

enum {red,blue,green,yellow} colour;

enum {bright,medium,dark} intensity;

a good compiler would issue warnings for all the type conflicts and misleading usages shown below:

colour = yellow; /* OK */

colour = bright; /* type conflict */

colour = 1; /* type conflict */

intensity=bright+medium; /*misleading */

Page 53: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/53

…Enumeration Types

Constant names in an enum declaration receive a default integer value based on their position in the list. These start at zero and go up by one with each new name.

The default values can be overridden by specifying other values. If you specify a value, all subsequent default values begin at one more than the last defined value. E.g.:

enum {APPLE,ORANGES=8,LEMONS,GRAPES=5,MELONS};

is the same as:enum {APPLE=0,ORANGES=8,LEMONS=9,GRAPES=5,MELONS=6};

Page 54: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/54

The void Data Type

The type specifier void indicates that no value is available.

Variables and constants cannot be declared with this type.

void can be used for the following purposes: • void in Function Declarations• Expressions of type void• Pointers to void

Page 55: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/55

void in Function Declarations

A function with no return value has the type void. E.g. in the function prototype:

void perror( const char * );This allows the compiler to detect any attempt to use the return value from perror as a mistake.

The other purpose of void is to declare a generic pointer which is automatically cast to the correct type when it s assigned a pointer value (ANSI standard).

Page 56: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/56

CONTROL FLOW

Recap: C provides the fundamental flow-control constructions

required for well-structured programs, including:• decision making (if);• looping with the termination test at the top (while, for) or at the bottom (do);

• and selecting one of a set of possible cases (switch).

Page 57: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/57

Conditional Branching

This is the most basic control feature of any language. In C, conditional execution is performed with the if and else keywords:

If the expression is ‘true’ (non-zero), the next statement is executed. If the else clause is present, the statement following the else is executed whenever the if expression is ‘false’ (0).

if ( expression

statementelse

statement)

Page 58: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/58

Comparison Expressions

Typically, the expression of an if statement is a comparison between two values:

< less than> greater than<= less than or equal>= greater than or equal== equal to!= not equal to

The value of a relational expression is an integer, either 1 (true) or 0 (false). For example:(-1 < 0) yields 1, (0 > 1) yields 0, (0 == 0) yields 1

Page 59: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/59

BUG ALERT - Confusing = with ==

One of the most common mistakes made by beginners and experts alike is to use the assignment operator (=) instead of the equality operator (==). E.g.:

if (j = 5) do_something();

which should have been:if (j == 5) do_something();

Note that the first version is syntactically legal since all expressions yield a value. The value of the expression j=5 is 5. As this is non-zero, it is accepted as ‘true’ and do_something() is always invoked.

Page 60: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/60

switch

When there are many paths on a program, if-else branching can become so convoluted that it is difficult to follow. These situations are prime candidates for use of the switch statement. E.g.:int switch_example(char input_arg) { switch (input_arg) { case ’D': return 1; case ’U': return 2; case ’N': return 3; case ’C': return 4; default: return -1; } /* end of switch */} /* end of switch_example */

The expression immediately after the switch keyword must be enclosed in parentheses and must be an integral expression. I.e., it can only be char, short, int or long.

Page 61: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/61

...switch

An important feature of the switch statement is that program flow continues from the selected case label until another control-flow statement or the end of the switch statement is reached.

That is, the any statements following the selected case label are executed until a break, goto or return statement appears.

For example:…

Page 62: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/62

...switch

typedef enum{ ERR_INPUT_VAL, ERR_OPERAND, ERR_OPERATOR, ERR_TYPE} ERROR_SET;ERROR_SET error_code...switch (error_code) { case ERR_INPUT_VAL: printf("Error: Illegal input value\n"); break; ... case ERR_TYPE: printf("Error: Incompatible data\n"); break; default: printf(”Error: Unknown error code%d\n",error_code);; break; /* Not strictly necessary but */ /* good programming practice. */}

Page 63: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/63

while

The statement, which is often a compound statement, is called the body of the while loop.

while ( expression statement)

Page 64: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/64

do...while

There are certain situation where you may need to execute the body at least one. When these situations occur, the do...while statement should be used. For example:

do { ch = getchar(); if (ch == ‘ ‘) num_of_spaces++; } while (ch != ‘\n’);

dostatementwhile(expression);

Page 65: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/65

for

The for statement is designed as shorthand for a particularly common looping situation• when you need to initialise one or more variables before

entering the loop, and• When you need to change the values of one or more

variables each time through the loop.

statement

expression1 expression2

expression3

)

; ;for (

Page 66: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/66

...for

The for statement operates as follows:1. Firstly expression1 is evaluated - usually assignment(s);2. then expression2 is evaluated. This is the conditional part

of the statement;3. if expression2 is false, program control exits the for

statement, otherwise statement is executed;4. after statement is executed, expression3 is evaluated and

then for loops back to test expression2 again - i.e. repeats from step (2).

statement

expression1 expression2

expression3

)

; ;for (

Page 67: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/67

...for

The easiest way to understand the for statement is to compare it to a while statement. For example:

for (expr1;expr2;expr3) statement;

is the same as:

expr1;while (expr2){ statement; expr3;}

Page 68: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/68

Null Statement

The syntax of the for loop allows the omission of not only the expressions within the for (...;...;...)but also the body of the for loop.

This is useful when the loop's work is being done by the expressions. For example:

void skip_spaces(void) { int c; for ( c=getchar(); isspace(c); c=getchar() ) ; /* Null statement */ ungetc(c,stdin); /* put the non-space character */ /* back into the input buffer. */}

Page 69: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/69

BUG ALERT - Misplaced semicolons

A common mistake is to place a semicolon immediately after a control flow statement. For instance:if (j == 1); j = 0;

is as:

if (j == 1) ; /* Null statement */j = 0; /* j _always_ gets assigned 0 */

Page 70: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/70

break

As well as its use in a switch a break can be used to force an immediate exit from while, do and for loops.

In this context, break statements should be used sparingly since they force program control to jump discontinuously to a new place and too many can make a program difficult to follow.

for (cnt=0; cnt<50; cnt++) { c=getchar(); if (c==’\n') break; else /* process the character */}

Page 71: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/71

continue

The continue statement provides a means for returning to the beginning of a loop earlier than normal.

It is particularly useful when you want to by-pass the remainder of the loop for some reason. For example, the code to 'make' an integer from input characters providing those characters are numeric could be written as:

while ((c = getchar()) != ’\n') { if (isdigit(c) == 0) continue; num = num * 10; num = num + (c - '0');}

Page 72: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/72

Alternative ways to ‘make’ an integer

for (c=getchar();isdigit(c);c=getchar()){ num = num * 10; num = num + (c - '0'); }

/* or */ c = getchar(); while (isdigit(c)) { num = num * 10; num = num + (c - '0'); c = getchar(); }/* or... */

Page 73: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/73

Operators and Expressions

C's rich set of operators is one of its distinguishing characteristics.

An expression consists of one or more operands and zero or more operators.

There are 4 main types of expression:

• Constant Expressions - containing only constant values.

• Integral Expressions - produce a result that has one of the integer types.

• Float Expressions - produce a result that has one of the floating point types.

• Pointer Expressions - are expressions that evaluate to an address value.

Page 74: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/74

Constant Expression

Contain only constant values. E.g:55 * 6 + 13/3.0'z'

Page 75: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/75

Integral Expressions

Produce a result (after all automatic and explicit type conversions) that has one of the integer types. E.g. (where j and k are integers):

jj/k + 33 + (int) 5.0/k

Page 76: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/76

Float Expressions

Produce a result that has one of the floating point types. E.g. (where j is an int, f is a float and d is a double):

f(float)jf/d + 31.0/CLOCKS_PER_SEC(double)3/4 + d

Page 77: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/77

Pointer Expressions

These are expressions that evaluate to an address value. They include expressions containing pointer variables, & operator, string literals and array names. If p is a pointer and j is an int, the following are pointer expressions:

p&jp + 1“a string literal”(char *) 0x000ffff

Page 78: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/78

Precedence and Associativity of C Operators

Class of Operator Operators in that Class Associativity Precedenceprimary () [] -> . Left-to-right HIGHEST

unary

Cast operatorsizeof

& (address of)* (dereference)

- +~ ++ -- !

Right-to-left

multiplicative * / % Left-to-rightadditive + - Left-to-rightshift << >> Left-to-rightrelational < <= > >= Left-to-rightequality == != Left-to-rightbitwise AND & Left-to-rightbitwise exclusive OR ^ Left-to-rightbitwise inclusive OR | Left-to-rightlogical AND && Left-to-rightlogical OR || Left-to-rightconditional ? : Right-to-left

assignment= += -= *=

/= %= >>= <<=&= ^=

Right-to-left

comma , Left-to-right LOWEST

Page 79: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/79

Precedence and Associativity of C Operators

Class of Operator Operators in that Class Associativity Precedence

primary () [] -> . Left-to-right HIGHEST

unary

Cast operatorsizeof

& (address of)* (dereference)

- +~ ++ -- !

Right-to-left

multiplicative * / % Left-to-rightadditive + - Left-to-rightshift << >> Left-to-rightrelational < <= > >= Left-to-rightequality == != Left-to-rightbitwise AND & Left-to-rightbitwise exclusive OR ^ Left-to-right

bitwise inclusive OR | Left-to-rightlogical AND && Left-to-rightlogical OR || Left-to-rightconditional ? : Right-to-left

assignment= += -= *=

/= %= >>= <<=&= ^=

Right-to-left

comma , Left-to-right LOWEST

Page 80: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/80

Precedence and Associativity of C Operators

Class of Operator Operators in that Class Associativity Precedenceprimary () [] -> . Left-to-right HIGHEST

unary

Cast operatorsizeof

& (address of)* (dereference)

- +~ ++ -- !

Right-to-left

multiplicative * / % Left-to-rightadditive + - Left-to-rightshift << >> Left-to-rightrelational < <= > >= Left-to-rightequality == != Left-to-rightbitwise AND & Left-to-rightbitwise exclusive OR ^ Left-to-right

bitwise inclusive OR | Left-to-rightlogical AND && Left-to-rightlogical OR || Left-to-rightconditional ? : Right-to-left

assignment= += -= *=

/= %= >>= <<=&= ^=

Right-to-left

comma , Left-to-right LOWEST

Page 81: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/81

Precedence and Associativity of C Operators

Class of Operator Operators in that Class Associativity Precedenceprimary () [] -> . Left-to-right HIGHEST

unary

Cast operatorsizeof

& (address of)* (dereference)

- +~ ++ -- !

Right-to-left

multiplicative * / % Left-to-rightadditive + - Left-to-rightshift << >> Left-to-rightrelational < <= > >= Left-to-rightequality == != Left-to-rightbitwise AND & Left-to-rightbitwise exclusive OR ^ Left-to-right

bitwise inclusive OR | Left-to-rightlogical AND && Left-to-rightlogical OR || Left-to-rightconditional ? : Right-to-left

assignment= += -= *=

/= %= >>= <<=&= ^=

Right-to-left

comma , Left-to-right LOWEST

Page 82: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/82

Precedence and Associativity of C Operators

Class of Operator Operators in that Class Associativity Precedenceprimary () [] -> . Left-to-right HIGHEST

unary

Cast operatorsizeof

& (address of)* (dereference)

- +~ ++ -- !

Right-to-left

multiplicative * / % Left-to-rightadditive + - Left-to-rightshift << >> Left-to-right

relational < <= > >= Left-to-rightequality == != Left-to-rightbitwise AND & Left-to-rightbitwise exclusive OR ^ Left-to-right

bitwise inclusive OR | Left-to-rightlogical AND && Left-to-rightlogical OR || Left-to-rightconditional ? : Right-to-left

assignment= += -= *=

/= %= >>= <<=&= ^=

Right-to-left

comma , Left-to-right LOWEST

Page 83: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/83

Precedence and Associativity of C Operators

Class of Operator Operators in that Class Associativity Precedenceprimary () [] -> . Left-to-right HIGHEST

unary

Cast operatorsizeof

& (address of)* (dereference)

- +~ ++ -- !

Right-to-left

multiplicative * / % Left-to-rightadditive + - Left-to-rightshift << >> Left-to-rightrelational < <= > >= Left-to-rightequality == != Left-to-right

bitwise AND & Left-to-rightbitwise XOR ^ Left-to-rightbitwise OR | Left-to-rightlogical AND && Left-to-rightlogical OR || Left-to-rightconditional ? : Right-to-left

assignment= += -= *=

/= %= >>= <<=&= ^=

Right-to-left

comma , Left-to-right LOWEST

Page 84: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/84

Precedence and Associativity of C Operators

Class of Operator Operators in that Class Associativity Precedenceprimary () [] -> . Left-to-right HIGHEST

unary

Cast operatorsizeof

& (address of)* (dereference)

- +~ ++ -- !

Right-to-left

multiplicative * / % Left-to-rightadditive + - Left-to-rightshift << >> Left-to-rightrelational < <= > >= Left-to-rightequality == != Left-to-rightbitwise AND & Left-to-rightbitwise exclusive OR ^ Left-to-right

bitwise inclusive OR | Left-to-right

logical AND && Left-to-rightlogical OR || Left-to-rightconditional ? : Right-to-left

assignment= += -= *=

/= %= >>= <<=&= ^=

Right-to-left

comma , Left-to-right LOWEST

Page 85: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/85

Precedence and Associativity of C Operators

Class of Operator Operators in that Class Associativity Precedenceprimary () [] -> . Left-to-right HIGHEST

unary

Cast operatorsizeof

& (address of)* (dereference)

- +~ ++ -- !

Right-to-left

multiplicative * / % Left-to-rightadditive + - Left-to-rightshift << >> Left-to-rightrelational < <= > >= Left-to-rightequality == != Left-to-rightbitwise AND & Left-to-rightbitwise exclusive OR ^ Left-to-right

bitwise inclusive OR | Left-to-rightlogical AND && Left-to-rightlogical OR || Left-to-right

conditional ? : Right-to-leftassignment

= += -= *=/= %= >>= <<=

&= ^=Right-to-left

comma , Left-to-right LOWEST

Page 86: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/86

Precedence and Associativity of C Operators

Class of Operator Operators in that Class Associativity Precedenceprimary () [] -> . Left-to-right HIGHEST

unary

Cast operatorsizeof

& (address of)* (dereference)

- +~ ++ -- !

Right-to-left

multiplicative * / % Left-to-rightadditive + - Left-to-rightshift << >> Left-to-rightrelational < <= > >= Left-to-rightequality == != Left-to-rightbitwise AND & Left-to-rightbitwise exclusive OR ^ Left-to-right

bitwise inclusive OR | Left-to-rightlogical AND && Left-to-rightlogical OR || Left-to-rightconditional ? : Right-to-left

assignment

= += -= *=/= %= >>=

<<=&= ^=

Right-to-left

comma , Left-to-right LOWEST

Page 87: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/87

Precedence and Associativity of C Operators

Class of Operator Operators in that Class Associativity Precedenceprimary () [] -> . Left-to-right HIGHEST

unary

Cast operatorsizeof

& (address of)* (dereference)

- +~ ++ -- !

Right-to-left

mutliplicative * / % Left-to-rightadditive + - Left-to-rightshift << >> Left-to-rightrelational < <= > >= Left-to-rightequality == != Left-to-rightbitwise AND & Left-to-rightbitwise exclusive OR ^ Left-to-right

bitwise inclusive OR | Left-to-rightlogical AND && Left-to-rightlogical OR || Left-to-rightconditional ? : Right-to-left

assignment= += -= *=

/= %= >>= <<=&= ^=

Right-to-left

comma , Left-to-right LOWEST

Page 88: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/88

Precedence and Associativity

The properties of precedence and associativity affect how operands are attached to operators. Operators with higher precedence have their operators bound, or grouped, to them before operators of lower precedence.

In cases where operators have the same precedence, associativity determines the order in which operands are grouped with operators. For example, The plus (+) and minus (-) operators have the same precedence and are both left-to-right associative:a + b - c; /* Add a to b, then subtract c */

The assignment operator (=) is right associative:a = b = c; /* Assign c to b, then assign b to a */

Page 89: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/89

Order of Evaluation

An important point to understand is that precedence and associativity have little to do with the order of evaluation. The order of evaluation refers to the actual order in which the compiler evaluates operators.

Note that this is independent from the order in which the compiler groups operands to operators. For most operators, the compiler is free to evaluate sub-expressions in any order it pleases. For example:

(2 + 3) * 4 could generate:2 + 3 and then * by 4, or

2 * 4 and then 3 * 4 and then add The order of evaluation can have a critical impact on

expressions that contain side effects or the reorganisation of expressions can give rise to overflow conditions.

Page 90: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/90

BUG ALERT - Integer Division and Remainder

If both operands of / are positive integers any fractional part is truncated:

5/2 -> 21/3 -> 0

If either operand is negative, however, the compiler is free to round the result either up or down:

5/-2 -> -2 or -3-1/3 -> 0 or -1

The sign of the result of a remainder operation has the same sign as the left operand:

-5%2 -> -15%-2 -> 1

Page 91: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 252223_06/91

C Style - Bibliography

C and C++ Style Guides<http://www.chris-lott.org/resources/cstyle/>…

Recommended C Style and Coding Standards (HTML)…<indhill-cstyle.html> [<http://tinyurl.com/dpv4v>]‘C’ Style Guide and Programming Guidelines (PDF)…<Peter_CStyleGuide.pdf> [<http://tinyurl.com/z2lxn>]

Recommended C Style and Coding Standards (PDF) <http://www.literateprogramming.com/indhill-cstyle.pdf>

Page 92: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

52.223 Low Level Programming Lecturer: Duncan Smeed

Overview of the C Programming Language

Part 3

Page 93: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/93

Arithmetic Assignment Operators

In addition to the simple assign operator =, C supports 5 additional assignment operators that combine assignment with each of the arithmetic operations. E.g.:

j = j * 5;can be written as:

j *= 5; Why have such operators?

• to avoid spelling mistakes and make code easier to read and to write, e.g. when referencing structure and union members

• compiler may produce more efficient low level code

Page 94: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/94

…Arithmetic Assignment Operators

Another feature of these operators is that if the 1value (left hand operand) contains side effects, the side effects occur only once.

Also, the assign operators have relatively low precedence, so:

j *= 3+4 j *= (3+4) j = j * (3+4)

notj = (j * 3) + 4

Page 95: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/95

Increment and Decrement Operators

The increment (++) and decrement (--) operators are unary and their operands must be a scalar lvalue.

It is legal to ++ or -- pointer variables, but the meaning of adding (subtracting) one to a pointer is different from adding one to an arithmetic value.

Precedence of ++ and --• ++ and -- have the same precedence, but bind

from right to left.

Page 96: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/96

Forms of ++ and --

Postfix increment : a++• get value of a, then increment a

Postfix decrement : a--• get value of a, then decrement a

Prefix increment : ++a• increment a, then get value of a

Prefix decrement : --a• decrement a, then get value of a

Page 97: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/97

BUG ALERT - Side Effects

The ++, -- and assignment operators cause side effects. I.e. they yield a value but the value of the variable is also changed.

The order in which the side effects occur is unpredictable - they are implementation dependent (i.e. non-portable). E.g., given:

x = j * j++;Is j evaluated first or is j++ evaluated first?

The problem also occurs in function calls such as foo(a,a++) as C does not guarantee the order in which arguments are evaluated.

To prevent such side effects avoid use of an affected variable anywhere else when using a side effect operator. E.g.:

x = j * j; /* unambiguous version */j++; /* of the above example.*/

Page 98: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/98

Comma Operator

The comma operator allows you to evaluate two or more distinct expressions whenever a single expression is allowed. The result is the value of the right most operand. I.e. :

a,b evaluate a, evaluate b, result is b. This operator is one of the few for which the order of evaluation

is specified. The compiler must evaluate the left hand operand first.

Over-use of the comma operator can lead to confusing code. By convention, therefore, it is used primarily in the first and last expressions of a for statements. Caveat : try to avoid the temptation of fitting as much as possible into the for expressions.

Page 99: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/99

…Comma Operator

Over-use of the comma operator can lead to confusing code. By convention, therefore, it is used primarily in the first and last expressions of a for statements. Caveat : try to avoid the temptation of fitting as much as possible into the for expressions.

for (c=getchar(),j=0 ; C! = EOF ;\ c=getchar(),putchar(c),j++) if (j% interval == 0) printf(”\n");

While the above is compact, it is not better since it is harder to read. You should be wary about using multiple assignments in the 3rd expression.

Page 100: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/100

Relational Operators

Relational operators have lower precedence than arithmetic operators. Thus:a+b*c < d/f (a+(b*c)) < (d/f)

Among these operators >, <, >= and <= have the same precedence.

The == and != operators have lower precedence.

They all have left-to-right associativity.

Page 101: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/101

BUG ALERT - Side effects in relational expressions

Relational operators must cause the compiler to evaluate operands from left to right.

Furthermore, a compiler evaluates only as much of a relational expression as it needs to determine the result.

In many cases this means that the entire expression is not evaluated. E.g.:

if (a < b) && (c == d++)

Page 102: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/102

Cast Operator

The cast operator enables you to convert a value to a different type. Remember that 3/2 gives 1 as a result so (float)3/2 promotes 3 to a F-P number to ensure that the result of the division is not truncated.

Another use of the cast operator is to convert function arguments. E.g. some runtime library functions such as pow( or sqrt() expect arguments that are of type double so if your variables are integers you need to cast them to double before you pass them as arguments:

int j, k;...

k = (int) pow(2.0, (double) j);Note that the cast to int prior to assignment to k is actually unnecessary as an automatic conversion of the RH expression of an assignment takes place. However, the explicit cast serves as an important documentation aid.

Page 103: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/103

sizeof Operator In general, the sizeof operator is used to find the size of

aggregate data objects such as arrays and structures and is often used to aid the portability of code. It accepts two types of operands: an expression or a data type.

An expression is not evaluated but sizeof returns the number of bytes that the result occupies in memory:

sizeof(3 + 5) yields the size of an intsizeof(3.0 + 5) yields the size of a double

If the operand is a data type then the result is the length in bytes of objects of that data type:

sizeof(char) 1 in all implementationssizeof(short) 2 in some implementationssizeof(int) 4 in some implementationssizeof(int *) 4 in some implementations

Page 104: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/104

?: Conditional Operator

The ?: operator is the only ternary (3 operand) operator and is really just shorthand for a common type of if...else expression:

if (x < y)z = x;

elsez = y;

can be written as:z = ((x < y) ? x : y);

The first operand must have scalar type and the 2nd and 3rd operands represent the final value of the expression and these must be compatible according to the normal conversion rules.

Page 105: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/105

... ?: Conditional Operator

This operator can make a statement difficult to read and so should be used carefully.

However, there are situations where it can be used to good effect, particularly in printf() statements:

printf ("...", j > 0 ? j : k);

This form avoids the need to generate redundant code by duplicating printf()s.

Page 106: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/106

Arrays and Pointers

Arrays and pointers are closely related in C. An array is a collection of identically-typed variables stored

contiguously in memory. Subscripts into arrays begin at 0, not 1, which means that the

highest legal subscript is one less than the array's size. The syntax of an array declaration is:

array

size

[ ]type

specifier

array

name

initialiser

Page 107: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/107

...Arrays and Pointers

Examples:

array

size

[ ]type

specifier

array

name

initialiser

int daily_temp [365];static int powers_of_two [8] = {1,2,4,8,16,32,64,128};

It is incorrect to enter more initialisation values than there are elements in the array.

If there are fewer initialisation values than elements, the remaining elements are initialised to zero.

When providing initial values it is permissible to omit the array size. For instance: static char vowels [] = {'a','e','i','o','u'};

Page 108: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/108

Pointer Arithmetic - Addition

C allows you to add and subtract integers to and from pointers. For example:

p + 3

is legal and causes the address returned to point to 3 objects after the object that p points to.

Note that rather than simply adding 3 to p, the compiler multiplies (scales) the 3 by the size of the object that p points to.

Page 109: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/109

Pointer Arithmetic - Subtraction

It is legal to subtract one pointer value from another, provided that they point to the same type of object.

Pointer subtraction yields an integral value that represents the number of objects between the two pointers. Examples:

long *p1, *p2; int j; char *p3;...p2 = p1 + 4; /* legal */j = p2 - p1; /* legal: j = 4 */j = p1 - p2; /* legal: j = -4 */p3 = p1 - 1; /* illegal: different pointer types */j = p3 - p1; /* illegal: different pointer types */

Page 110: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/110

Null Pointer

C supports the notion of a null pointer - a pointer that is guaranteed not to point to a valid object. A null pointer is any pointer assigned the integral value zero. E.g.:

char *p;

p = 0; /* make p a null pointer */ In this one case - assignment of 0 - you do not need to cast the

integral expression to the integral expression to the pointer type. Null pointers are particularly useful in control-flow statements

since the zero-valued pointer evaluates to false, whereas all other pointer values evaluate to true. E.g.:while (p) { /*iterate until p is a null pointer*/

...}

Page 111: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/111

Accessing Array Elements Through Pointers

One way to access array elements is to enter the array name followed by a subscript. Another way is via pointers. Given:

short ar[4];short *p;p = &ar[0];

then

*p ar[0] Due to the scaled nature of pointer arithmetic

*p+3 ar[3]in fact

*p+e ar[e]

Page 112: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/112

...Accessing Array Elements Through Pointers

Furthermore, if an array name is not followed by a subscript then it is interpreted as a pointer to the initial element of the array. Thus:

ar &ar[0]

Therefore:

ar[n] is the same as *(ar + n)

Because of this inter-relationship, pointer variables and array names can be used interchangeably to reference array elements.

It is important to remember, though, that the values of pointer variables may change but array names cannot.

Page 113: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/113

Differences Between Pointers and Arrays

An array name is not a variable - it refers to the address of the array variable.

You cannot change the address of variables. This means that an array name alone cannot appear on the LHS of an assignment statement. This difference between pointer and arrays is an important distinction to grasp. For instance:p = ar; /*legal: same as p=&ar[0] */ar = p; /*illegal: you may not assign*/ /*to an array address */&p = ar; /*illegal: you may not assign*/ /*to a pointer address */ar++; /*illegal*/ar[1]=*(p+3); /*legal*/p++; /*legal*/

Page 114: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/114

Passing Arrays as Function Arguments

In C, an array name that appears as a function argument is interpreted as the address of the first element of the array. E.g.:

x = func(array); x = func(&array[0]); On the receiving side, you need to declare the argument as a

pointer to the initial element of the array. I.e.:

func (short *ar){

...}

func (short ar[]){

...}

or

In terms of readability however, the 2nd version may have the edge since it emphasises that the object being passed is the base address of an array.

Page 115: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/115

...Passing Arrays as Function Arguments

The choice of declaring a function argument as an array or a pointer has no effect on the compiler's operation.

To the compiler ar simply points to a short - it is not an array.

Because of the pointer-array equivalence you can still access ar as if it were an array.

But you cannot find out the size of the array passed as the argument by using the sizeof operator on it.

Page 116: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/116

...Passing Arrays as Function Arguments

Because of this inability to determine the size of an array in the called function, it is often a good idea to pass the size of the array along with the base address. This enables the called function to check array boundaries:

void foo (int array[], int array_size)

{

...

} You can obtain the number of elements in an array by simply

dividing the size of the array by the size of each element:

foo (demo, sizeof(demo)/sizeof(demo[0]));

Page 117: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/117

Strings A very common use of array is to store strings. A string is an

array of characters terminated by a null character - '\0'. A string constant (literal) is a series of characters enclosed in

double quotes and has an array of char data type. A compiler automatically appends a null character to the string; this means it is one character longer than it appears. E.g.:

static char str [] = "some text"; If an array size is given it must be long enough to hold all the

characters including the null. E.g.:static char str [10] = "some text";

A char pointer can also be initialised with a literal. E.g.:char *ptr = "some text";

This is subtly different from the earlier examples as itcreates an additional variable for the pointer.

Page 118: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/118

Strings vs Characters

It is important to recognise the differences between string constants and character constants. I.e.:char ch = 'a'; /* 1 byte allocated for 'a' */char *ps = "a"; /* 2 bytes allocated for... */ /* ..."a", plus ? bytes for... */ /* ...pointer ps */

It is legal to:*ps = 'a'; /* OK */

but not:*ps = "a"; /* Illegal */

Likewise:ps = "a"; /* OK */ps = 'a'; /* Illegal */

Page 119: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/119

Three versions of a string copy function

strcopierV1 (char d[], char s[]) {for (int i = 0; s[i]; ++i)

d[i] = s[i];d[++i] = '\0';

}strcopierV2 (char *d, char *s) {

for (int i = 0; *(s + i); ++i)*(d + i) = *(s + i);

d[++i] = '\0';}strcopierV3 (char *d, char *s) {

while (*d++ = *s++) ;

}

Page 120: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/120

Multi-dimensional Arrays

An array of arrays is declared with consecutive pairs of brackets. For instance:

int x[3][5] Such multi-dimensional arrays are stored in row-major order,

which means that the last subscript varies fastest. E.g., given the above example:

x[0][0] x[0][1] x[0][2] ...x[1][0] x[1][1] x[1][2] ......

If you specify fewer subscripts than there are dimensions, the result is a pointer to the base type of the array. E.g.:

x[1] &x[1][0]The result is a pointer to an int.

Page 121: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/121

Initialising a Multi-dimensional Array

When initialising a multi-dimensional array, you may enclose each row in braces - { and }. If there are too few initialisers, the extra elements in the row are initialised to zero. So:

static int x[3][5] = {{1,2,3,4,5},{6}}

Here, only the first two rows are initialised, the second row has only the first element initialised. Therefore, the array has the following layout:

1 2 3 4 56 0 0 0 00 0 0 0 0

Page 122: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/122

...Initialising a Multi-dimensional Array

The first size specification may be omitted as it can be determined by the number of initialisers present.

int y[][3][2] = {

{{1,1},{0,0},{1,1}},

{{0,0},{1,2},{0,1}}

}

results in a 2-by-3-by-2 array because there are 12 initialisers. Note that:

int z[][] = {1,2,3,4,5,6};

is illegal since the compiler has no way of knowing whether to create a 2-by-3 array or a 3-by-2 array.

Page 123: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 352223_07/123

BUG ALERT - Comma Operator Error

One of the most common mistakes made by new C programmers is to use a comma to separate subscripts:

x[1,2] = 0;

instead of

x[1][2] = 0;

Page 124: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

52.223 Low Level Programming Lecturer: Duncan Smeed

Overview of the C Programming Language

Part 4

Page 125: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 452223_08/125

Structures and Unions

Arrays deal with groups of identically typed variables whereas structures deal with groups of mixed types (aggregates). A union, another aggregate type, enables you to interpret the same memory locations in different ways.

The elements in a structure, called fields or members, have names instead of subscript values. For example:

struct vitalstat {char vs_name [19], vs_ssnum [11];short vs_day, vs_month, vs_year;

};struct vitalstat vs;

vitalstat is a tag name for a structure template. It represents a new, user-defined, data type. Actual variable declarations, such as vs, use this tag name.

Page 126: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 452223_08/126

...Structures and Unions

It can sometimes be useful to declare a single structure type (without a tag name) when used in one place only as in:

struct { ... } vs; A tag name and variables can be declared together:

struct vitalstat { ... } vs, *pvs, vsa [10];

A final, preferable, method is to define a typedef name. E.g.:typedef struct {

... } VITALSTAT;

Typically, such structure definitions are placed in a header file where they can be accessed by multiple source files. To declare a variable using this technique use:

VITALSTAT vs;

Page 127: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 452223_08/127

Initialising Structures

Structures can be initialised in the same manner as arrays - the list of initialisers, enclosed in braces.

Each initialiser should agree in type with the corresponding field in the structure. E.g.:

VITALSTAT vs = {"George Smith","002340671",14,10,1954

};

Page 128: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 452223_08/128

Initialising Specific Members

The C99 standard allows the explicit association of an initialiser with a specific member by prefixing a member designator with an equal sign to the initialiser:VITALSTAT vs = { .vs_ssnum = "197345678",

.vs_month = 10, 1954 };

An initialiser with no designator is associated with the first member, if it is the first initialiser, or with the member that follows the last member initialised.

Page 129: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 452223_08/129

Referencing Structure Members

There are two methods of accessing structure fields, depending on whether you have the structure itself or a pointer to the structure.

Each method uses a special operator. Given the structure itself, you can enter the structure

name and field name separated by the dot (.) operator. E.g.:

vs.vs_month = 11;

vs.vs_day = 21;

vs.vs_year = 1988;

Page 130: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 452223_08/130

...Referencing Structure Members

The other way to reference a structure member is indirectly through a pointer to the structure. Given the following declaration:

VITALSTAT *pvs; To reference a member through the pointer pvs the

right arrow operator () is used:

pvs->vs_day This operator is actually shorthand for dereferencing

the pointer and using the dot operator. I.e.:

pvsvs_day (*pvs).vs_day

Page 131: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 452223_08/131

Unions

Unlike structure members the members of a union all share the same location in memory; i.e. all members of a union start at the same address.

Thus, there can be many members, but only one member can contain a value at any given time.

Unions are an easy way for programmers to use a location in memory in different ways.

Page 132: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 452223_08/132

Defining Union Types The definition of a union is formally the same as that

of a structure. E.g.:union [tag_name] {member_declaration_list};

Example:union Data {int i; double x; char s[16]};

An object of this type can store an integer, a floating-point number, or a short string. Example:

union Data var, myData[100];Defines var as an object of type union Data, and myData as an array of 100 elements of type union Data.

A union is at least as big as its largest member. So:sizeof(var) yields 16, sizeof(myData) yields 1600

Page 133: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 452223_08/133

Initialising Unions

Unions can be initialised in the same manner as structures - with an initialisation list.

However, this list can contain only one initialiser. As for structures, C99 allows the use of a member

designator to override the default - the first - member and specify which member of the union is being initialised. E.g.:union Data var1 = {77}, var2 = {.s="Hello"}, myData[100] = {{.d=0.5}, {1}};

Page 134: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 452223_08/134

Referencing Union Members

Union member access is the same as structure member access.

However, when the value of a union member is changed all members of the union are modified.

The programmer is responsible for making sure that the contents of a union object are interpreted correctly. E.g., the following code uses a union to illustrate the storage of a double value in memory:

var.d = 1.25;for (int i = sizeof(double)-1; i >= 0; --i) printf("%02X ",(unsigned char)var.s[i]);

Page 135: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 452223_08/135

Bit-Fields

Members of structures or unions can also be bit-fields. A bit-field is an integer variable of specific bit width. Bit-fields may be packed into a single machine word

giving very compact storage of small units of data. Advantage over bitwise operators: handling of bits by

name. The declaration of a bit-field has the form:

type [member_name] : width ;

Page 136: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 452223_08/136

Syntax of Bit-Fields

type [member_name] : width ;type

An integer type such as int, signed int, unsigned int.

member_nameThe name of the bit-field, which is optional. Nameless bit-fields serve only as padding to align subsequent bit-fields to a certain position in a machine word.

widthThe number of bits in the bit-field. A constant integer expression whose value is non-negative; must be less than or equal to the bit-width of the specified type.

Page 137: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 452223_08/137

Example of the use of Bit-Fields

The following example may result in the structure struct Date being packed into a 32-bit word:

struct Date {unsigned int day : 5;unsigned int month : 4;signed int year : 22;_Bool isDST : 1;

}

An object of type struct Date can be initialised in the normal way:struct Date birthday = {14,10,1954};

Page 138: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 452223_08/138

Restrictions on the use of Bit-Fields

Unlike other structure members, bit-fields generally do not occupy an addressable location in memory.

Thus you cannot apply the address operator (&) or the offsetof macro to a bit-field.

Also, arrays of bit-fields cannot be declared.

Page 139: 52.223 Low Level Programming Lecturer: Duncan Smeed Overview of the C Programming Language Part 1

Overview of the C Programming Language - Part 452223_08/139

offsetof Macro

ANSI C provides a method of determining the byte offset of any non-bit-field structure member. The macro takes two arguments: the type of the structure and the member name:

offsetof(type,member_name)and expands to an integral byte offset of type size_t as defined in the stddef.h header file.