26
TECHNICAL UNIVERSITY OF CLUJ-NAPOCA Faculty of Automation and Computer Science Computer Science Department Lecture Notes on C Computer Programming Marius Joldo¸ s 2005

Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

TECHNICAL UNIVERSITY OF CLUJ-NAPOCAFaculty of Automation and Computer Science

Computer Science Department

Lecture Notes on C

Computer Programming

Marius Joldos

2005

Page 2: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code
Page 3: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

Contents

1 C Crash Course 31.1 C Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . 3

1.1.1 History of C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . 31.1.2 Characteristics of C . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 31.1.3 C Program Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 41.1.4 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . 51.1.5 Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . 71.1.6 Arithmetic Operations . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 71.1.7 Comparison Operators . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . 81.1.8 Logical Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . 81.1.9 Order of Precedence . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 81.1.10 Conditionals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 81.1.11 Looping and Iteration . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . 101.1.12 Arrays and Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . 121.1.13 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . 131.1.14 Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 141.1.15 Defining New Data Types . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 151.1.16 Unions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . 151.1.17 Type-Casting or Coercion . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . 161.1.18 Enumerated Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . 161.1.19 Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . 161.1.20 More on C Preprocessor . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . 20

1.2 C Language Keywords . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . 211.3 Special Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . 221.4 Operator Precedence and Associativity Rules in C / C++ . .. . . . . . . . . . . . . . . . . . . . . . . . 221.5 Some C header files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . 231.6 A Strange Way to Write C Code . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 23

1

Page 4: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

Contents

2

Page 5: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1 C Crash Course

1.1 C Basics

There are many high level languages. PASCAL, for example is highly disciplined and structured. C is much more flexibleand it is this freedom the chsracteristic which gives C much more power that experienced users can employ.

1.1.1 History of C

The milestones in C’s development as a language are listed below:

• UNIX developed c. 1969 – DEC PDP-7 Assembly Language• BCPL – a user friendly OS providing powerful development tools developed from BCPL. Assembler tedious long

and error prone.• A new language “B” a second attempt. around 1970.• A totally new language “C” a successor to “B”. c. 1971• By 1973 UNIX OS almost totally written in “C”.

1.1.2 Characteristics of C

Some of C’s characteristics that define the language and alsohave lead to its popularity as a programming language willbe listed briefly below:

• Small size• Extensive use of function calls• Loose typing – unlike PASCAL• Structured language• Low level programming readily available• Pointer implementation - extensive use of pointers for memory, array, structures and functions.

Here are some reasons for which C still is a widely used professional language:

• It has high-level constructs.• It can handle low-level activities.• It produces efficient programs.• It can be compiled on a variety of computers.

Its main drawbackis that it haspoor error detectionwhich can make it off putting to the beginner. However diligence inthis matter can pay off since having learned the rules of C we can break them (this is not what we encourage you to do).Few languages allow this. If done properly and carefully leads to the power of C programming. As an extreme examplethe following C code shown in figure 1.2 of Addendum 1.6 is actually legal C code.That piece of code is taken from an international ObfuscatedC Code Contest. The standard for C programs was originallythe features set by Brian Kernighan. In order to make the language more internationally acceptable, an internationalstandard was developed, ANSI C1.

C Compilation Model

Figure 1.1 shows how C sources are turned into executable programs.

1American National Standards Institute

3

Page 6: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1 C Crash Course

Preprocessor

Compiler

Assembler

Linker

Source code

Assembly code

Object code

Executable code

Libraries

Figure 1.1: The C compilation model.

The Preprocessor

The Preprocessor accepts source code as input. Itinterprets special preprocessor directives denoted by#. It also removes all comments. For example:

• #include – includes contents of a namedfile. Files usually called header files. e.g#include <sting.h> – standard librarystring precessing file.#include <math.h> – standard librarymaths file.#include <stdio.h> – standard libraryI/O file.

• #define – defines a symbolic name or con-stant. which is replaced all over the text whereit appears by macro substitution. E.G.#define MAX_ARRAY_SIZE 100

C Compiler

The C compiler translates source to assembly code. The source code is received from the preprocessor.

Assembler

The assembler creates object code. On a UNIX system you may see files with a .o suffix (.OBJ on MSDOS) to indicateobject code files.

Link Editor

the link editor combines library functions referenced in source code or functions defined in other source files (withmain()) to create an executable file. It also resolves external variable references.

1.1.3 C Program Structure

A C program basically has the following form:

1. Preprocessor Commands2. Type definitions3. Function prototypes – declare function types and variables passed to function.4. Variables5. Functions

We must have amain()function. A functionhas the form:

type funct ion_name ( parameters ){

l o c a l va r i a b l e sC Statements

}

If the type definition is omitted C assumes that function returns an integer type.NOTE: This can be a source of problemsin a program.

/∗ Sample program∗ /main ( ){

p r i n t f ( " I l i k e C\ n " ) ;e x i t ( 0 ) ;

}

NOTE:

1. C requires a semicolon at the end of every statement.2. printf is a standard C function – called from main.3. \n signifies newline. Formatted output – more later.4. exit() is also a standard function that causes the program to terminate. Strictly speaking it is not needed here as it is

the last line ofmain() and the program will terminate anyway.

4

Page 7: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1.1 C Basics

Another example of printing statement:

p r i n t f ( " \ n a \ n b \ n c \ n " ) ;

The output of this would be:

abc

1.1.4 Variables

C has the following simple data types:NOTE: There isnoBooleantype in C – you shoulduse char, int or (bet-ter) unsigned char. Un-signed can be used with allchar andint types. To de-clare a variable in C, do:var_type list variables;e.g.

i n t i , j , k ;f l o a t x , y , z ;char ch ;

Every variable has anameand avalue. The name iden-tifies the variable, the valuestores data.

int integer numberfloat floating point (real) numberdouble double precision floating point

(real) numberchar a single byte of memory , enough to

hold a characterThese types can be modified using the keywordsshort , long , andunsigned . Thus we can have:unsigned int unsigned integershort int an integer, possibly of reduced sizeunsignedshort int

an unsigned integer, possibly of re-duced size

long int or justlong

an integer, possibly of increasedsize

long double a quadruple precision floating pointunsigned char byte

Table 1.1: C data types.

Every variable name in C must start with a letter, the rest of the name can consist of letters, numbers and underscorecharacters. C recognizes upper and lower case characters asbeing different – i.e it iscase-sensitive. Finally, you cannotuse any of C’s keywords likemain, while, switch etc. as variable names.

Global Variables

