LECTURE 4, 5 and 6

Introduction to programming in C

„My first, second, ..., n-th program in C”

Programs: c1_1.c ... c1_9.c

Tomasz Zieliński

COMPILER vs. INTERPRETER (1) – in general

C/C++

= compilers (Visual Studio Express, Eclipse, Dev-C++)

• translate the whole program at once to μP instructions,

then the program is executed

• used when the algorithm is already known (developed)

Basic

= interpreters

Matlab

• translate and execute line by line not the whole program

• used when the algorithm is under development

Good points

Drawbacks

Compiler

• Fast program execution

Long way from an idea to its

• Possible program code

verification

optimization: e.g. high speed,

low memory requirements

Interpreter

Short way from an idea to its

Slow program execution

verification

COMPILER vs. INTERPRETER (2) –program development

f1.obj, f2.obj, ...

static (lib)

Lib Maker

and dynamic (dll)

Consolidation

system.dll

execution

linking libraries

of the whole

system.lib

my.lib

my.dll

program

Text/Program

Operating

COMPILER

Linker

editor

system

prog.c

prog.obj

prog.exe

INTERPRETER – a separate program / application

1

1

Line

editor

Interpr

Li e

n te

e r

Line

INTElinii

RPRETER

executor

Program

= set of lines

>> ...?... (CR)

2

2

COMPILER vs. INTERPRETER (3)

speed of development vs. speed of execution

time

time of program

time of program

development

execution

(debugging)

Assembler

C/C++ language

Matlab

Simulink

CONCLUSIONS:

♦ when I am looking for a solution, I am choosing a high-level computer

language, even graphical, with many libraries

(I am fast writing a program that is slowly executed)

♦ when I know the solution, I am choosing a low-level computer language

(I am slowly writing a program that is fast executed)

COMPUTER ARITHMETIC (1)

(coding sign of integer numbers)

Code sign-magnitude

0 0 0 1 0 0 0 0 = +16

(16)

+ 1 0 0 1 0 0 0 0 = −16

(144)

---------------------------------

1 0 1 0 0 0 0 0 = −32 (160)

Code two’s complement C2

0 0 0 1 0 0 0 0 = +16

1 1 1 0 1 1 1 1

(negate all bits)

+ 1

(add 1 to the result of negation)

-------------------------

1 1 1 1 0 0 0 0 = −16 (128+64+32+16 = 240)

without change to

first 1, including it,

0 0 0 1 0 0 0 0 (+16)

then negate all bits

+16 = 0 0 0 1 0 0 0 0

+

1 1 1 1 0 0 0 0 (-16)

-16 = 1 1 1 1 0 0 0 0

1 0 0 0 0 0 0 0 0 (+0)

COMPUTER ARITHMETIC (2)

(example of C2 code usage)

00000110 = 6

00000101 = 5

00000110 = 6

--------------

+ 11111011 = −5

11111010

------------------------

+

1

1|00000001 = 1

--------------------

11111011 = −5

COMPUTER ARITHMETIC (3)

(coding non-integer fractional numbers using C2 code)

0 1 0 0 0 1 1 0 binary number (70)

-----------------------------------------------------------------------------------

−1 2−1

2−2

2−3

2−4

2−5

2−6

2−7

weights

−1

1/2

1/4

1/8

1/16 1/32 1/64 1/128

-----------------------------------------------------------------------------------

RESULT

1/2

1/32 1/64 = 35/64

= 0.546875

1 0 1 1 1 0 1 0

binary number (-70)

----------------------------------------------------------------------------------

−1 2−1

2−2

2−3

2−4

2−5

2−6

2−7

weights

−1

1/2

1/4

1/8

1/16 1/32 1/64 1/128

----------------------------------------------------------------------------------

RESULT

−1

1/4

1/8

1/16 1/64 = −35/64

= −0.546875

EXAMPLES:

00000110 = 0 + (1/32 + 1/64) = 3/64

11111011 = −1 + (1/2 + 1/4 + 1/8 + 1/16 + 1/64 + 1/128) = −1 + 123/128 = −5/128

COMPUTER ARITHMETIC (4)

(coding very small/big real numbers: sign, mantissa and characteristic) x = −0,009765625 = −0,9765625*10-2 = − (1/2+1/8) * 2- 6= − 0,625 * 2- 6

