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
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)
(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)
(example of C2 code usage)
00000110 = 6
00000101 = 5
00000110 = 6
--------------
+ 11111011 = −5
11111010
------------------------
+
1
1|00000001 = 1
--------------------
11111011 = −5
(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
(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;
}
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 …
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
}
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