Local variables are declared within the body of a function, and canonly be used within that function. When anotherfunction is called, all required data is passed to it as arguments. Alternatively, a variable can be declaredglobally so itis available to all functions. Modern programming practicerecommendsagainstthe excessive use of global variablesbeacuse they can lead to poor program structure, and tend to clog up the available name space.A global variable declaration is located outside any of the program’s functions. This is usually done at the beginning ofthe program file, but after preprocessor directives. The variable is not declared again in the body of the functions whichaccess it, because then it would be considered local, and theglobal one will no longer be accessible to that function.Global variables are defined abovemain() in the following way:

short number1 , number2 ;i n t number3 , number4 ;char a l e t t e r ;main ( ){}

It is also possible to pre-initialize global variables using the "‘="’ operator for assignment.NOTE: The "‘="’ operator isthe same as "‘:= "‘ (assignment operator) is in Pascal. For example:

f l o a t fsum = 1 . 0 ;i n t isum = 3 ;char l e t t e r = ’Z ’ ;main ( ){}

This is the same as:

f l o a t fsum ;i n t isum ;

DSAL.105.AC.01.04-B2 5

Page 8: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1 C Crash Course

char a l e t t e r ;main ( ){

fsum = 5 . 0 ;isum = −3;a l e t t e r = ’E ’ ;

}

but is more efficient.C also allows multiple assignment statements using =, for example:a = b = c = d = 3 ;

which is the same as, but more efficient than:a = 3 ;b = 3 ;c = 3 ;d = 3 ;

This kind of assignment is only possible if all the variable in the statement are of thesame type. New type can be definedby usingtypedef keyword.E.g. Let us define two new types:real andletter. These new types can then be used inthe same way as the pre-defined C types:typedef r e a l double ;typedef l e t t e r char ;

Variables declared:r e a l fsum = 0 . 0 ;l e t t e r o t h e r l e t t e r ;

External Variables

A variable is called anexternalvariable when it is a global variable is declared in one file, and used by functions fromanother. In the functions which use it must be declared external. The declaration must be preceded by the keywordextern. The declaration is required to simplify the task of the compiler compiler: it can find the type of the variablewithout having to search through several source files for thedeclaration.Global and external variables can be of any legal type. They can be initialized, but the initialization takes place when theprogram starts up, before entry to the main function.

Static Variables

A staticvariable is local to a particular function. However, it is only initialized once – on thefirst call to that function.Also the value of the variable on leaving the function remains intact. On thenext callto the function the the static variablehas the same value as on leaving. To define a static variable simply prefix the variable declaration with the static keyword.For example:void mystat ( ) ; /∗ p r o t o t y p e f n ∗ /main ( ){

i n t i ;fo r ( i = 0 ; i < 5 ; ++ i )

mystat ( ) ;}mystat ( ){

i n t auto_var = 0 ;s t a t i c i n t s t a t i c _ v a r = 0 ;p r i n t f ( " au to = %d , s t a t i c = %d \ n " ,

auto_var , s t a t i c _ v a r ) ;++auto_var ;++s t a t i c _ v a r ;

}

Output is:

auto_var = 0, static_var = 0auto_var = 0, static_var = 1auto_var = 0, static_var = 2auto_var = 0, static_var = 3auto_var = 0, static_var = 4

Theauto_var variable is created each time, but thestatic_var is created once and remembers its value.

6

Page 9: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1.1 C Basics

Printing Out and Inputting Variables

C usesformattedoutput. Theprintf function has a special formatting character (%) – a character following this definesa certain format for a variable:%c −− characte rs%d −− i n t e g e rs%f −− f l o a t s

E.g.printf("%c %d %f", ch, j, y); NOTE: Format statement enclosed in "...", variables follow after. Make sureorder of format and variable data types match up.scanf() is the function forinputting valuesto a data structure. Its format is similar toprintf: i.e. scanf("%c %d

%f",&ch,&j,&y); NOTE: & before variables.

1.1.5 Constants

ANSI C allows you to declare constants. When you declare a constant it is a bit like a variable declaration except thevalue cannot be changed. Theconst keyword is to declare a constant, as shown below:i n t const d = 1 ;const i n t d = 2 ;

Note: You can declare theconst before or after the type. We would advise you to use the secondform. It is usual toinitialize aconst with a value as it cannot get a value any other way.The preprocessor#define is another more flexible method to define constants in a program. You frequently see constdeclaration in function parameters. This says simply that the function is not going to change the value of the parameter.The following function definition used concepts we have not met, but for completeness of this section it is is includedhere:void s t r cp y ( char ∗buf , char const ∗ s t r )

The second argument,str, is a C string that will not be altered by the string copying standard library function.

1.1.6 Arithmetic Operations

As well as the standard arithmetic operators (+-*/) found inmost languages, C provides some more operators. There aresome notable differences with other languages, such as Pascal.

Assignment is "=" i.e. i = 4; ch = ’f’;

Increment ++, Decrement −− , which are more efficient than their long hand equivalents, for example:x++ is fasterthanx = x + 1. The++ and−− operators can be either in post-fixed or pre-fixed. With pre-fixed the value iscomputed before the expression is evaluated whereas with post-fixed the value is computed after the expression isevaluated. In the example below,++y is pre-fixed and thez- is post-fixed:i n t x , y , w ;main ( ){

x = ( ( ++z ) − ( w−− ) ) % 100;}

This would be equivalent to:i n t x , y , w ;main ( ){

z ++;x = ( z − w ) % 100;w−−;

}

% (modulus) operator only works withintegers.Division / is for both integer and float division. So be careful. The answer to: x = 3 / 2 is 1 even ifx is declared a

float! RULE : If both arguments of / are integer then do integer division.So make sure you do this. The correct (fordivision) answer to the above isx = 3.0 / 2 or x= 3 / 2.0 or (better)x = 3.0 / 2.0.

There is also a convenient shorthand way to express computations in C. It is very common to have expressions like:i

= i + 3 or x = x * ( y + 2 ) This can written in C (generally) in a shorthand form like this:l v a l u e opera to r = rva lue

which is equivalent to (but more efficient than):l v a l u e = l v a l u e opera to r rva lue

So we can rewritei = i + 3 asi += 3 andx = x * (y + 2) asx *= y + 2.

Note thatx *= y + 2 meansx = x * (y + 2) andnotx = x * y + 2.

DSAL.105.AC.01.04-B2 7

Page 10: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1 C Crash Course

1.1.7 Comparison Operators

• To test for equality is==.A warning: Beware of using “=” instead of “==”, such as writing accidentallyif ( i = j ) ... This is aperfectly legal C statement (syntactically speaking) which copies the value in j into i and delivers this value,which will then be interpreted as TRUE ifj is non-zero. This is calledassignment by value– a key feature of C.

• Not equals is!=.

• Other operators < (less than) , > (grater than), <= (less thanor equals), >= (greater than or equals) are as usual.

1.1.8 Logical Operators

Logical operators are usually used with conditional statements which we shall meet in the next Chapter. The two basiclogical operators are:&& for logical AND, || for logical OR. Beware & and | have a different meaning forbitwiseANDand OR.

1.1.9 Order of Precedence

It is necessary to be careful of the meaning of such expressions asa + b * c. We may want the effect as either(a + b) * c

ora + (b * c)

All operators have apriority, and high priority operators are evaluated before lower priority ones.Operators of the samepriority are evaluated from left to right, so thata - b - c

is evaluated as( a - b ) - c

as you would expect.

From high priority to low priority the orderfor all C operators (we have not met all ofthem yet) is given in table 1.2 and in moredetail in Addendum 1.4 Thusa < 10 && 2 * b < c

is interpreted as( a < 10 ) && ( ( 2 * b ) < c )

and

a =b =spokes / spokes_per_wheel+ spares ;

as

( ) [ ] -> .! - * & sizeof cast ++ −−(these are right->left)

* / + -< <= >= >== !=&|&&||?: (right->left)= += -= (right->left), (comma)}