x = (-1)s * m * 2c

x = s

(p)

(p)

1 bit | c8 bits

| m23 bits, ⇐ c8 bits = c + 127, -126 ≤ c ≤ 127

8 bits

23 bits

x = 1 | 01111001 | 1010 0000 0000 0000 0000 000

1/2 + 1/8 = 5/8 = 0,625

121 = -6+127

121 = 0 + 1*64 +1*32 + 1*16 + 1*8 + 0*4 + 0*2 + 1*1

/* Example 1 - ver. 1 - my first program */

// remark

#include <stdio.h>

// description how are called functions from

// the library stdio.h, in particular printf()

main()

// program beginning

{

// opening the block of program instructions

float budget, mine;

// declaration of variable types:

int

persons;

// budget, mine, persons

budget = 1500.45;

// initialization of variable values:

persons = 4;

// bugdet and persons

mine = budget/persons;

// usage of variables budget and persons

// calculation of my part of the money

printf("\n" );

// new line

printf(" My part is = %7.3f \n", mine );

// display on the screen

printf("\n" );

// new line

return(0);

// return from the program to the OS

}

// closing the block of program instructions

/* PROGRAM DESCRIPTION

1) Program should begin with introduction what is calculated in it:

/* ... what I am doing ? .. */.

2) Next, files describing how are called functions from different libraries should be added: e.g.

#include <stdio.h> - standard input/output library

#include <math.h> - library with mathematical functions like sin(), cos(), exp(), log(), ...

#include <string.h> - library with functions acting on string of characters 3) main() { ... my program ... } – main program (main function)

char represents a character code written on 8 bits (1 byte)

int represents an integer number with sign written on 16 bits (2 bytes) – C2 coding is used long represents an integer number with sign written on 32 bits (4 bytes) – C2 code float represents a floating-point number written on 32 bits (4 bytes) double represents a floating-point number written on 64 bits (8 bytes) 4) After declaration of variable types (number of bits and coding used) the compiler allocates memory cells for storing each variable.

5) After initialization of variable values the declared numbers are written into memory cells associated with the variables.

6) We are using variables performing operations on their names (arithmetic operators: +, -, *, /,

% - reminder from division of two integer values, e.g. 7%4=3).

For example operation mine = budget/persons means:

a) take from memory to μP registers values of variables budget and persons b) divide contents of these registers

c) write the result into memory allocated for storing the variable mine 7) Function

printf(”my part is = %f PLN \n”, mine) will display on the screen: My part is = 375.1125 PLN

” %d %f %c %s ...” – transformation codes, how to print (decimal, float, character, string)

”\n \t \b” – codes controlling the cursor movement (new line, tab, backspace)

*/

/* Examples 1 ver. 2 - #define, scanf */

#include <stdio.h>

#define PERSONS

4 // definition of the text constant PERSONS

// during compilation the text PERSONS

main()

// will be always replaced with 4

{

float budget, mine;

printf("\n" );

// new line on the screen

printf("What is the budget ? " ); // display question on the screen scanf("%f", &budget);

// read number from the keyboard

// and store it in the variable budget

mine = budget/PERSONS;

printf("\n" );

printf(" My part is = %7.3f \n", mine );

printf("\n" );

return(0);

}

/* PROGRAM DESCRIPTION

1) Text

constants are defined in the program beginning: therefore they are easy to find and to be changed. For example: number of characters in one line, buffer length, ...

2) They are usually written in capital letters: therefore it is easy to distinguish in the program them from variables.

3) Function

scanf("%f", &budget):

a) read a sequence of ASCII codes from the keyboard (terminated with the button ENTER), b) translate it to binary number coded in specific chosen format (”%f” means float) c) store the result memory cells allocated to variable budget.

4) IMPORTANT:

budget – variable name, &budget - „address” in memory of variable budget,

*address - value of the number stored in memory under given address pointer is a variable being an address into memory and pointing to number having specified type (char, int, float, double).

EXAMPLE of pointer definitions

int x, y;

// declaration of variables „x” and „y”

int *pa, *pb;

// declaration of pointers „pa” i „pb” to variables of type „int”

pa = &x; pb = &y;

// pointer pa is pointing to variable x and pb – to variable y

*pa = 10; *pb = 20;

// writing numbers 10 and 20 into memory under specified addresses;

// now values of variables x and y are initialized

*/

