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
• Possible program code
optimization:
e.g. high speed,
low memory requirements
Long way from an idea to its
verification
Interpreter
Short way from an idea to its
verification
Slow program execution
COMPILER vs. INTERPRETER (2) –
program development
Linker
Text/Program
editor
prog.c
COMPILER
prog.obj
my.lib
prog.exe
Lib Maker
Consolidation
f1.obj, f2.obj,
...
system.lib
Operating
system
execution
of the whole
program
my.dll
static (lib)
and dynamic (dll)
linking libraries
Interpreter
linii
INTERPRETER – a separate program / application
Line
INTERPRETER
Line
executor
Line
editor
Program
= set of lines
1
2
1
2
>> ...?... (CR)
system.dll
COMPILER vs. INTERPRETER (3)
speed of development vs. speed of execution
Assembler
time of program
development
(debugging)
time of program
execution
C/C++ language
Matlab
Simulink
ti
me
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)
+16 = 0 0 0 1 0 0 0 0
without change to
first 1, including it,
then negate all bits
-16 = 1 1 1 1 0 0 0 0
0 0 0 1 0 0 0 0 (+16)
1 1 1 1 0 0 0 0 (-16)
+
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 * 2
c
x = s
1 bit
| c
8 bits
(p)
| m
23 bits
,
⇐ c
8 bits
(p)
= c + 127, -126
≤ c ≤ 127
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
8 bits
23 bits
/*
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
float
ing-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
float
ing 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 2
b
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 ] );
//
A
SCII
to
i
nteger
f = atof( argv[ 2 ] );
//
A
SCII
to
f
loat
*/
/* 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