Table 1.2: Brief summary of operator precedence.

a = (b = ( spokes / spokes_per_wheel ) + spares ) ;

1.1.10 Conditionals

Apart from slight syntactic variation they are similar to other languages. As we have seen following logical operationsexist in C:==, !=, , &&. One other operator is theunitary - it takes only one argument - not !. These operators areused in conjunction with the following statements.

The if statement

The if statement has the same function as other languages. Ithas three basic forms:

i f ( expression )sta tement

. . .

or:

i f ( expression )statement1

else

8

Page 11: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1.1 C Basics

statement2. . .

or:

i f ( expression )statement1

else i f ( expression )statement2

elsestatement3

For example:

i n t x , y , z , w ;main ( ){

i f ( x > 0){

z = w ;. . .

}else

{z = y ;. . .

}}

The ? operator

The ? (ternary condition) operator is a more efficient form for expressing simple if statements. It has the following form:expression1 ? expression2: expression3

It simply states: if expression1 then expression2 else expression3 For example to assign the maximum ofa andb to z:

z = (a>b) ? a : b;

which is the same as:

i f ( a > b )z = a ;

elsez = b ;

The switch statement

The C switch is similar to Pascal’s case statement and it allows multiple choice of a selection of items at one level of aconditional where it is a far neater way of writing multiple if statements:

switch ( expression ){

case i tem1 :statement_1 ;break ;

case i tem2 :statement_2 ;break ;

case i temn :statement_n ;break ;

de fau l t :sta tement ;break ;

}

In each case the value ofitemi must be aconstant, variables are not allowed. The break is needed if you want toterminatethe switch after execution of one choice. Otherwise the nextcase would get evaluated. Note: This is unlike most otherlanguages. We can also have null statements by just including a ; or let the switch statement fall through by omitting anystatements (see e.g. below). The default case is optional and catches any other cases. For example:

switch ( l e t t e r ){

case ’A ’ :

DSAL.105.AC.01.04-B2 9

Page 12: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1 C Crash Course

case ’E ’ :case ’ I ’ :case ’O’ :case ’U ’ :

numberofvowels++;break ;

case ’ ’ :numberofspaces++;break ;

de fau l t :numberofconstants ++;break ;

}

In the above example if the value of letter is ‘A’, ‘E’, ‘I’, ‘O’ or ‘U’ then numberofvowels is incremented. If the valueof letter is ‘ ’ thennumberofspaces is incremented. If none of these is true then the default condition is executed, thatis numberofconstants is incremented.

1.1.11 Looping and Iteration

This section will look at C’s mechanisms for controlling looping and iteration. Even though some of these mechanismsmay look familiar and indeed will operate in standard fashion most of the time.NOTE: some non-standard features areavailable.

The for statement

The C for statement has the following form:fo r ( expression1 ; 2 ; expression3 )

sta tement ;or { block o f sta tements}

expression1 initializes;expression2 is the terminate test;expression3 is the modifier (which may be more thanjust simple increment);NOTE: C basically treats for statements as while type loops.

For example:i n t x ;main ( ){

fo r ( x = 3 ; x > 0 ; x−−){

p r i n t f ( " x=%d \ n " , x ) ;}

}

outputs the following lines to the standard output device:

x=3x=2x=1

All the following statements are legal for statements in C. The purpose of the following example is for illustratation ofsome peculiar features of C that may be useful:fo r ( x = 0 ; ( (x > 3) && ( x < 9) ) ; x ++) ;fo r ( x= 0 , y = 4 ;

( ( x > 3) && ( y < 9) ) ;x ++ , y += 2 ) ;

fo r ( x = 0 , y = 4 , z = 4000;z ;z /= 10)

The second example shows that multiple expressions can be separated. In the third example the loop will continue toiterate until z becomes 0.

The while statement

The while statement is similar to those used in other languages although more can be done with the expression statement– a standard feature of C. The while has the form:

10

Page 13: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1.1 C Basics

while ( expression )sta tement

For example:

i n t x = 3 ;main ( ){

while ( x > 0){

p r i n t f ( " x=%d \ n " , x ) ;x−−;

}}

outputs:

x=3x=2x=1

to the screen. Because the while loop can accept expressions, not just conditions, the following are all legal:

while ( x−− ) ;while ( x = x + 1 ) ;while ( x += 5 ) ;

Using this type of expression, only when the result ofx-, x = x + 1, or x += 5, evaluates to 0 will thewhilecondition fail and the loop be exited. We can go further stilland perform complete operations within the while expression:

while ( j ++ < 10 ) ;while ( ( ch = getchar ( ) ) != ’ q ’ )

putchar ( ch ) ;

The first example countsj up to 10. The second example uses C standard library functions getchar() − reads acharacter from the keyboard− andputchar()− writes a given char to screen. The while loop will proceed to read fromthe keyboard and echo characters to the screen until a ’q’ character is read.NOTE: This type of operation is used a lot in C and not just with character reading!

The do-while statement

C’s do-while statement has the form:

dosta tement ;

while ( expression ) ;

It is similar to PASCAL’srepeat ... until except do while expression is true. For example:

i n t x = 3 ;main ( ){

do{

p r i n t f ( " x=%dn " ,x−−);}while ( x > 0 ) ;

}

outputs:

x=3x=2x=1

NOTE: The postfixx−− operator which uses the current value ofx while printing and then decrementsx.

break and continue

C provides two commands to control how we loop:

break – exit form loop or switch.continue – skip 1 iteration of loop.

DSAL.105.AC.01.04-B2 11

Page 14: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1 C Crash Course