/* Example 1 - ver. 3 – simple function */

#include <stdio.h>

// declaration how to call functions from

// stdio library ( e.g. scanf(), printf() )

#define PERSONS

4

float equation( float money );

// declaration how to call my function

/* main program ---------------------------------------------------------- */

main()

{

float budget, mine;

printf("\n");

printf("What is the budget ?");

scanf("%f", &budget);

// mine = budget/PERSONS; // calculation without a function

// call to my function equation()

mine = equation( budget ); // value of the variable budget is sent to the

// function, value of the variable mine is

// returned

printf("\n");

printf("My part is = %7.3f \n", mine);

printf("\n");

return(0);

}

/* definition of the function equation() ------------------------------------------- */

float equation( float money ) // the function is given and it returned

{

// a floating-point value

float temp;

// inner auxiliary variable of the function

temp = money/PERSONS; // calculation of temp value

return( temp );

// returning this value to the main program

}

/* PROGRAM DESCRIPTION

1) Before the main program one should let know the compiler calling convention for all his function that are used in it. In the same manner it is done for library functions, e.g. in stdio.h.

2) The following should be specified:

• types of variables that are sent from the main program to the function

• type of the variable that is transferred back from the function to the main program via return() command

3) What can one sent to a function?

• a variable value (copied from memory cells allocated for this variable)

• an address to variable location in memory

In the second case the function can:

• read the variable value itself from the memory

• modify this value writing a new one into the memory (under the known address) mine = equation( budget )

- send a variable value (copy of a number from memory)

mine = equation( &budget ) - send an address of the variable in memory In our example, we are transferring a value of the variable (taken from the memory associated with it).

4) Any function has an access to the following variables:

• obtained from the precedent (superior) program or function (value or address)

• global ones, e.g. defined out of all brackets { } including the main program brackets also; global variables are not “hidden” between/inside {.} and, therefore, they are available for

“everybody”;

• local ones created inside the function

In our example:

• money inside the function represents a value of the variable budget,

• text constant PERSONS is defined outside any brackets and, therefore, can be used inside the function equation(),

• temp is a local variable of the function equation().

5) Inside the function the sent variables can have different names from these that are used in the main program. We have ” formal” names (parameters) inside the function and specific

“calling” names (parameters) used in the main program.

In our example we can send to the function equation() a value of any family budget. e.g.

budget1, budget2 or budget3. In all cases inside the function the transferred values will be known as money.

It means that one can execute function giving her different data.

The function is written only once but used many times.

It leads to so-called structural (modular) programming: the main program represents a root of the tree, which has many branches (auxiliary functions) that in turn can have additional side branches (sub-functions).

*/

/* Example 1 - ver. 4 – complex multi-argument function */

#include <stdio.h>

#define PERSONS 3

void equation( float money, float *pers1, float *pers2, float *pers3 );

/* main program --------------------------------------------------------------------- */

main()

{

float budget;

float mum, dad, me;

printf("\n");

printf(" What is the budget ? ");

scanf( "%f", &budget );

// the function call

equation( budget, & mum, & dad, & me ); // value of the budget

// address to mum, dad, me

printf("\n");

printf("mum = %7.3f, dad = %7.3f, me = %7.3f \n", mum, dad, me); printf("\n");

return(0);

}

/* my auxiliary function -------------------------------------------------------------- */

void equation( float money, float *pers1, float *pers2, float *pers3 )

{

float meanval;

/* inner auxiliary variable, mean value */

meanval = money/PERSONS;

*pers1 = 1.00 * meanval;

*pers2 = 1.25 * meanval;

*pers3 = 0.75 * meanval;

}

/* PROGRAM DESCRIPTION

1) At present we are not egoists. Now we are not only interested in our “business” but also in money of our mummy and daddy.

2) Therefore we are declaring three floating-point variables: mum, dad, me.

3) To the function equation(.) we are sending memory addresses of these three variables:

&mum, &dad, &me.

4) Inside the function these addresses are denoted as: pers1, pers2, pers3.

Writing

float *pers1, we are saying: value under address pers1 is a floating-point number.

So we are saying that pers1 is a pointer indicating a floating-point number.

4) Next, we are performing all necessary calculations inside the function and store the results into the memory under addresses given during the function call, e.g.:

*pers = 1.00*meanval what means that value under address pers1 must be set to 1.00*meanval;

5) Now we can write a multi-argument function:

function(a, b, c, &x, &y, &z)

a, b, c – values of variable (copied from memory)

x, y, z – pointers to variables (addresses into memory + information about the variable types)

• if the function has obtained only a copy of the variable value, it cannot change it (it can only make use of this value),

• if the function has obtained the variable address, it can do everything with the variable: use its value and modify it.

*/

/* Example 1 ver. 5 - tables, for, if */

#include <stdio.h>

#define

PERSONS 3

//

void = function nothing

//

send

to

the

main

void equation( float money, float members[] );

// program by return(.)

// transferring a table

/* main program -------------------------------------------------------------------------- */

main()

{

float

budget;

float

family[ PERSONS ];

char

*names[ PERSONS ] = {"mummy", "daddy", "me"}; int

i;

printf( "\n" );

printf( "What is the budget ?" );

scanf( "%f", &budget );

equation( budget, family );

printf("\n");

for( i=0; i<PERSONS; i++ )

{

printf( "person no %d, i.e. %s = %7.3f \n", i, names[i], family[i] );

}

printf("\n");

if ( family[0] > family[2] )

// >, >=, <, <=, ==, !=

{ printf( "Something is wrong ! I have less than mummy ! \n" ); }

else

{ printf( "It is OK ! \n" ); }

printf( "\n" );

return(0);

}

/* my auxiliary function ----------------------------------------------------------------- */

void equation( float money, float members[] )

{

float meanval;

/* inner auxiliary variable, mean value */

meanval = money/PERSONS;

members[0] = 1.00 * meanval;

members[1] = 1.25 * meanval;

members[2] = 0.75 * meanval;

}

/* PROGRAM DESCRIPTION

1) void equation(.) – means that the function does not send back anything by return(.).

2) void equation( float money, float members[] ) – to the function is transferred a floating-point value, that will be called “money” inside the function, and a table members[] with floating point numbers (it is not specified how many);

Table represents a vector of numbers of the same type, which are stored in memory one by one in continues block of memory cells. Transferring a table means that the function is given an initial address to the first memory cell of this block.

3) float

family[ PERSONS ] – declaration of a table having 3 elements (since PERSONS = 3).

As a consequence 3 floating-point numbers are stored in memory one-by-one and create one joint block of data. One can call them as follows:

family[0], 0 – 0-th displacement from the beginning of the data block

family[1], 1 – displacement of one floating-point number from the block beginning family[2], 2 – displacement of two floating-point numbers from the block beginning EXAMPLE:

int

a[3];

a[0] = 1; a[1] = 10;

a[2] = a[0] + a[1];

4) char

*names[ PERSONS ] = {"mummy", "daddy", "me"}; Declaration of a 3-element table consisting of addresses to strings of characters (texts, captions) and the same time initialization of memory locations specified by these addresses by writing to them the words: ”mummy”, ”daddy” and „me”.

5) equation( budget, family ) – call to the function equation() and transferring to it the value of variable budget (copied from memory) and the address to the beginning of memory block where the table family is stored, e.g. three floating-point numbers: family[0], family[1], family[2].

Inside the function this table is known (denoted) as members. Since the starting address of both tables is the same, we have:

members[0] = family[0]

members[1] = family[1]

members[2] = family[2]

Calculated income of each family member is put into memory in the following way: member[0] = 1.00 * meanval; … and so on …

6) Control

instruction

for:

for( initialization1, condition2, operation4 )

{ set of instructions 3 }

Execution

order:

a)

do

initialization

b)

check

condition2

c) if it is fulfilled, then perform set of instructions 3;

otherwise END of the instruction for

d)

do

operation4

e) return to point b)

In our program for consecutive values 0, 1, 2 of the variable „i”, values of the table elements names[i] (”mummy”, ”daddy” and „me”) and family[i] (500.150, 625.187, 375.112) are displayed: person no 0, i.e. mummy = 500.150

person no 1, i.e. daddy = 625.187

person no 2, i.e. me = 375.112

7) Control

instruction

if:

if ( condition )

if ( condition )

|| a simplified

{ instructions set A }

{ instructions set A } || version

else

{ instructions set B }

Execution

order:

a)

check

condition

b) if it is fulfilled, then perform instructions set A

c) otherwise, perform instructions set B

In our program, since family[0] > family[2] (500.150 > 375.112), the caption ”Something is wrong ! I have less than mummy !” will be displayed on the screen.

Examples of complex logical conditions:

AND (condition1 && condition2)

e.g. if( (a>1) && (b<2) )

OR (condition1 || condition 2)

e.g. if( (a>b) || (b>c) )

8) Other

control instructions:

while( condition )

| do

e.g. int i; i = 10;

{ set of instructions }

| { set of instructions }

do

-----------------------------

|

while( condition )

{ i = i-1; }

a)

check

condition

|

-----------------------------------

while( i > 0)

b) if it is true ,

| a)

perform

set of instructions

then

perform

set of instructions |

b) check condition

c) return to point a)

|

c) if it is true, then return to point a)

goto LABEL

| switch( expression )

e.g. char c; c = getchar();

...

|

case constant expression: { instr } switch( c )

LABEL:

|

default:

case ‘a’: printf(”a”); break;

|

case ‘b’: printf(”b”); break;

|

default: printf(”NOT a, NOT b”);

9) Bit operators are very similar logical operators:

AND

=

&

e.g. c = a & b (AND of corresponding bits of numbers a and b) OR = |

e.g. c = a | b (OR ......)

XOR

=

^

e.g. c = a ^ b (XOR ....)

Binary shift of a number:

>> − right e.g. b = a >> 1 (shift bits of a − 1 bit right, now b is 2 times smaller)

<< − left e.g. b = a << 1 (shift bits of a − 1 bit left, now b 2 times bigger) e.g. c = a << b (shift bits of a − b bits left, now b is 2b times bigger)

*/