Consider the following example where we read in integer values and process them according to the following conditions.If the value we have read is negative, we wish to print an errormessage and abandon the loop. If the value read is greatthan 50, we wish to ignore it and continue to the next value in the data. If the value is zero, we wish to terminate the loop.

while ( scanf ( "%d " , &va lue ) == 1&& va lue != 0)

{i f ( va lue < 0){

p r i n t f ( " I l l e g a l va lue \ n " ) ;break ;/∗ Abandon t h e loop ∗ /

}i f ( va lue > 50){

p r i n t f ( " I n v a l i d va lue \ n " ) ;continue ;/∗ Sk ip t o s t a r t loop again ∗ /

}/∗ Process t h e va lue read∗ //∗ guaran teed between 1 and 50∗ /

. . . ;

. . . ;} /∗ end wh i l e va lue != 0 ∗ /

1.1.12 Arrays and Strings

In principle arrays in C are similar to those found in other languages. As we shall shortly see arrays are defined slightlydifferently and there are many subtle differences due the close link between array and pointers.

Single and Multi-dimensional Arrays

Let us first look at how we define arrays in C:

i n t l i s t o fn u mb e rs [ 7 5 ] ;

BEWARE : In C array subscripts start at 0 and end one less than the array size. For example, in the above case validsubscripts range from 0 to 74. This is abig difference between C and other languages and does require a bit of practice toget in the right frame of mind. Elements can be accessed in thefollowing ways:

fourthnumber = l i s t o fn u mb e rs [ 3 ] ;l i s t o fn u mb e rs [ 7 ] = 99 ;

Multi-dimensional arrays can be defined as follows:

i n t arrayofnumbers [ 2 0 ] [ 2 0 ] ;/∗ f o r two d imens ions /∗

For further dimensions simply add more[]:

i n t mul t iD [ 5 0 ] [ 5 0 ] [ 4 0 ] [ 3 0 ] . . . [ 5 0 ] ;

Elements can be accessed in the following ways:

anumber = arrayofnumbers [ 2 ] [ 3 ] ;arrayofnumbers [ 1 7 ] [ 1 6 ] = 6 6 ;

Strings

In C Strings are defined as arrays of characters. For example,the following defines a string of 60 characters:

char name [ 6 0 ] ;

C has no string handling facilities built in and so the following are all illegal:

char f i r s t n a me [ 3 0 ] , lastname [ 3 0 ] , fu l lname [ 6 0 ] ;f i r s t n a me = " Jona than " ; /∗ I l l e g a l ∗ /lastname = " S w i f t " ; /∗ I l l e g a l ∗ /fu l lname = "Mr . "+ f i r s t n a me+ lastname ; /∗ I l l e g a l ∗ /

However, there is a special library of string handling routines which we will come across later. To print a string we useprintf with a special%s control character:

p r i n t f ( ‘ ‘% s ’ ’ , name ) ;

12

Page 15: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1.1 C Basics

NOTE: We just need to give the name of the string. In order to allow variable length strings the ’\0’ character is used toindicate the end of a string. If we have a string,char name[30]; and we store the “ADAM” in it its contents will looklike:

0 1 2 3 4 . . . 29’A’ ’D’ ’A’ ’M’ ’\0’ < anybyte > . . . < anybyte >

1.1.13 Functions

C provides functions which are again similar to most programming languages. One difference is that C regardsmain()

as function. Unlike some languages, such as Pascal, C does not haveprocedures– it uses functions to service bothrequirements. The form of a function, which we already know,is:

r e tu rn t yp e fn_name ( parameter_def1 ,parameter_def2 , )

{l o c a l _ v a r i a b l e sfunct ion_code

}

E.g.To find the average of two integers:

f l o a t f i ndaverage ( double a , double b ){

double average ;average = ( a + b ) / 2 ;re turn ( average ) ;

}

We would invoke the function as follows:

main ( ){

double a = 5 , b = 15 , r e s u l t ;r e s u l t = f i ndaverage ( a , b ) ;p r i n t f ( " ave rage=%f \ n " , r e s u l t ) ;

}

NOTE: The return statement passes the result back to the main program. The parenthesis afterreturn are notmanditory.

void Functions

Thevoid function provides a way of emulating PASCALtype procedures. If you do not want to return a value you mustuse the return type void and not provide the return statement:

void cubes ( ){

i n t loop ;fo r ( loop = 1 ; loop < 10 ; loop ++) ;

p r i n t f ( "%d \ n " , loop ∗ loop ∗ loop ) ;}main ( ){

cubes ( ) ;}

NOTE: We must provide "‘()"’ even for no parameters.

Functions and Arrays

Single dimensional arrays can be passed to functions as follows:

f l o a t f indmax ( i n t size , f l o a t l i s t [ ] ){

i n t i ;f l o a t max = 0 . 0 ;

fo r ( i = 0 ; i < s ize ; i ++)i f ( l i s t [ i ] > max )

max = l i s t [ i ] ;re turn ( max ) ;

}

DSAL.105.AC.01.04-B2 13

Page 16: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1 C Crash Course

Here the declarationfloat list[] tells C that list is an array of float. Note we do not specify thedimension of thearray when it is a parameter of a function. Multi-dimensional arrays can be passed to functions as follows:void p r i n t t a b l e ( i n t rowsize ,

i n t co ls i ze ,f l o a t t a b l e [ ] [ 5 ] )

{i n t r , c ;fo r ( r = 0 ; r < rowsize ; r ++ )

{fo r ( c = 0 ; c < c o l s i z e ; c++ )

p r i n t f ( " \ t%f " ,t a b l e [ r ] [ c ] ) ;

puts ( " \ n " ) ;}

}

Herefloat table[][5] tells C that table is an array of dimensionN × 5 of float. Note we must specify the second(and subsequent) dimension of the arraybut not the first dimension.

Function Prototyping

Before you use a function, C must have knowledge about the type it returns and the parameter types the function expects.The ANSI standard of C introduced a new (better) way of doing this than previous versions of C. (Note: All new versionsof C now adhere to the ANSI standard.)The importance of prototyping is twofold. It makes for more structured and therefore easier to read code. It allows theC compiler to check the syntax of function calls. How this is done depends on the scope of the function. Basically if afunctions has been defined before it is used (called) then youare ok to merely use the function. If NOT then you mustdeclare the function. The declaration simply states the type the function returns and the type of parameters used by thefunction. It isgood practiceto prototype all functions at the start of the program, although this is not strictly necessary.To declare a function prototype simply state the type the function returns, the function name and in brackets list the typeof parameters in the order they appear in the function definition. E.g.i n t s t r l e n ( char [ ] ) ;