/* Example 1 ver. 6 – argument values from command line

*/

/* Starting program:

e1_6 <number> <Enter>

*/

/*

e.g.: e1_6 1500 <Enter>

*/

#include <stdio.h>

#include <stdlib.h>

#define PERSONS 3

void equation( float money, float members[] ); // my numerical function

/* main program ------------------------------------------------------------------------ */

main(argc, argv) /*

argc – number of parameters, now argc = 2

*/

int argc;

/* parameter 1 - argv[ 0 ] = program name */

char *argv[];

/* parameter 2 - argv[ 1 ] = budget value

*/

{

float

budget;

float

family[ PERSONS ];

char

*names[ PERSONS ] = {"mum", "dad", "me"};

int

i;

if (argc < 2)

// checking number of arguments,

{

// should be equal two

printf("\n Error! Program call: e1_6 <number> \n"); return(0);

}

// conversion of string of ASCII codes

budget = atof( argv[ 1 ] ); // into floating-point number and using it

// for setting the value of variable budget

printf( "\n budget = %7.3f \n", budget );

equation( budget, family );

printf( "\n" ); // new line on the screen

for( i=0; i<PERSONS; i++)

{

printf( "person no %d, e.g %s = %7.3f \n", i, names[i], family[i] );

}

printf("\n"); // new line on the screen

return(0);

}

/* my auxiliary function ----------------------------------------------------------------- */

void equation( float money, float members[] )

{

float meanval;

// inner auxiliary variable

meanval = money/PERSONS;

*members++ = 1.00 * meanval; // set value, increment pointer value

*members++ = 1.25 * meanval; // set value, increment pointer value

*members = 0.75 * meanval; // set value

}

/* PROGRAM DESCRIPTION

Transferring parameters values to the program directly from OS command line is very frequently used (in blue – program name, in red – parameter values always transferred to the program as a sequence of ASCII codes):

edit program.c

gcc

program.c

For example, in programs c9_3.c, c9_4.c and c9_5.c this method is used for choosing recording parameters for audio WAV files:

c9_5 <name.wav> < 44/32/24/22/16/11/8 > < s/m > < 16/8 >

|

|

|

|

|

|

|

|

|

sampling

|

number

|

frequency

|

of bits

name

in kHz

|

per sample

of a WAV

Mono

file

Stereo

e.g.

c9_5 test.wav 44 s 16

=

file test.wav, 44 kHz, stereo, 16 bits

Since parameters values are transferred to the program as a sequence of ASCII codes, they have to be changed inside the program into binary numbers (int, long, float, double): i = atoi( argv[ 1 ] );

// ASCII to integer

f = atof( argv[ 2 ] );

// ASCII to float

*/