This states that a function calledstrlen returns an integer value and accepts a single string as a parameter. NOTE:Functions can be prototyped and variables defined on the sameline of code. This used to be more popular in pre-ANSIC days since functions are usually prototyped separately atthe start of the program. This is still perfectly legal though:order they appear in the function definition. e.g.i n t length , s t r l e n ( char [ ] ) ;

Herelength is a variable,strlen is the function as before.

1.1.14 Structures

Structures in C are similar to records in Pascal. For example:s t ruc t studen t{

char name [ 5 0 ] ;i n t i d ;f l o a t mark ;

} ;s t ruc t studen t group ;

defines a new structurestudent and makesgroup an instance of it.NOTE thatstudent is a tag for the structure thatserves as shorthand for future declarations. We now only need to saystruct student and the body of the structure isimplied as we do to make thegroup variable. Thetag is optional. Variables can also be declared between the "‘{"‘ and"‘}"’ of a struct declaration, i.e.:s t ruc t studen t{

char name [ 5 0 ] ;i n t i d ;f l o a t mark ;

} group ;

struct’s can be pre-initialized at declaration:s t ruc t studen t S1 = { " John " , 4077 , 9 } ;

which givesS1 the name "‘John"’, an id of 4077 and a mark of 9. To access a member (or field) of astruct, C providesthe "‘."’ operator. For example, to giveS1 another id:

14

Page 17: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1.1 C Basics

S1 . i d = 4100;

1.1.15 Defining New Data Types

typedef can also be used with structures. The following creates a newtype astudent which is of typestructstudent and can be initialized as usual:

typedef s t ruc t studen t{

char name [ 5 0 ] ;i n t i d ;f l o a t mark ;

} astudent ;astudent s2 = { " Mary " , 3088 , 10 } ;

Herestudent still acts as a tag to thestruct and is optional. Indeed since we have defined a new data type itis notreally of much use,astudent is thenewdata type.s2 is avariable of typeastudent which is a structure. C also allowsarrays of structures:

typedef s t ruc t studen t{

char name [ 5 0 ] ;i n t i d ;f l o a t mark ;

} astudent ;astudent a l l s t u d e n t s [ 1 7 0 0 ] ;

This givesallstudents 1700 students. This may be used in the following way:

a l l s t u d e n t s [ 5 0 ] . mark = 8 ;

gives student at position 50 a mark of 8, and:

grade = a l l s t u d e n t s [ 0 ] . mark ;

assigns the mark of Arnie’s first student tograde.

1.1.16 Unions

A union is a variable which may hold (at different times) objects of different sizes and types. C uses the union statementto create unions, for example:

union number{

short shortnumber ;long longnumber ;double f loatnumber ;

} anumber ;

defines aunioncallednumber and an instance of it calledanumber. number is a union tag and acts in the same way as atag for a structure. Members can be accessed in the followingway:

p r i n t f ( "%l d \ n " , anumber . longnumber ) ;

This clearly displays the value oflongnumber. When the C compiler is allocating memory for unions it will alwaysreserve enough room for thelargest member(in the above example this is 8 bytes for the double). In orderthat theprogram can keep track of the type of union variable being used at a given time it is common to have a structure (withunion embedded in it) and a variable which flags the union type. An example is:

typedef s t ruc t{

i n t maxpassengers ;} car ;typedef s t ruc t{

i n t l i f t c a p a c i t y ;} crane ;typedef s t ruc t{

i n t maxpayload ;} l o r r y ;typedef union{

car carU ;crane craneU ;

DSAL.105.AC.01.04-B2 15

Page 18: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1 C Crash Course

l o r r y l o r r yU ;} ve h i c l e s ;typedef s t ruc t{

ve h i c l e t yp e kind ;i n t speed ;ve h i c l e d e s c r i p t i o n ;

} aVehic le ;

This example defines a base unionvehicles which may either be car, crane, or lorry. In theaVehicle structure there isakind member which indicates which structure is being held at the time.

1.1.17 Type-Casting or Coercion

C is one of the few languages to allowcoercion, that is forcing one variable of one type to be another type. Callows thisusing the cast operator "‘()"’. So:

i n t integernumber ;f l o a t f loatnumber = 9 . 8 7 ;integernumber = ( i n t ) f loatnumber ;

assigns 9 (the fractional part is thrown away) tointegernumber. And:

i n t integernumber = 10 ;f l o a t f loatnumber ;f loatnumber = ( f l o a t ) integernumber ;

assigns 10.0 tofloatnumber. Coercion can be used with any of the simple data types including char, so:

i n t integernumber ;char l e t t e r = ’A ’ ;integernumber = ( i n t ) l e t t e r ;

assigns decimal value 65 (the ASCII code for ‘A’) tointegernumber. Some typecasting is done automatically – thisis mainly with integer compatibility. A good rule to follow is: If in doubt cast. Another use is the make sure divisionbehaves as requested: If we have two integersinternumber andanotherint and we want the answer to be a float then,e.g.:

f loatnumber = ( f l o a t ) in ternumber /( f l o a t ) a n o t h e r i n t ;

ensures floating point division.

1.1.18 Enumerated Types

Enumerated types contain a list of constants that can be addressed in integer values. We can declare types and variablesas follows.

enum days { mon , tues , . . . , sun } week ;enum days week1 , week2 ;

NOTE: As with arrays first enumerated name has index value 0. Somon has value 0,tues 1, and so on.week1 andweek2 are variables. We can define other values:

enum escapes{

b e l l = ’ \ a ’ ,backspace = ’ \ b ’ ,tab = ’ \ t ’ ,newl ine = ’ \ n ’ ,vtab = ’ \ v ’ ,re turn = ’ \ r ’

} ;

We can also override the 0 start value:

enum months { j an = 1 , feb , mar , . . . , dec } ;

Here it is implied thatfeb = 2 mar = 3, etc.

1.1.19 Pointers

Pointers are a fundamental part of C. If you cannot use pointers properly then you have basically lost all the power andflexibility that C allows. The secret to C is in its use of pointers and C uses pointers a lot. Why? Because it is the only wayto express some computations. It produces compact and efficient code. It provides a very powerful tool. C uses pointers

16

Page 19: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1.1 C Basics

explicitly with: arrays, structures, functions.NOTE: Pointers are perhaps the most difficult part of C to understand. C’s implementation is slightlydifferentfrom otherlanguages.

What is a Pointer?

Definition 1.1.1 A pointeris a variable which contains the address in memory of anothervariable. We can have a pointerto any variable type.

The unary or monadic operator & gives the "‘address of a variable"’. The indirectionor dereferenceoperator * gives the"‘contents of an object pointed to by a pointer"’. To declarea pointer to a variable do:int *pointer;

NOTE that we must associate a pointer to a particular type and cannot assign the address of ashort int to alongint, for instance. Consider the effect of the following code:

i n t x = 1 ,y = 2 ;i n t ∗ i p ;i p = &x ;y = ∗ i p ;x = i p ;∗ i p = 3 ;

It is worth considering what is going on at the machine level in memory to fully understand how pointer work. Assumefor the sake of this discussion that variable x resides at memory location 100,y at 200 andip at 1000.Note. A pointeris a variable and thus its values need to be stored somewhere.It is the nature of the pointers value that is new. Now theassignmentsx = 1 andy = 2 obviously load these values into the variables.ip is declared to be a pointer to an integerand is assigned to the address ofx (&x). Soip gets loaded with the value 100. Nexty gets assigned to the contents ofip.In this example ip currently points to memory location 100 – the location ofx. Thusy gets assigned to the values ofx –which is 1. We have already seen that C is not too fussy about assigning values of different type. Thus it is perfectly legal(although not all that common) to assign the current value ofip to x. The value ofip at this instant is 100. Finally we canassign a value to the contents of a pointer (*ip). IMPORTANT : When a pointer is declared it does not point anywhere.You must set it to point somewhere before you use it.So

i n t ∗ i p ;∗ i p = 100;

will generate an error (program crash). The correct use is:

i n t ∗ i p ;i n t x ;i p = &x ;∗ i p = 100;

We can do integer arithmetic on a pointer:

f l o a t ∗ f l p , ∗ f l q ;∗ f l p = ∗ f l p + 10 ;++∗ f l p ;(∗ f l p )++ ;f l q = f l p ;

NOTE: A pointer to any variable type is anaddressin memory – which is an integer address. A pointer is definitely NOTan integer. The reason we associate a pointer to a data type isso that it knows how many bytes the data is stored in. Whenwe increment a pointer we increase the pointer by one “block”memory. So for a character pointer++ch_ptr adds 1 byteto the address. For an integer or float++ip or ++flp adds 4 bytes to the address. Consider a float variable (fl) and apointer to a float (flp).

Pointer Arithmetic

Assume thatflp points tofl then if we increment the pointer (++flp) it moves to the position shown 4 bytes on. If onthe other hand we added 2 to the pointer then it moves 2 float positions i.e 8 bytes.

Pointers and Functions

Let us now examine the close relationship between pointers and C’s other major parts. We will start with functions. WhenC passes arguments to functions it passes them by value. There are many cases when we may want to alter a passedargument in the function and receive the new value back once to function has finished. Other languages do this (e.g.var

parameters in PASCAL). C uses pointers explicitly to do this. Other languages mask the fact that pointers also underpinthe implementation of this. The best way to study this is to look at an example where we must be able to receive changed

DSAL.105.AC.01.04-B2 17

Page 20: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1 C Crash Course

parameters. Let us try and write a function to swap variablesaround? The usual function call:swap(a, b) WON’TWORK. Pointers provide the solution: Pass the address of thevariables to the functions and access address of function.Thus our function call in our program would look like this:swap(&a, &b) The Code to swap is fairly straightforward:

void swap ( i n t ∗px , i n t ∗py ){

i n t temp ;temp = ∗px ;/∗ c o n t e n t s o f p o i n t e r ∗ /∗px = ∗py ;∗py = temp ;

}

We can return pointer from functions. A common example is when passing back structures. e.g.:

typedef s t ruc t{

f l o a t x , y , z ;} COORD;main ( ){

COORD p1 ,∗coord_fn ( ) ; /∗ d e c l a r e f n t o r e t u r n p t r o fCOORD t y p e ∗ /. . .p1 = ∗ coord_fn ( . . . ) ;/∗ a s s i g n c o n t e n t s o f address r e t u r n e d∗ /. . .

}COORD ∗coord_fn ( . . . ){

COORD p ;. . .p = . . . ;/∗ a s s i g n s t r u c t u r e v a l u e s∗ /re turn &p ;/∗ r e t u r n address o f p∗ /

}

Here we return a pointer whose contents are immediately unwrapped into a variable. We must do this straight away as thevariable we pointed to was local to a function that has now finished. This means that the address space is free and can beoverwritten. It will not have been overwritten straight after the function has quit though so this is perfectly safe. Pointersand Arrays Pointers and arrays are very closely linked in C. Hint: think of array elements arranged in consecutive memorylocations. Consider the following:

i n t a [ 1 0 ] , x ;i n t ∗pa ;/∗ pa p o i n t e r t o address o f a [0 ]∗ /pa = &a [ 0 ] ;/∗ x = c o n t e n t s o f pa

( a [0 ] i n t h i s case ) ∗ /x = ∗pa ;

To get somewhere in the array using a pointer we could do:pa + i⇔a[i]

WARNING : There is no bound checking of arrays and pointers so you can easily go beyond array memory and overwriteother things. C however is much more subtle in its link between arrays and pointers. For example we can just typepa

= a; instead ofpa = &a[0] anda[i] can be written as*(a + i). i.e. &a[i]⇔a + i. We also express pointeraddressing like this:pa[i] *(pa + i).

However pointers and arrays are different: A pointer is a variable. We can do pa = a and pa++. An Array is not a vari-able.a = pa anda++ are illegal. This stuff is very important. Make sure you understand it. We will see a lot more of this.

We can now understand how arrays are passed to functions. When an array is passed to a function what is actuallypassed is its initial elements location in memory. So:strlen(s) strlen(&s[0]). This is why we declare the function:int strlen(char s[]); An equivalent declaration is :int strlen(char *s); sincechar s[] ⇔ char *s.strlen() is a standard library function that returns the length of a string. Let’s look at how we may write a function:

i n t s t r l e n ( char ∗s ){

char ∗p = s ;

18

Page 21: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1.1 C Basics

while (∗p != ’ 0 ’ ) p++;re turn ( p − s ) ;

}

Now lets write a function to copy a string to another string.strcpy() is a standard library function that does this.

void s t r cp y ( char ∗s , char ∗ t ){

while ( (∗ s++ = ∗ t ++) != ’ \ 0 ’ ) ;}

This uses pointers and assignment by value.NOTE: Uses of Null statements with while.

Arrays of Pointers

We can have arrays of pointers since pointers are variables.Example use: Sort lines of text of different length.NOTE:Text can’t be moved or compared in a single operation. Arraysof Pointers are a data representation that will copeefficiently and conveniently with variable length text lines. How can we do this?: Store lines end-to-end in one big chararray.n will delimit lines. Store pointers in a different array where each pointer points to the first char of each new line.Compare two lines usingstrcmp() standard library function. If 2 lines are out of order – swap pointer in pointer array(not text). This eliminates:

• complicated storage management.• high overheads of moving lines.

Multidimensional arrays and pointers