/* Example 1 ver. 7 – reading arguments values from file */

#include <stdio.h>

#include <stdlib.h>

#define PERSONS 3

void equation( float money, float members[] );

/* main program -------------------------------------------------------------------------- */

main()

{

FILE *FileIn, *FileOut;

// declaration of file handles FileIn, FileOut

float

budget;

float

family[ PERSONS ];

char

*names[ PERSONS ] = {"mummy", "daddy", "me"}; int

i;

// connect handles to files

FileIn = fopen( " in.dat", "r" ); // open file in.dat for reading FileOut = fopen( " out.dat", "w" );

// open file out.dat for writing

fscanf( FileIn, "%f", &budget);

// read from file (handle FileIn)

fprintf( FileOut, "budget = %7.3f \n", budget ); // write to file (FileOut) equation( budget, family );

// calculate how many to whom

for( i=0; i<PERSONS; i++)

{

fprintf( FileOut, " %s = %7.3f \n", names[i], family[i] ); // write

}

fclose( FileIn );

//

close file (handle FileIn), so in.dat

fclose( FileOut );

// close file (handle FileOut), so out.dat

return(0);

}

/* Order of operations:

1) define handles to files,

2) open appropriate files for reading (”r”), writing (”w”), reading & writing (”rw”) and connect them to handles,

4) read from files and write to files,

5) close

files.

*/

/* Example 1 ver. 8 – structures or complex variables */

#include <stdio.h>

#define PERSONS 3

// DECLARATION OF THE STRUCTURE person

// Example of initialization of complex variable "x"

struct person {

// having the structure person

char name[10];

// struct person x;

// type declaration of x

float money; // strcpy( x.name, "daddy"); // set name of x

};

// x.money = 500.123;

// set money of x

void equation( float money, struct person anyfamily[] );

// main program ---------------------------------------------------------------------------

main()

{

// tables of variables with structure person

float budget = 1500.45;

// smiths[0].name

struct

person smiths[ PERSONS ];

// smiths[0].money

char *name[ PERSONS ] = {"mummy", "daddy", "me"}; int i;

for( i=0; i<PERSONS; i++ )

// The same more simple:

{

// smiths[0].name = names[0];

strcpy( smiths[i].name, name[i] ); // smiths[1].name = names[1];

}

// smiths[2].name = names[2];

equation( budget, smiths );

// calling function that divides family income

printf("\n");

for( i=0; i<PERSONS; i++)

// print on the screen: who, how many PLNs

{

printf("person no %d, e.g. %s = %7.3f \n", i, smiths[i].name, smiths[i].money);

}

printf("\n");

getchar();

return(0);

}

// my auxiliary function --------------------------------------------------------------------

void equation( float money, struct person anyfamily[] )

{

float meanval; // auxiliary inner variable

meanval = money/PERSONS;

anyfamily[0].money = 1.00 * meanval;

anyfamily[1].money = 1.25 * meanval;

anyfamily[2].money = 0.75 * meanval;

}

/* PROGRAM DESCRIPTION

In C language one can define structures = multi-variables = complex variables composed of simple ones.

struct multivariable {

// declaration of a structure having name ”multivariable”

int a;

// it consists of: one integer variable a

float b;

// one float variable b

char c;

// and one character c

};

struct multivariable x;

// declaration of a variable “x” having structure ”multivariable”

x.a = 1;

// initialization of sub-variable „a” of the variable „x” (int) x.b = 1.2345;

// initialization of sub-variable „b” of the variable „x” (float) x.c = ‘r’;

// initialization of sub-variable „c” of the variable „x” (char) Pointer (address) to complex multivariables can be sent to a function, e.g.

myfunction( & x );

// calling a function, sending a pointer (address)

void myfunction( struct multivariable *y)

// function definition

{

(*y).a = 1;

// differently: y->a = 1;

(*y).b = 1.2345;

// differently: y->b = 1.2345;

(*y).c = ‘r’

// differently: y->c = ‘r’;

}

We can define tables of complex variables (multivariables), e.g.:

struct

multivariable x[10];

x[0].a = 1; x[0].b = 1.2345; x[0].c = ‘r’;

Stuctures can be tree-like embedded, i.e. one simple structure can be a part of any more difficult structure. For example, the structure address can used as a brick in structures patient, student, ...

struct student

{

struct

address {

char surname[30];

char city[20];

char name[20];

long code;

struct addreds adr;

char street[40];

int age;

int number;

int height;

long flat;

} zm;

};

zm.adr.code = 30059;

*/