We should think of multidimensional arrays in a different way in C: A 2D array is really a 1D array, each of whoseelements is itself an array Hence a[n][m] notation. Array elements are stored row by row. When we pass a 2D array to afunction we must specify the number of columns – the number ofrows is irrelevant. The reason for this is pointers again.C needs to know how many columns in order that it can jump from row to row in memory.

Considerint a[5][35] to be passed in a function: We can do:f(int a[][35]) ..... or even:f(int (*a)[35])

..... We need parenthesis(*a) since [] have a higher precedence than * So:int (*a)[35]; declares a pointer to anarray of 35 ints.int *a[35]; declares an array of 35 pointers to ints. Now lets look at the (subtle) difference betweenpointers and arrays. Strings are a common application of this. Consider:

char ∗name [ 1 0 ] ;char Aname [ 1 0 ] [ 2 0 ] ;

We can legally doname[3][4] andAname[3][4] in C. HoweverAname is a true 200 element 2D char array. accesselements via20*row + col + base_address in memory. name has 10 pointer elements.NOTE: If each pointer inname is set to point to a 20 element array then and only then will 200 chars be set aside (+ 10 elements). The advantageof the latter is that each pointer can point to arrays be of different length. Consider:

char ∗name [ ] = { " no month " , " j a n " , " f eb " , . . . } ;char Aname [ ] [ 1 5 ] = { " no month " , " j a n " , " f eb " , . . . } ;

Static Initialization of Pointer Arrays

Initialization of arrays of pointers is an ideal application for an internal static array.

some_fn ( ){

s t a t i c char ∗months ={ " no month " , " j a n " , " f eb " , . . . } ;

}

static reserves a private permanent bit of memory.

Pointers and Structures

These are fairly straight forward and are easily defined. Consider the following:

s t ruc t COORD{

f l o a t x , y , z ;} p t ;s t ruc t COORD ∗ p t _ p t r ;p t _ p t r = &p t ; /∗ a s s i g n s p o i n t e r t o p t∗ /

DSAL.105.AC.01.04-B2 19

Page 22: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1 C Crash Course

the operator lets us access a member of the structure pointedto by a pointer.i.e.:

p t _ p t r x = 1 . 0 ;p t _ p t r y = p t _ p t r y − 3 . 0 ;

Example: Linked Lists

typedef s t ruc t{

i n t va lue ;NodeT ∗next ;

} NodeT ;NodeT n1 , n2 ;n1 . next = &n2 ;

NOTE. We can only declare next as a pointer to ELEMENT. We cannot have a element of the variable type as this wouldset up a recursive definition which is NOT ALLOWED. We are allowed to set a pointer reference since 4 bytes are setaside for any pointer. The above code links a noden1 to n2. we will look at this matter further in the next Chapter.Common Pointer Pitfalls Here we will highlight two common mistakes made with pointers. Not assigning a pointer tomemory address before using it.

i n t ∗x ;∗x = 100;

we need a physical location say:

i n t y ;x = &y ;∗x = 100;

This may be hard to spot. NO COMPILER ERROR. Alsox could have some random address at initialization.

Illegal indirection

Suppose we have a functionmalloc() which tries to allocate memory dynamically (at run time) andreturns a pointer toblock of memory requested if successful or a NULL pointer otherwise.char *malloc() – a standard library function.Let us have a pointer:char *p; Consider:

/∗ r e q u e s t 100 b y t e s o f memory∗ /∗p = ( char ∗ ) mal loc ( 1 0 0 ) ;∗p = ’y ’ ;

There is mistake above.What is it? No* in *p = (char *) malloc(100); malloc returns a pointer. Alsop does not point to any address.The correct code should be:

p = ( char ∗ ) mal loc ( 1 0 0 ) ;

If code rectified one problem is if no memory is available andp is NULL. Therefore we can’t do:*p = ’y’;.

A good C program would check for this:

p = ( char ∗ ) mal loc ( 1 0 0 ) ;i f ( p == NULL){

p r i n t f ( " E r r o r : Out o f Memory \ n " ) ;e x i t ( 1 ) ;

} ∗p = ’y ’ ;

1.1.20 More on C Preprocessor

#define can also be given arguments which are used in its replacement. The definitions are then calledmacros. Macroswork rather like functions, but with the following minor differences.Since macros are implemented as a textual substitution, there is no effect on program performance (as with functions).Recursive macros are generallynot a good idea. Macros don’t care about the type of their arguments. Hence macros are agood choice where we might want to operate on reals, integersor a mixture of the two. Programmers sometimes call suchtype flexibility polymorphism. Macros are generally fairlysmall. Macros are full of traps for the unwary programmer. Inparticular the textual substitution means that arithmeticexpressions are liable to be corrupted by the order of evaluationrules. Here is an example of a macro which won’t work.

#define DOUBLE( x ) x+x

Now if we have a statement

a = DOUBLE( b ) ∗ c ;

20

Page 23: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1.2 C Language Keywords

This will be expanded to

a = b+b * c;

And since * has a higher priority than +, the compiler will treat it as.

a = b + ( b ∗ c ) ;

The problem can be solved using a more robust definition of DOUBLE

#define DOUBLE( x ) ( x+x )

Here the brackets around the definition force the expressionto be evaluated before any surrounding operators are applied.This should make the macro more reliable. In general it isbetterto write a C function than risk using a macro.

The preprocessor directive#include is an instruction to read in the entire contents of another file at that point. This isgenerally used to read in header files for library functions.Header files contain details of functions and types used withinthe library. They must be included before the program can make use of the library functions.Library header file names areenclosed in angle brackets, < >. These tell the preprocessorto look for the header file in the standard location for librarydefinitions. This is/usr/include for most UNIX systems. For example

#include < s t d i o . h>

Another use for#include for the programmer is where multi-file programs are being written. Certain information isrequired at the beginning of each program file. This can be putinto a file calledglobals.h and included in each programfile. Local header file names are usually enclosed by double quotes, " ". It is conventional to give header files a namewhich ends in.h to distinguish them from other types of file. Ourglobals.h file would be included by the followingline.

#include " g l o b a l s . h "

The preprocessor has a conditional statement similar to C’sif else. It can be used to selectively include statementsin a program. This is often used where two different computertypes implement a feature in different ways. It allows theprogrammer to produce a program which will run on either type.

The keywords for conditional selection are;#ifdef, #else and#endif.

#ifdef takes a name as an argument, and returns true if the the name has a current definition. The name may be definedusing a#define, the-d option of the compiler, or certain names which are automatically defined by the UNIXenvironment.

#else is optional and ends the block beginning with#ifdef. It is used to create a 2 way optional selection.#endif ends the block started by#ifdef or #else.

Where the#ifdef is true, statements between it and a following#else or #endif are included in the program. Whereit is false, and there is a following#else, statements between the#else and the following#endif are included. This isbest illustrated by an example.

#include < s t d i o . h>

main ( ){# i f d e f vax

p r i n t f ( " Th is i s a VAX\ n " ) ;#endi f# i f d e f sun

p r i n t f ( " Th is i s a SUN\ n " ) ;#endi f}

#ifdef also provides a useful means of temporarily ‘blanking out’ lines of a program. The lines in question are precededby #ifdef DEBUG and followed by#endif. Thus you can get rid of lines introduced for debugging purposes in theproduction version of your program. When you want to have allthe debugging messages that you placed in the sourcecode, you simply do

#define DEBUG 1

1.2 C Language Keywords

The following names are reserved by C language:

DSAL.105.AC.01.04-B2 21

Page 24: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1 C Crash Course

auto break case char continuedefault do double else enumextern float for goto if

int long register return shortsizeof static struct switch typedefunion unsigned void while

Table 1.3: C language keywords

1.3 Special Characters

’\f’ form feed (also ’\014’)’\n’ line feed’\t’ tab’\\’ backslash’\” single quote’\"’ double quote’\b’ backspace’\r’ carriage return’\0’ string terminator

Table 1.4: C special characters

1.4 Operator Precedence and Associativity Rules in C / C++

:: scope resolution (C++, e.g. name::member) left-to-right:: global (C++, e.g. ::name)( ) function call left-to-right[ ] array element. class, structure or union member

−> pointer reference to member:: scope access / resolution (C++)

sizeof size of object in bytessizeof size of type in bytes

++ post increment (lvalue++) right-to-left++ pre increment (++lvalue)– post decrement (lvalue–)– pre decrement (–lvalue)˜ bitwise complement right-to-left! logical not- unary minus+ unary plus& address of* contents of

new create object (C++)delete destroy object (C++)

delete[] destroy array (C++)(type) cast to type

.* member pointer (C++) left-to-right−>* pointer reference to member pointer (C++)

* multiply left-to-right/ divide

% remainder+ add left-to-right- subtract

22

Page 25: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1.5 Some C header files

« bitwise left shift left-to-right» bitwise right shift< scalar less than left-to-right<= scalar less than or equal to> scalar greater than>= scalar greater than or equal to== scalar equal left-to-right!= scalar not equal& bitwise and left-to-rightˆ bitwise exclusive or left-to-right| bitwise or left-to-right

&& logical and left-to-right|| logical inclusive or left-to-right

? : conditional expression right-to-left= assignment operator right-to-left

also += -= *= /= %= &= ˆ = |= »= «=, sequential expression left-to-right

All of the operators in this table can be overloaded(C++) except:

. C++ direct component selector.* C++ dereference:: C++ scope access/resolution?: Conditional

Table 1.5: Operator Precedence and Associativity Rules in C/ C+

1.5 Some C header files

assert.h Diagnosticsctype.h Character Handling and Conversionfloat.h Floating Point Supportlimits.h Maximum and Minimum Limitslocale.h International Supportmath.h Mathematicssetjmp.h Jumpssignal.h Signal Handlingstdarg.h Variable Number of Argumentsstddef.h Standard Definitionsstdio.h Input and Output Supportstdlib.h General Definitions and Utilitiesstring.h String Handlingtime.h Time and Date Support

Table 1.6: The ANSI C Header Files

1.6 A Strange Way to Write C Code

The figure 1.2 taken from the International Obfuscated C Contest, Edition 1987, shows a strange way to write code,together with the authors’hints.

DSAL.105.AC.01.04-B2 23

Page 26: Data Structures and Algorithms. Course.users.utcluj.ro/~jim/CP/Resources/Lectures/CP-C.pdf · the following C code shown in figure 1.2 of Addendum 1.6 is actu ally legal C code

1 C Crash Course

Larry Wall Unisys - System Development Group Santa Monica9132 Kester Ave Panorama City, CA 91402 USATry: lwall | bc | lwallinput: x*xinput: c^2Also try: lwall | bc and lwall | catWhat we found amazing was how the flow of control wastransferred between subroutines. Careful inspection willshow that the array of pointers to functions named ‘vi’ refersto functions which seem to not be directly called. Even so,these pointers to functions are being used as an argument tosignal. Can you determine why this is being done and how itis being exploited?Some compilers complained about this file, so we changed:’=++I’ to ’= ++I’.Copyright (c) 1987, Landon Curt Noll & Larry Bassel.All Rights Reserved. Permission for personal, educational ornon-profit use is granted provided this this copyright andnotice are included in its entirety and remains unaltered.All other uses must receive prior permission in writingfrom both Landon Curt Noll and Larry Bassel.#define iv 4#define v ;(void#define XI(xi)int xi[iv*’V’];#define L(c,l,i)c(){d(l);m(i);}#include <stdio.h>int*cc,c,i,ix=’\t’,exit(),X=’\n’*’\d’;XI(VI)XI(xi)extern(*vi[])(),(* signal())();char*V,cm,D[’x’],M=’\n’,I,*gets();L(MV,V,(c+=’d’,ix))m(x){v) signal(X/’I’,vi[x]);}d(x)char*x;{v)write(i,x,i);}L(MC,V,M+I)xv(){c>=i?m( c/M/M+M):(d(&M),m(cm));}L(mi,V+cm,M)L(md,V,M)MM(){c=c*M%X;V-=cm;m(ix);} LXX(){gets(D)||(vi[iv])();c=atoi(D);while(c>=X){c-=X;d("m");}V="ivxlcdm" +iv;m(ix);}LV(){c-=c;while((i=cc[*D=getchar()])>-I)i?(c?(c<i&&l(-c-c, "%d"),l(i,"+%d")):l(i,"(%d")):(c&&l(M,")"),l(*D,"%c")),c=i;c&&l(X,")"),l(-i,"%c");m(iv-!(i&I));}L(ml,V,’\f’)li(){m(cm+!isatty(i=I));}ii(){m(c=cm = ++I)v)pipe(VI);cc=xi+cm++;for(V="jWYmDEnX";*V;V++)xi[*V^’ ’]=c,xi[*V++] =c,c*=M,xi[*V^’ ’]=xi[*V]=c>>I;cc[-I]-=ix v)close(*VI);cc[M]-=M;}main(){ (*vi)();for(;v)write(VI[I],V,M));}l(xl,lx)char*lx;{v)printf(lx,xl)v) fflush(stdout);}L(xx,V+I,(c-=X/cm,ix))int(*vi[])()={ii,li,LXX,LV,exit,l, d,l,d,xv,MM,md,MC,ml,MV,xx,xx,xx,xx,MV,mi};

Figure 1.2: Roman numeral -> decimal and vice versa conversion...

24