/* Example 1 ver. 9 – dynamic list of family members */

/* see lecture no 7 and 8 */

#include <stdio.h>

#include <stdlib.h>

#define PERSONS 3

//

DECLARATION

OF

THE

STRUCTURE

person

struct person { // Example of initialization of variable x having structure person: char name[10]; // struct person x;

float money; // strcpy( x.name, "daddy"); // set name of x

};

// x.money = 500.123;

// set money of x

struct node { // DECLARATION OF THE NODE OF ONE-DIRECTIONAL LIST

struct person anybody; // inside the node there is a variable having structure person struct node *next; // and an address to the next node

}; // e.g. struct

node n;

//

strcpy(n.anybody.name,"daddy");

// n.anybody.money = 500.123;

//

(*n).next = ?; or n->next = ?;

typedef struct node *ADRnode; // ADRnode is now a name of a new type,

// e.g. address to node

void equation( float money, ADRnode list ); // declaration of function call

// main program ---------------------------------------------------------------------------

main()

{

float budget = 1500.45; // type declaration and value initialization ADRnode list, n, n0, n1, n2; // declaration of 5 addresses to nodes int i; // declaration of auxiliary variable

// dynamic memory allocation for 3 nodes

n0 = (ADRnode) malloc( sizeof( struct node ) );

n1 = (ADRnode) malloc( sizeof( struct node ) );

n2 = (ADRnode) malloc( sizeof( struct node ) );

list = n0; // list = address of the first node

strcpy(n0->anybody.name,"mummy"); // set person name in node 0

strcpy(n1->anybody.name,"daddy"); // set person name in node 1

strcpy(n2->anybody.name,"me"); // set person name in node 2

// every node, except the last one, is pointing out to the next node n0->next = n1; // node 0 is pointing out to node 1

n1->next = n2; // node 1 is pointing out to node 2

n2-> next = NULL; // node 0 is pointing out to nothing

equation( budget, list ); // the function call

printf("\n");

// new line

n = lista; i = 0; // set pointer to the list beginning

while( n != NULL ) // print income of family members

{

printf( "person no %d, e.g. %s = %7.3f \n",

i, n->anybody.name, n->anybody.money );

n = n->next; i++; // set pointer to next node

}

printf("\n");

// new line

getchar();

// wait for a character from the keyboard

free( n0 ); // free memory of the nodes

free( n1 );

free( n2 );

return(0);

}

// auxiliary my function -----------------------------------------------------------------

void equation( float money, ADRnode n )

{

float meanval; // auxiliary inner variable

meanval = money/PERSONS;

n->anybody.money = 1.00 * meanval; // money in node 0

n = n->next; // address to next node

n-> anybody.money = 1.25 * meanval; // money in node 1

n = n->next; // address to next node

n-> anybody.money = 0.75 * meanval; // money in node 2

}

Program debugging in Dev-C++

0) Initialization:

Tools Æ Complier options Æ Settings Æ Linker:

Set: Generate debugging information ON

Tools Æ Complier options Æ Settings Æ Optimization NO

1) Open (load) or Edit (write) a program.

2) Execute Æ Compile (find and remove errors in this program).

3) Execute Æ Rebuild All (build a program to be debugged)

4) Debug Æ Debug.

5) Go with cursor to the selected program line.

6) Execute program to the cursor: Run to Cursor (Shift+F4)

7) Add variables to the watch (their values will be observed):

a few times Add watch (F4)

8) Add program breakpoints:

select lines with the cursor + Toggle Breakpoint (CTRL + F5)

9) Execute the next program line:

Next Step (F7) – without coming into the function body

Step Into Function (Shift + F7) – with coming into the function body 10) Continue program execution to the next breakpoint:

Continue (Ctrl + F7)

Run to Cursor

Shift + F4

Add

watch F4

Toggle Breakpoint

Ctrl + F5

Next

Step

F7

Step

Into

Shift

+

F7

Continue

Ctrl

+

F7