Sie sind auf Seite 1von 143

BRIEF INTRODUCTION

TO C/C++ LANGUAGE
Created by Tom Koudela

C is older language, without type checking, without objects, requires


more strict definition and declaration of variables

C++ is newer language which includes type checking, definition of


variables at arbitrary place of code, objects, templates, exceptions, and
namespaces.

C language is subset of C++.

BOTH ARE CASE SENSITIVE


!" #tru$ture o% t&e C++ 'ro(ram

Program is usually decomposed to several logical blocks of functions,


which are written together in one file.

The file with block of functions is called module and it has .cpp
extension.

Each module should has an include(header) file, where the prototype


declarations of each function are written.

nclude file also contains declarations of variables and definitions of


data types.

!sual include file extension is .h ".hpp for include files with class
definitions#.
!"!" #tru$ture o% t&e I)$lude F*le

$efinition of an identification symbol "macro# of given header file

$efinition of symbolic constants and macros

$efinition of types

$eclaration of global variables "keyword extern#

$eclaration of function prototypes and%or classes

nclude files should never contain definitions which allocates memory

ncluding other include files should be maximally reduced.

&ymbolic constant ' #define PI 3.1415


(fter this definition symbol PI can be used instead of real constant for )udolfs
number and symbol occurrence is replaced by number *.+,+-.

&ymbolic macro ' #define sqr(x)((x)*(x))


occurrence of sqr(a) is replaced by ((a)*(a))

&uppression of multiple including of header files . the body of the include


file should be encapsulated into following directives'
#ifndef UNIQUE_HEADERFILE_ID_SYMBOL
#define UNIQUE_HEADERFILE_ID_SYMBOL
.
body of the header file
.
#endif

UNIQUE_HEADERFILE_ID_SYMBOL could be defined for example as a


header file name joined with _H extension
!"+" #tru$ture o% t&e ,odule -C++ F*le.

(ll necessary system or library include files are included using


#include <header_name>

(ll necessary user include files are included using


#include "header_name"

$efinitions of local function prototypes and data types

$efinitions of global variables "keyword extern#

$efinitions of local module variables "keyword static#

$efinitions of functions

/hen program starts, it calls function with name

main() or int main(int argc, char *argv[])

The function main should be in separate module which is usually


called main.cpp or program_name.cpp.

Thus the name of any function may be arbitrary except of main and
0%011 keywords
"234 . main{} program-end program#
+" C Key/ord0
auto automatic variable . today unused
break breaks loops and switches
case denotes case of switches
char character type +5 si6e
const constant modifier of type
continue skip to next loop step
default denotes default case of switch
do begin of do7while loop
double real type with 85 si6e
else else statement of if-else
enum enumeration type
extern type modifier for global variables
float real type with ,5 si6e
for beginning of for loop
goto jump statement . almost never used
if beginning of if-else statement
int integer type with ,5 si6e
long integer type with ,5 si6e "85 on 9,bit#
or integer type modifier
"long long int . 85 on *:bit#
return return from function
short integer type with :5 si6e
signed default integer type modifier
sizeof determines si6e in bytes of variables
static type modifier for global module var
struct user defined structure composed from several other types
similar to 234 type-end type
switch beginning of switch statement
typedef definition of user types or aliases for built7in types
union similar to 234 common 7 almost unused
unsigned integer type modifier "suppression of sign#
void unknown type "pointer, parameter, return value#
volatile type modifier "system use#
while end statement of do-while loop
C++ keyword enhancement
class class type
public modifier of class data members
private modifier of class data members
protected modifier of class data members
friend modifier of class data members
this pointer to the actual instance of the object
operator function type modifier
inline function type modifier
try exception checking
catch exception catching
throw exception raise
template template of function or class
using using of declarations and%or definitions from the given
namespace or class
namesapce definition of namespace which prevents collisions of
identifiers and function%class names
1" O2erator0 a)d T&e*r 'r*or*ty
1. level (the highest)
( ) normal parenthesis
[ ] array index
-> access to class or struct members
class or struct are given by a pointer
. access to class or struct members
2. level
(type_name) type casting
& reference
* dereferencing "unary operator#
- minus "unary operator#
+ plus "unary operator#
! logical negation "unary operator#
++ increments operand by + or by si6e of type "pointers#
-- decrements operand by + or by si6e of type "pointers#
sizeof(var) returns si6e of variable var
sizeof(type_name) returns si6e of type type_name
3. level
* multiplication
/ division
% modulo of operands "rest of integer division#
4. level
+ addition
- subtraction
5. level
<< bit shift left
>> bit shift right
6. level
< or > less or greater then
<= or >= less or equal or greater or equal
7. level
== logical equal comparison
!= logical non7equal comparison
. level
& bitwise (;$
!. level
^ bitwise <=>
1". level
| bitwise =>
11. level
&& logical (;$
12. level
|| logical =>
13. level
? : ternary conditional operator "rarely used#
14. level
= assignment
-= += *= ... or any combination of logical, bitwise or
mathematical operator with =
performs operation given by the first operator with left and right
operands. The result is stored in the left operand. 2or example '
a += b is equivalent to a = a + b
a /= b is equivalent to a = a / b
15. #evel (lowest)
, operator of oblivion
3" Co)0ta)t0

$ecimal integer constant ' 19

?exadecimal integer constant ' 0x0013

>eal constant ' 1.900e+01

&tring constants "string literals#' "Hello world"


"Hello " "world"

The last hidden character '\0' of string constant is added by compiler. The
terminating character is necessary for the string length calculation and for
memory allocation. The character '\0' have to be the last character of all
strings.

0haracter constant ' 'A' or '\65'


3"! #2e$*al C&ara$ter0 a)d Co)0ta)t0

\a or \0x07 alert "bell#

\b or \0x08 backspace "moves cursor left#

\n or \0x0a new line

\r or \0x0d carriage return

\t or \0x0c hori6ontal tabulator

\\ or \0x5c backslash

\" or \0x22 quotas

NULL special integer constant that has 6ero value.

5lock of comments /* */
/* This sequence opens comment block
Body of the comment block
Following sequence closes comment block */

0omments /* */ cannot be nested

/*
/* This sequence opens comment block
Body of comment block
*/
The sequence above closes the comment block
*/ ???!!! undefined characters
4" Comme)t0

=ne line comments //


t comments the rest of line following after the comment sequence.
long temp; // temporary variable
// FILE *log; // log file
/* The previous comment removes unused variable log */
5" De%*)*t*o) o% 6ar*able0

Local variables @ local at the statement block or function.


double a; // normal variable with double precision
double *b; // pointer to double
double d[20]; // array of doubles
long i, j, k; // long integer
char c, *buffer; // char, pointer to char
// array of char with initialization string "Hello world"
char name[] = "Hello world";
vector u; // variable of user defined type vector

global module variables @ local at given module "file# but global to functions
defined in this module.
// global at one module
static long Counter;
or
long Counter;

global variables @ global to all functions in the program


2or examples see MEFEL/SRC/global.h file
// one module
double *Array; // definition (variable Array is allocated)
// at remaining modules
extern double *Array; // declaration (no memory allocation)
5"!" De$larat*o) o% U0er Ty2e0

enum is assumed to be an integer and both the symbolic names "aliases# or


integer values may be used. The yes alias is represented by + in this case.
enum answer {no=0, yes, maybe=5};

struct can be considered as a collection of data which can be of built7in or


user defined type.
struct vector
{
long size;
double *real;
};
n this case, the structure contains component size of a long type and
component real of a pointer to double type.
5"!" De$larat*o) o% U0er Ty2e0

enum is assumed to be an integer and both the symbolic names "aliases# or


integer values may be used. The yes alias is represented by + in this case.
enum answer {no=0, yes, maybe=5};

struct can be considered as a collection of data which can be of built7in or


user defined type.
struct vector {
long size;
double *real;
};
n this case, the structure contains component size of a long type and
component real of a pointer to double type.

&tructure components can be accessed either by the . operator or by the ->


operator.
Example'
struct node
{
double x, y; // 2D coordinates
};
...
node n; // variable n is type of node
n.x = 0.0; // accessing of x-coordinate
n.y = 1.2; // accessing of x-coordinate

=perator -> can be used in the case of access to the struct type via a
pointer "This approach is demonstrated in the concluding example of section
3.+#.
5"+" Ty2e Co)7er0*o)
enum answer {no=0, yes, maybe=5};
answer a;
double b;
int c;
long d;
c = int(a); // enum to int
c = int(b/d); // double to int
b = b/d; // implicit conversion to double
8" #tateme)t09 Blo$ o%
#tateme)t0

Each statement have to be separated by semicolon ;

5lock of statements have to be enclosed by pair of braces { }

Example of the code '


double x, y, z, norm; // declaration & definition of double variables
long i; // declaration & definition of long integer variable
norm = x*x + y*y + z*z; // assignment statement
i = norm >= 0.0; // assignment statement
norm = sqrt(norm); // function call
Example "similar piece of code enclosed to block#'
{
norm = x*x + y*y + z*z; // assignment statement
i = norm >= 0.0; // assignment statement
norm = sqrt(norm); // function call
; // empty statement
}
8"!" Co)d*t*o)al #tateme)t0
$im%le Conditional $tatement if( )
if (expression)
statement;
The expression in simple conditional statements which should have an
integer value. The statement is performed if the expression is non76ero.
Example '
if (i == 0)
i++; // increments i (i = i+1)
Conditional $tatement with $tatement &lock
if (i%2) // if i is even
{
c = a+b;
i--; // decrement i (i=i-1 or i-=1)
}
Com%lete Conditional $tatement if( ) else
if (expression)
statement or statement block
else
statement or statement block
Example '
double a, b, c;
long i;
a = 5.0; b = 2.0;

if (i%2) // if i is even
{
c = a+b;
i--; // decrement i (i=i-1)
}
else
{
c = a-b;
i *= 3; // i=i*3;
}
>esulting values for i@-: on input' a=5.0, b=2.0, c=3.0, i=15
>esulting values for i@+* on input' a=5.0, b=2.0, c=!.0, i=12
$witch $tatement switch( ) {}
switch (expression) {
case const_1:
statements or statement block
case const_2:
statements or statement block
default:
statements or statement block
}

Expression should be integer type and constants const_1, const_2, ... ,


const_i should be integer constants or aliases defined in enum"

Program compares expression with values of constants or aliases at each case


and performs given statement or statement block"

0ase denoted with keyword default is optional. f it is included to the switch


structure, it will be performed in addition to performed statements in the
corresponding case.

&uppression of default case can be attained by break statement which is


included into particular case statements. The break statement causes interruption
of the performed switch statement.
Example '
answer an;
switch (an) {
case no: // another possibility is case 0:
c = a+b;
break;
case yes: // coupled cases yes and maybe
case maybe:
{
i++;
break;
}
default: // performed if none of the above cases is matched
// or if the break statement misses in the
// performed case
printf( Unknown answer );
}
8"+" Loo20
#oo% while( ) {}
while (expression)
statement or statement block

expression have to be integer type

statement or statement block are performed until the


expression is 6ero.
E:am2le ;
long i = 0;
double a[5];
while (i < 5)
{
a[i] = i*i;
i++;
}
Resulting values:
a"0#=0, a"1#=1, a"2#=$, a"3#=%, a"$#=1, i=5
#oo% for () {}
for (init; expression; final)
statement or statement block

5efore loop for starts, the init statement is performed.

expression have to be an integer type and it is tested at the


beginning of each step. The loop is performed until the expression
is 6ero.

The final statement is performed at the end of loop body for each
step.
E:am2le ;
double a[100];
for (long i=0; i < 100; i++)
{
a[i] = 0.0;
}
>esulting values'
a"0#=a"1#=a"2#=....=a"%%# = 0.0, i=100 or i is no& defined
long i, j, a[100];
for (i=0, j=1; i < 100; i++, j--)
{
a[i] = j;
}
>esulting values'
a"0#=1, a"1#=0, a"2#='1, ...., a"%%#='%(, i=100, )='%%
#oo% do while () ;
do
statement or statement block
while(expression);

expression have to be an integer type

The body of the loop is performed until the expression is 6ero.


Example '
long i=10, a[11]; // dimension of array a have to be 11
do {
a[i] = i*i;
i--;
}
while(i);
>esulting values'
a"0#=no& defined, a"1#=1, a"2#=$, a"3#=%, ... , a"10#=100, i=0
2or the full initiali6ation of array a, the condition should be
while(i != -1);
<" Fu)$t*o)0

0%011 knows only functions "no subroutines as in 234 or Pascal#.


Program starts automatically with main function.

Each function returns only one value, if no return value is required, the
void return type can be specified.

The returned value need not to be stored at some variable, it can be


forgotten.

f multiple values are required to return, the function parameters,


structures, classes or pointers can be used.
<"!" De$larat*o) o% Fu)$t*o) 'rototy2e
ret_type func_name(param_1, param_2,...);
where '
ret_type type of returned value
func_name the name of given function
param_i set of parameters separated by comas.
Each param_i consists of '
type par_name
where '
type type of the given parameter
par_name name of the given parameter
Example of prototypes '
void read(void); // void parameter type means no parameters
double scalpr(double *a, double *b, long n);
long read (FILE *in);
void read(); // no parameters
read (long i); // inconsistent with C99 and C++

There are three overloaded functions which differ with the'


=
type of parameters,
=
number of parameters
&ome compilers treats the function read(long i) as returning int "according to
0 standard# while the return type have to be specified on the other compilers
according to 033 or 011 standard.

f the function does not return a value, either the void type can be specified or no
parameter type is specified.
<"+" Fu)$t*o) 'arameter0 -Ar(ume)t0.

5y default, the function parameters are passed by values.

n such the case, the compiler creates automatically local variables with given
name and type. Then it copies passed values into them and when function
finishes these variables are destroyed.

=riginal variables, whose values have been passed, remains untouched.

t is possible to overload function or operator.

n case of overloading, several functions may have the same name, but they
have to have'
> different parameter types or
> number of parameters.

Parameters can be also passed by reference.

n such cases, changes of parameters performed in the function body modify their
real values Thus these changes take effect even outside of the given function.

Parameters passed by a reference are denoted by ampersand "A#


Example '
int increment (double &x);

(lternatively, parameters can be passed by pointers. The value of pointer is passed


by value "i.e. changes inside of function does not affect pointer value outside of
function#
B!T
the value of variable referenced by this pointer can be changed.
int decrement (double *x);
E:am2le;
int increment (double &x) // passing parameter by reference
{
x+=2.0;
if (x>5.0)
return 0;
return 1;
}
int decrement (double *x) // passing by value using pointer
{
*x -= 5.0; // or x[0] -= 5.0
if (x<0.0)
return 0;
return 1;
}
void decrement (double x) // overloaded above function
{ x -= 2.0; } // x has changed value only inside this function
main()
{
double d = 1.0;
int i = increment(d); // d= 3.0, i=1
int j = decrement(&d); // d=-2.0, j=0
decrement(d); // d=-2.0
}
<"1" De%*)*t*o) o% Fu)$t*o)
ret_type func_name(param_1, param_2,...)
{
declaration of local variables
statements or blocks of statements
}
2unction header is the same as in the prototype but it is not followed by semicolon.
t is followed by pair of braces in which the function body is written.
2unction body consists of a local variables definition list followed by statements or
blocks of statements.
Example'
/*
The function returns scalar product of two vectors stored
in arrays a and b. Size of arrays is given by n.
*/
double scalpr(double *a, double *b, long n)
{
long i; // definition & declaration of the local variable
double ret = 0.0; // definition & declaration & initialization
// of the local variable

// calculation of the scalar product
for (i=0; i < n; i++)
{
ret += a[i]*b[i];
}
return (ret); // return the result
}
?" 'o*)ter09 Array09 #tr*)(0

Pointers could be treated as integer type variable whose value is BindexC at


memory allocated by system to the given program.

Pointer is represented in hexadecimal format usually

(rrays is defined by pointer of given type to the first element.

Inde" of arrays starts from # "234 from +#

$ultidimensional arrays are stored by ro%s.


"234 7 by columns#

&trings are arrays of characters "char*#.

t is necessary to count the last terminating character '\0' into the memory
allocation.

Thus the string consists of characters stored in the character array from the first
position to the first occurrence of '\0' including.

The si6e of allocated memory for string "array of char# can be greater then the
reported string length because terminating '\0' may occur at any position of
allocated array.

The s&ring leng&h is the number of characters from the array beginning to the first
occurrence of the terminating character '\0'.
$trings
Example'
char str[8];
str[0] = 'H'; str[1] = 'e'; str[2] = 'l';
str[3] = 'l'; str[4] = 'o'; str[5] = '\0';
D The length of str is -
D Einimum memory required
for "Hello" string storage
is 9 bytes.
D (dditional two bytes of
allocated memory are filled
with FG4F or not initiali6ed
Example of static array "static string#'
char *str = "Hello";
H e \0 o l l
0
x
0
4
0
0
5
1
0
x
0
4
0
0
5
5
0
x
0
4
0
0
5
4
0
x
0
4
0
0
5
3
0
x
0
4
0
0
5
2
0
x
0
4
0
0
5
8
0
x
0
4
0
0
5
7
0
x
0
4
0
0
5
6
0
x
0
4
0
0
5
9
Addresses of particular
memory bytes
emory co!te!t
str=0x040051,
*str = str[0] = 'H'
str+1=0x040052, str[1] = 'e'
str+2=0x040053, str[2] = 'l'
str+3=0x040054, str[3] = 'l'
str+4=0x040055, str[4] = 'o'
str+5=0x040056, str[5] = '\0'

( value referenced by a pointer can be obtained by the dereferencing


operator *. This operator precedes a variable name of the dereferenced
pointer.

Halues of array elements can be obtained by the indexing operator [].

( pointer to some variable "address of variable# can be obtained by


using reference operator &. This operator precedes name of referenced
variable.

$ynamical allocation of memory is done using special operator new,


deallocation of memory is done with special operator delete.
Example "for ntel architecture . )ittle Endian#'
int *a = new int[2];
a[0] = 1, a[1] = 502;
delete [] a;
1 0 0 0 0 0
0
x
0
4
0
0
5
1
0
x
0
4
0
0
5
5
0
x
0
4
0
0
5
4
0
x
0
4
0
0
5
3
0
x
0
4
0
0
5
2
0
x
0
4
0
0
5
8
0
x
0
4
0
0
5
7
0
x
0
4
0
0
5
6
0
x
0
4
0
0
5
9
Addresses of particular
memory bytes
emory co!te!t
a=0x040051, *a = a[0] = 1
a+1=0x040055, a[1] = 502
246
1
?"!" 'o*)ter Ar*t&met*$0

The pointer is physically represented by ,5 integer on *: bit systems "85 on


9, bit# and it is possible to apply arithmetics operators "+, -, ++, --# on its
value.

(pplying arithmetics to the array pointer the value of pointer is changed and
it points to another array element.

>eal integer value of pointer is incremented or decremented depending on


the added "subtracted# value multiplied by si6e of referenced type.
type *p;
p + n (void *)p+n*(sizeof(type))
Examples of pointer and pointer arithmetics'
double *a, *b; // pointers to double
double c[100]; // static double array
double pc[]; // pointer to static double array
long *id1, *id2; // two pointers to long integer
long **d; // pointer to pointer
long n = 500;
vector *v = NULL; // pointer initialized to NULL
// dynamically allocated array
a = new double[n];
// a now points to the first element of array
v = new vector; // new structure vector
id1 = &n; // id1 now points to variable n
d = &id1; // d now points to variable id1
// following lines describe access to array
// elements, all lines are equivalent
c[5] = a[0];
c[n/100] = *a;
c[*id1/100] = *a;
c[id1[0]/100] = a[0];
c[**d/100] = *a;
// following lines describe access to struct vector
v->real = new double[10];
v->size = 10;
// another form of two previous lines
*v.real = new double[10];
*v.size = 10;
b = a+2; // b points to the third element of array a
b += n/100; // b points to the eighth element of a
b = a; // b is equivalent to a, points to same allocated memory
// deallocation of array
delete [] a;
// deallocation of structure vector
delete v;
// once allocated memory has to be deallocated only once
// following line causes error because memory has been already
// released by statement delete [] a;
delete b;
!@" #ta)dard C L*brary Fu)$t*o)0

&tandard functions <stdlib.h>

Eathematical functions <math.h>

nput%output functions <stdio.h>

Time functions <time.h>

&tring and memory functions <string.h>

Processes control <process.h>


!@"!" #tdl*b"& Fu)$t*o)0

abort(), (exit() ?)

abs(x), labs(), fabs()

char* mktmp(char *)

0 memory allocation functions '


malloc(), calloc(), free(), realloc()

rand()
!@"+ ,at&"& Fu)$t*o)0

cos, sin, tan, acos, asin, atan, atan2(x, y)

cosh, sinh, tanh, asinh, acosh, atanh

pow, pow10, log, log10, exp, sqrt

fabs, floor, round

arguments of trigonometric functions are expected to be in radians


!@"1" I)2ut a)d Out2ut Fu)$t*o)0
'n%(t)o(t%(t *(nctions can +e o* three ty%es,

standard input%output ' scanf / printf

file input%output ' fscanf / fprintf

string input%output ' sscanf / sprintf

Prototypes of these functions are the same except of the first parameter.

2or the standard %=, the first parameter is omitted.

2or the file %=, the first parameter is pointer to opened file.

2or the string %=, the first parameter is pointer to string"


-ile o%ening)closing. -ile /%erations

2iles are represented by the structure FILE defined in stdio.h. !sers


almost never use this structure directly but only a pointer to this structure
"FILE *#.

The structure FILE contains an actual position in the opened file from%to
which the data are read%written. The initial position is set to the beginning or
end of file by function fopen() depending on its parameters.

Position in the file is changed by each call of fscanf and fprintf


functions or by fseek function.

The function fopen() performs opening of the file.

The function fclose() performs closing of the file.

The function fflush() performs flushing unwritten data.

0hanging position where the data are read or written is performed by the
function fseek().
E:am2le o% %*le o2erat*o)0;
FILE *in, *out, *iof, *oldf;
char fname[] = "EXAM/DAMAGE/dam1.in";
// opening text file for reading
in = fopen(fname, "rt");
// opening binary file for writing
out = fopen("input.dat", "wb");
// opening file for reading/writing
iof = fopen("input.dat", "r+");
// opening text file for writing, data will be appended
oldf = fopen("input.dat", "at");
fprintf(oldf, "My data\n"); // writing of string
fflush(oldf); // flushing buffered data
fclose(oldf); // closing file
fclose(in); fclose(out); fclose(iof); // closing files
-ormatted 'n%(t
(s/f)scanf(src, char *fmt, arg_1, arg_2, ...);

src is either pointer to structure FILE (FILE *)opened for reading or pointer to
source string "char *#

fmt is string with format description "similar to 234 7 format#

arg_i is a pointers to variable where the required data will be stored "t must have
the sufficient si6e to hold read data . by default, it is not chec&ed by the com'iler#

2or each call of fscanf is the internal file position shifted by the number of bytes
read. The position is stored in the structure 2)E which is given by src.

2or each call of sscanf, the internal string position cannot be remembered and thus
the next call of sscanf starts scanning of the string src from the string beginning
again.
-ormatted /(t%(t
(s/f)printf(src, char *fmt, arg_1, arg_2, ...);

src is either pointer to structure FILE "FILE *# opened for writing or pointer to
source string "char*#

fmt is string with format description "similar to 234 . format#

arg_i is a variable which should be printed out. (rguments have to be in the


right order which corresponds with the fmt.

2or each call of fscanf is the internal file position shifted by the number of
bytes read. The position is stored in the structure 2)E which is given by src.

2or each call of sscanf, the internal string position cannot be remembered and
thus the next call of sscanf starts scanning of the string src from the string
beginning again.

The pointer src must have enou(h memory allocated in order to store all output
variables.
-ormat $tring 0escri%tion

The format string may contain arbitrary sequence of characters except of % which
have a special meaning.

f a string literal is used for the format string than the %, \ and " characters cannot
be used.

\ denotes esca*e se+uence in a string literal, backslash can be written by \\

" opens%closes string literal, quotas " inside a string literal can be written by \"

% denotes beginning format of the printed or read variable

percent character at the output has to be denoted by %% in the format string or string
literal.

scanf functions process the % format sequence and they also try to read all
sequences of characters written in the format string which do not belong to %
format.
2ormat of printed%scanned variable is represented by % followed by format
specifiers and switches. The following specifiers are often used '

%le for double or %e float

%d for integer

%ld for long integer

%s for string

%c for character

%f for double or %f float

%g for double or %g float

%n for the storage of the number of processed characters at the input%output


to the corresponding argument

%p for pointer

% $ the I represents format specifiers d, e, f, g. The space between %


and formats specifier $ causes output of prefix space in the case of
positive value of the argument.
Example'
printf("x=% lf, y=% lf", 1.0, -1.0);
produces at the output'
x= 1.0, y=-1.0

%nd n is an integer number which specifies the width of printed field

%.ne n is an integer number which specifies the number of printed


decimal places of a real number
Examples'
%.5e prints a real value with - digit precision
%20.5e prints a real value with - digit precision to the field with
the :4 character width . unused position are filled with
spaces.
12am%le o* -ormatted 'n%(t)/(t%(t
double a, b;
long k;
answer i;
char s[10], t[5];
// open text file data.out for writing
FILE *out = fopen("data.out", "wt");
// read values from the standard input device
scanf("%le %le %ld %d %9s %4s", &a, &b, &k, (int *)&i, s, t);
// print string into a column on the standard output device
long j = 0;
while ((j<10) && (s[j] != '\0')){
printf("%c\n",s[j]);
j++;
}
// print values to the file data.out
fprintf(out, "%.10e %g %d\n%-5ld %s %15s\n", a, b, answer, k, t, s);
fclose(out);
12am%le o* -ormatted 'n%(t)/(t%(t 3
Contin(ation
&tandard input device "format string "%le %le %ld %d %9s %4s")'
&tandard output device'
s
i
g
m
a
X
0ontent of data.out (format string "%.10e %g %d\n%-5ld %s %15s\n")'
1234567890123456789012345 ... column numbers in data.out
Press E;TE>
?idden new line characters FGnF
2.000000000e+01 -5200 1
10 [MPa sigmaX
20.0 -5.2e3 10 1 sigmaX [MPa]
!!" Cla00e0 a)d ObAe$t0

Object oriented programming (OOP) consists of three basic


concepts'
1) enca*sula&ion of data and code,
2) inheri&ance,
3) *ol,mor*hism.

nheritance and polymorphism are not used in the SIF! native


code.

Enca'sulation means that data and functions operating on these


data are grouped into one data type called structure"class.

Each class has to be defined 5!T the definition of class itself


does not allocate memory

( variable of class type allocates memory and such variable is called


class ins&ance or ob)ec& of the class.

0lass data are called da&a members or class a&&ribu&es and class
functions are called me&hods.

There are two special kinds of methods which are called cons&ruc&ors
and des&ruc&ors.

Each class has defined pointer this implicitly which references to the
currently used instance of the class.

The pointer this is a hidden argument for each method and it allows
for access to data members and methods.

The main application of this pointer is in overloading of operator = or


in methods returning reference to the given object.

n class methods, it is not necessary "but possible# to reference data


members of the given class by this pointer.
!!"!" Cla00 De%*)*t*o)
class or struct class_name {
public :
declaration of variables // public members
declaration or definition of functions // public methods
private :
declaration of variables // private members
declaration or definition of functions // private methods
protected :
declaration of variables // protected members
declaration or definition of functions // protected methods
};

The declara&ion of da&a members is the same as the declaration of variables.

The declaration of method is the same as the declaration of a function prototype


known from 0.

The definition of methods is the same as the definition of a classical 0 function but
the method name is decorated by class name followed by '' operator
ret_type class_name::method_name(par_list){method body}

The declaration of class name has the following syntax'


class class_name;
The declaration of class name is useful in the case that two classes contain data
members of given classes types.
Example'
class vector; // declaration of class name
class node { // class definition
double x, z; // private data members coordinates of node
public :
void init(vector &v); // initialization of coords. from vector v
int read(FILE *in); // method reads coords. from the file in
};

private: modifier switches following class members to the private mode


i.e. only methods of given class can access these attributes. t is
default modifier for class"

public: modifier switches following class members to the public mode


i.e. whoever can access these attributes. t is a default modifier
for struct.

protected: modifier switches following class members to protected mode


i.e. only methods of given class and inherited classes can
access%call these members.

friend . declarations with the friend specifier have granted access


from outside to the *ro&ec&ed or *riva&e class members. 2unctions,
class%struct members or whole classes%structures can be declared
as friends to the given class.

static . declarations with the static specifier declares that the given
attribute%method will be created independently on the instances of
the given class. &tatic attribute has only one instance for the given
class ty'e. &tatic attributes%methods may be accessed%called even
though the given class has no instance.
Examples of friend declaration'
class node
{ double x,z; // private members accessible for the following friends
friend int search(); // global function search() is a friend
friend elem::length(); // method length of elem class is a friend
friend topology; // class topology is a friend
};
Example of static declaration'
class node
{ // private members contained in every class instance
double x,z;
// Private static data member is stored separately only once for
// the given class. In this case, it contains a counter of instances
// of the class node.
static int ninst;
public :
node() { x = z = 0.0; ninst++;}; // default constructor
~node() { ninst--; }; // destructor
// static method allows for access to the static data member
static int get_ninst() { return ninst; };
};
. . .
int n = node::get_ninst(); // call of the static method
4ood 5rogramming 5ractice

$efinitions of classes should be in separate header files or .hpp or .h.

=nly declarations of methods or definitions of inline methods should be used in the


class body "i.e. in the .hpp or .h# while the definitions of methods should be placed
at source files .cpp.
Example of vector.h'
#ifndef VECTOR_H
#define VECTOR_H
#include <stdio.h>
class vector{
public :
long n; // number of vector components
double *a; // array of component values
vector(); // default constructor
vector(long m); // constructor allocates memory for m components
void init(vector &v); // initialization of vector components from v
void read(FILE *in); // method reads components from the file in
~vector(); // destructor deallocates used memory
};
#endif
Example of vector.cpp'
#include <stdio.h>
#include "vector.h"
/* Default constructor initializes data members. */
vector::vector(){
n = 0; a = NULL;
}
/* User constructor allocates memory fro m components. */
vector::vector(long m){
n = m; a = new double[n];
}
/* Initialization of the object from the vector v. */
void vector::init(vector &v){
if (a != NULL) delete [] a;
n = v.n; a = new double[v.n];
for(long i; i<n; a[i]=v.a[i], i++);
}
/* Reading of components from the file given by the parameter in */
void vector::read(FILE *in){
for(long i; i<n; i++)
fscanf(in, "%le", a+i);
}
Example of node.h'
#ifndef NODE_H
#define NODE_H
#include <stdio.h>
class vector; // declaration of class name
class node { // class definition
// class members are private by default
double x, z; // data members coordinates of node
double *r; // array of unknown nodal displacements
public : // following methods are public
void init(vector &v); // initialization of nodal coordinates from
// the vector v
void read(FILE *in); // method reads coordinates from the file in
};
#endif
Example of node.cpp'
#include "node.h" // include header file of the given class node
#include "vector.h" // include header file for used class vector
/*
The function initializes nodal coordinates by the values
stored in the vector v.
*/
void node::init(vector &v)
{
x = v.real[0];
z = v.real[1];
}
/*
The function reads nodal coordinates from the opened text file given
by parameter in.
*/
int node::read(FILE *in)
{
return fscanf(in, "%lf %lf", &x, &z);
}
!!"+" Co)0tru$tor0 a)d De0tru$tor0

0onstructors are methods with the same name as their class type.

$estructors are methods with same name as their class type preceded by ~.

0lasses can have several constructors "overloaded# which differ with a type of
parameters but only one destructor.

5oth constructors and destructors do not return value.

f an instance of class is created, the appropriate constructor is called'


1) -efaul& (im*lici&) cons&ruc&or . automatically generated%synthesi6ed by
compiler
2) .ser defined cons&ruc&or 7 programmed by user, it allows user defined
initiali6ation%creation of the object.

0onstructors of all data members are called before the constructor body is
performed.

The co*, cons&ruc&or is defined with one parameter which is of the given class
type passed by reference.

The copy constructor should copy data members from the object of constructor
argument into the corresponding data members of the current instance.

Especially, it should 'rovide dynamic memory allocation of all attributes of


the parameter.

f the user do not specify a copy constructor and compiler finds that should be
called, it automatically creates one by the cons&ruc&or s,n&hesis . so called
shallo/ co*, cons&ruc&or,

B!T it does not allocate any dynamically allocated attributes in the class. t
only co'ies 'ointer values )addresses* not their content + "source of program
crashes in the case of automatic call of destructor for this object#

0opy constructor is required by assi(nment statement or it is called in case that


parameters of given class type are 'assed by values.

f the copy constructors are used and some class attributes are allocated
dynamically, the programmer E!&T implement own copy constructor which
performs dee* co*, of the object and takes care about correct dynamic memory
allocation and copying of the memory content.

=ur recommendation is do not 'ass classes by values and do not use


assi(nment %ith classes. nstead of this, use passing by reference "much
more faster# and a copy function.

$estructors have to dispose "deallocate# all dynamically allocated memory


of the given class.

$estructors are called each time the variable is removed. That means in the
case of delete call "controlled by programmer#,

B!T the com'iler also calls destructors of local variables


automatically when they are removed "passing function parameters by
values, leaving declaration block or function#.
Example of constructors and destructors'
class element{
public:
long *nodes;
long nnod, nndof;
matrix stiffmat;
// user defined default constructor
element() { nnod = nndof = 0L; nodes = NULL};
// user defined constructor
element(long nn){ nnod = nn; nodes= new long[nn]; };
// explicit copy constructor
element(element &e)
{
nnod = e.nnod; nodes= new long[nnod];
nndof = e.nndof;
for(long i=0; i<nnod; i++)
nodes[i] = e.nodes[i];
stiffmat.init(e.stiffmat);
};
// destructor
~element(){ delete [] nodes; };
};
Example of constructors and destructors 7 continuation'
void print_sm(element e){ e.stiffmat.print(stdout); }
void print_sm(FILE *out, element &e){ e.stiffmat.print(out); }
main{
...
...
...
...
element::element()
matrix::matrix()
=rder of calls
element::element(int)
element::element(element &)
matrix::matrix()
matrix::matrix()
a
a.stiffmat
b
copy of a
b.stiffmat
(copy of a).stiffmat
&ource of calls
element a;
element b(10);
print_sm(a);
print_sm(stdout, b);
}
element::~element() copy of a
matrix::~matrix() (copy of a).stiffmat
element::~element() b
matrix::~matrix() b.stiffmat
element::~element() a
matrix::~matrix() a.stiffmat
!!"1" ObAe$t Com2o0*t*o)9 I)&er*ta)$e

0reation of one object from the other objects is called ob)ec& com*osi&ion
class matrix
{
public:
long m, n; // m number of rows, n number of columns
double *a; // array of matrix elements
matrix (long i, long j); // user defined constructor
void init(matrix &b); // initializes object from b
void print(FILE *out); // prints the matrix to out
double &get(long i, long j); // returns matrix element i-th,j-th
};
class element
{
public:
long *nodes; // array of node numbers
long nnod; // number of nodes on element
long nndof; // number of degrees of freedom (dofs) in one node
matrix stiffmat; // stiffness matrix
element(); // default constructor
};
0nheri&ance consists in cloning of an existing class%classes and modifying of
the class content or addition of new members and methods.
class element
{
public:
long *nodes
long nnod;
long nndof;
matrix stiffmat;
element();
// assemble stiffness matrix
void assemble_stiffmat(){ printf("Element stiffmat\n"); };
};
class beam : public element
{
public:
vector memfrc; // vector of member forces
beam(); // default constructor
// assemble stiffness matrix
void assemble_stiffmat(){ printf("Beam stiffmat\n"); };
void comp_memfrc(vector &r); // compute member forces
};
n the previous example'

The class beam inherits all data members and all methods from the base class
element except of constructors, destructors and the assignment operator =.

The keyword public in the inheritance syntax provides that all inherited data and
methods remain in their original access mode specified in the base class.

The private specification in the inheritance syntax changes the access mode for all
inherited data to private.

The protected specification in the inheritance syntax changes the access mode of
inherited public and protected data to protected while the inherited private data
remains in the private mode.

The new data member memfrc was added and new method comp_memfrc was
added for the member forces computation.

The method assemble_stiffmat was redefined.

Public or protected inherited data members can be accessed in the child class methods
by the standard . or > operators.
6emory layo(t o* the o+7ects
element
beam
5ase class
$erived class
4
x
4
,
4
4
-
+
4
x
4
,
4
4
-
3
4
x
4
,
4
4
-
-
4
x
4
,
4
4
-
$
Program memory
4
x
4
,
4
4
J
+
4
x
4
,
4
4
9
3
nodes nndof
(ddresses of
particular
memory bytes
nherited data members ;ew data member
. . .
nnod stiffmat
element
::nodes
element
::nndof
element
::nnod
element::stiffmat memfrc
D
$erived class is a &,*e of base class. 2rom this point of view, the
object%pointer%reference of type of derived class can be used instead of base class
object%pointer%reference. 0onversion of object type of derived class to the base
class is called u*ca&sing
Example of upcasting'
#include "element.h"
int eleminit(int ne, char *te){
element **elems = new element*[ne];
for (long i=0; i<ne; i++){
if (te[i] == 'e')
// base class pointer corresponds to the original definition
elems[i] = new element;
if (te[i] == 'b')
// pointer to the derived class CAN replace the original type
elems[i] = new beam; // upcasting is performed
}
// compute stiffness matrix for all elements
for (long i=0; i<ne; i++)
// method assemble_stiffmat is inherited
elems[i]->assemble_stiffmat();
return 0;
}
'nheritance 3 constr(ctor and destr(ctor iss(es
D
The main issue is the order of 'ro'er constructor calls which influences the
correct object creation.
D
f the programmer do not care about it, the compiler performs constructor
synthesis from the default constructors. The default order of constructor calls is
defined as follows'
> constructor of the base class
> constructor of the class members in the order given by the class definition
> constructor of the derived class
D
The order of the constructor calls and their type can be prescribed in the
cons&ruc&or ini&iali1er lis&.
D
f the constructor initiali6er list is incomplete, the compiler calls the default
constructors for the missing ones.
D
The destructors are called in the reverse order than the constructor were called.
Example of constructor initiali6er list'
class element{
// The definition of the class element is the same as
// in the example of constructors and destructors
...
...
};
class beam : public element{
public:
double a; // cross-section area
vector memfrc; // vector of member forces
// user defined default constructor initializes element attributes
// by explicit call of user defined constructor element::element(long)
// and also explicit call of beam attribute memfrc by user defined
// constructor vector::vector(long)
beam() : element(2), memfrc(6) { a = 0.0; }
// user defined constructor initializes element attributes
// by explicit call of user defined constructor element::element(long)
// default constructor vector::vector is called for memfrc attribute by
// compiler because nothing else is specified in the initializer list
beam(double area) : element(2) { a = area; }
// destructor
~beam(){};
};
Example of the order of constructor and destructor calls'
element::element()
matrix::matrix()
=rder of calls
matrix::~matrix()
element::element()
vector::vector()
element::~element()
matrix::~matrix()
vector::~vector()
element::~element()
matrix::matrix()
beam::beam()
beam::~beam()
element *e;
beam *b;
e = new element;
delete e;
b = new beam;
delete b;
e
e->stiffmat
b->stiffmat
b
b->memfrc
e
e->stiffmat
b->memfrc
b
b->stiffmat
b
b
&ource of calls
6(lti%le inheritance
D
0lass can be derived from the multiple base classes @ mul&i*le inheri&ance
Example'
class class_name : base_1, base_2 { . . . };
Example of non7virtual multiple inheritance'
class Base {public: short x;};
class DerA : Base {public: short a;};
class DerB : Base {public: short b;};
class DerAB : DerA, DerB {public: int c;};
DerivedAB z;
z.DerA::x = 5;
z.DerB::x = 4;
Base Base
DerB DerA
DerAB
DerAB::c DerA::a DerB::b Base::x Base::x Eemory content
4
x
4
,
4
4
-
+
4
x
4
,
4
4
-
-
4
x
4
,
4
4
-
,
4
x
4
,
4
4
-
*
4
x
4
,
4
4
-
:
4
x
4
,
4
4
-
8
4
x
4
,
4
4
-
J
4
x
4
,
4
4
-
9
4
x
4
,
4
4
-
3
4
x
4
,
4
4
-
E
4
x
4
,
4
4
-
$
4
x
4
,
4
4
-
0
4
x
4
,
4
4
9
5
4
x
4
,
4
4
-
(
(ddresses of particular
memory bytes
6
8irt(al inheritance
D
Eultiple inheritance can cause problems with multiple inherited members from
the common base class. These problems can be avoided by using of vir&ual
inheri&ance which provides that each member of the common base class is
contained only once in the derived class.
Example of virtual multiple inheritance'
class Base {public: short x;};
class DerA : virtual Base {public: short a;};
class DerB : virtual Base {public: short b;};
class DerAB : DerA, DerB {public: int c;};
DerivedAB z;
z.x = 5;
Base Base
DerB DerA
DerAB
DerAB::c DerA::aDerB::b Base::x
6
Eemory content
4
x
4
,
4
4
-
+
4
x
4
,
4
4
-
-
4
x
4
,
4
4
-
,
4
x
4
,
4
4
-
*
4
x
4
,
4
4
-
:
4
x
4
,
4
4
-
8
4
x
4
,
4
4
-
J
4
x
4
,
4
4
-
9
4
x
4
,
4
4
-
3
4
x
4
,
4
4
-
$
4
x
4
,
4
4
-
0
4
x
4
,
4
4
9
5
4
x
4
,
4
4
-
(
(ddresses of particular
memory bytes
!!"3 'olymor2&*0m
D
Polymorphism solves another issue which is connected with the inheritance. n the
upcasting example, one excepts naturally that for the eleminit(2, "eb") call, the
output should be following '
Element stiffmat
5eam stiffmat
5!T in reality the output will be'
Element stiffmat
Element stiffmat
The problem is that the compiler used earl, binding for assemble_stiffmat.
Early binding means that the compiler decided at compile time that
assemble_stiffmat from the original type of elems will be called.
D
The type of upcasted dynamically allocated objects is not known at compile time and
thus the la&e binding has to be used for the intended program behavior. The late
binding for methods can be enforced by the keyword virtual which precedes
returning type of the method in the class definition.
virtual ret_type method_name(par_list);
Example of virtual methods'
class element{
public:
long *nodes
long nnod;
long nndof;
matrix stiffmat;
element() { nodes = NULL; }
element(long nn) { nnod = nn; nodes = new long[nn]; }
~element(){ delete [] nodes; }
// virtual method - assemble stiffness matrix
virtual void assemble_stiffmat(){ printf("Element stiffmat\n"); };
};
class beam : public element{
public:
vector memfrc; // vector of member forces
beam() : element(2), memfrc(6) { }; // default constructor
~beam() { }; // destructor
// virtual method - assemble stiffness matrix
virtual void assemble_stiffmat(){ printf("Beam stiffmat\n"); };
void comp_memfrc(vector &r); // compute member forces
};
Example of virtual methods 7 continuation'
#include "element.h"
int eleminit(int ne, char *te){
element **elems = new element*[ne];
for (long i=0; i<ne; i++){
if (te[i] == 'e')
elems[i] = new element;
if (te[i] == 'b')
// upcasting with late binding is performed
elems[i] = new beam;
}
// compute stiffness matrix for all elements
for (long i=0; i<ne; i++){
// method assemble_stiffmat is inherited,
// late binding is performed due to virtual keyword
elems[i]->assemble_stiffmat();
}
return 0;
}
2or the call eleminit(2, "eb"), the output will be following'
Element stiffmat
Beam stiffmat
5olymor%hism 9 r(les *or virt(al methods
D
The virtual modifier can be used for methods or destructors
D
0onstructors, static methods and friend functions must not be virtual.
D
f the method is virtual in a base class then the method must be virtual also in
a derived class.
D
5ase classes contain methods which cannot be implemented because of their
excessive abstraction and implementation of such methods is performed in
the derived classes. n such the case, the method can be declared as a *ure
vir&ual me&hod and the class containing at least one pure virtual method is
called abs&rac& class. The pure virtual method can be specified as follows'
virtual ret_type method_name(par_list) = 0;
D
The pure virtual method cannot be called and an instance of abstract class
cannot be created.
D
>eferences or pointers to abstract classes can be declared.
Example of virtual destructors . part '
// class definitions used in the example of virtual methods
#include "element.h"
#include "beam.h"
int eleminit(int ne, char *te){
element **elems = new element*[ne];
for (long i=0; i<ne; i++){
if (te[i] == 'e')
elems[i] = new element;
if (te[i] == 'b')
// upcasting with early binding of destructor is performed
elems[i] = new beam;
}
... // execution of the main code of eleminit(int, char*)
for (long i=0; i<ne; i++){
// destructor of element and beam are not virtual and it leads to
// early binding -> destructor of vector memfrc is not called and
// memfrc memory is not released -> memory leak

}
delete [] elem;
return 0;
}
delete elems[i]; // destroy used elements
Example of virtual destructors . part '
=rder of calls
matrix::~matrix()
element::~element()
delete elem[i];
elem[i]->stiffmat
elem[i]
&ource of calls
nnod, nndof
nodes
stiffmat
nodes
memfrc
matrix::m
matrix::n
matrix::a
nodes[0]
nodes[1]
vector::n
vector::a
vector::real[0]
vector::real[5]
vector::real[1]
vector::real[2]
vector::real[4]
vector::real[3]
Memory leak
due to early
binding of
destructor
Explicit
memory
deallocation
by delete
Explicit
memory
deallocation
by delete
Example of virtual destructors . part '
class element{
public:
long *nodes
long nnod;
long nndof;
matrix stiffmat;
element() { nodes = NULL; }
element(long nn) { nnod = nn; nodes = new long[nn]; }
~element(){ delete [] nodes; } // virtual destructor
// virtual method - assemble stiffness matrix
virtual void assemble_stiffmat(){ printf("Element stiffmat\n"); };
};
class beam : public element{
public:
vector memfrc; // vector of member forces
double *load; // uniform load
beam() : element(2), memfrc(6) {load = NULL;} // default constructor
~beam() { delete [] load; }; // virtual destructor
// virtual method - assemble stiffness matrix
virtual void assemble_stiffmat(){ printf("Beam stiffmat\n"); };
void comp_memfrc(vector &r); // compute member forces
};
virtual
virtual
Example of virtual destructors . part H'
// class definitions used in the example of virtual methods
#include "element.h"
#include "beam.h"
int eleminit(int ne, char *te){
element **elems = new element*[ne];
for (long i=0; i<ne; i++){
if (te[i] == 'e')
elems[i] = new element;
if (te[i] == 'b')
// upcasting with late binding of destructor is performed
elems[i] = new beam;
}
...
for (long i=0; i<ne; i++){
// destructor of element and beam ARE virtual and it leads to
// LATE binding -> destructor of beam is called -> destructor of
// vector memfrc is called consequently and memory of
// beam vector memfrc is RELEASED
}
delete [] elem; return 0;
}
delete elems[i]; // destroy used elements
Example of virtual destructors . part H'
=rder of calls
matrix::~matrix()
element::~element()
delete elem[i];
elem[i]->stiffmat
elem[i]
&ource of calls
nnod, nndof
nodes
stiffmat
nodes
memfrc
matrix::m
matrix::n
matrix::a
nodes[0]
nodes[1]
vector::n
vector::a
Explicit
memory
deallocation
by delete
vector::real[0]
vector::real[5]
vector::real[1]
vector::real[2]
vector::real[4]
vector::real[3]
Correct
explicit
memory
deallocation
by delete
due to late
binding of
destructor
beam::~beam() elem[i]
Explicit
memory
deallocation
by delete
vector::~vector() elem[i].memfrc
'm%lementation o* virt(al methods in C++
D
Each class containing at least one virtual method has automatically generated so
called vir&ual me&hod &able "HET or HT(5)E# which stores addresses of the
virtual methods.
D
The address "pointer# of HET is stored secretly into each instance of the given
class. The pointer to HET is often called HP=;TE>. Thus the si6e of each
class containing virtual methods is given by si6es of the attributes plus si6e of
HP=;TE>.
D
Hirtual methods are not called directly by their addresses but indirect calls via
V$T are performed. 0ompiler knows at compile time that the name of the
virtual method will be stored on certain position in HET.
D
0orrect virtual methods are called even thou(h the u'catin( to the base class is
performed due to the indirect call using HET. This behavior is allowed because
of HP=;TE> which is not influenced by the upcasting and remains constant.
nndof
nodes
stiffmat
memfrc
nnod
nndof
nodes
stiffmat
nnod
VPOINTER VPOINTER
elems[0] elems[1]
(rray elems
=bjects
&beam::
assamble_stiffmat()
&element::
assamble_stiffmat()
HT(5)Es
!+" O2erator o7erload*)(

The standard set of 011 operators can be overloaded similarly to the function
overloading.

=perator overloading 0(;;=T'


+# change the meaning of the existing operators "1+1 is always evaluated as 2#
:# introduce new operators like @, $, , ...
*# change the priority of the operators
,# overload operators ?:, ::, ., sizeof, #, ##, extended typecasting operators
and typeid operator.

(ll operators can be overloaded as non7static methods of the object types or as


ordinary functions except of #unction call operator (), [], =, static t$pecast
operator (type)% new and delete.

#unction call operator (), [], =, static t$pecast operator (type) can be
overloaded as non7static methods only.

new and delete operators can be overload as static methods or ordinary functions.

The syntax of declaration of the overloaded operator'


operator @(par1){...} for the unary operator defined as an ordinary
function,
operator @(par1, par2){...} for the binary operator defined as
an ordinary function,
operator @(){...} for the unary operator defined as a method,
operator @(par1){...} for the binary operator defined as a method
The symbol @ stands for the symbol of the given operator. The par1 is the left%first
operand for operators defined as functions and the right operand for operators defined
as methods. The par2 is the right operand for binary operators defined as functions
or int for postfix unary operators ++ and --.
Example of the operator overloading . '
class matrix
{
public:
long m, n; // m number of rows, n number of columns
double *a; // array of matrix elements
matrix (long i, long j); // user defined constructor
matrix (matrix &b); // explicit copy constructor
void init(matrix &b); // initializes object from b
void print(FILE *out); // prints the matrix to out
double &get(long i, long j); // returns matrix element i-th,j-th
double* operator[](long i); // returns the address of the i-th row
double& operator()(long i,long j); // returns matrix i-th,j-th element
matrix& operator +(matrix &b); // adds two matrices
matrix& operator =(matrix &b); // assignment operator
};
enum mat_type {dense, skyline, compressed_rows};
mat_type operator ++(mat_type &t); // declaration of prefix ++
mat_type operator ++(mat_type &t, int); // declaration of postfix ++
Example of the operator overloading . '
double* matrix::operator[](long i)
{
if ((i >= 0) && (i < m))
return &a[i*n];
else
return NULL;
}
double& matrix::operator()(long i, long j){
if ((i >= 0) && (i < m) && (j >= 0) && (i < n))
return a[i*n+j];
else
printf("Matrix indices out of range\n");
return 0.0;
}
matrix& matrix::operator +(matrix &b){
long i, j;
matrix aux(*this);
for (i=0; i<m; i++){
for (j=0; j<n; j++)
aux[i][j] += b(i,j);
}
return aux;
}
Example of the operator overloading . '
matrix& matrix::operator =(matrix &b){
long i, j;
if ((m != b.m) && (n != b.n)){
printf("Incompatible dimensions of matrices\n");
return *this;
}
for (i=0; i<m; i++){
for (j=0; j<n; j++)
get(i,j) = b(i,j);
}
return *this;
}
mat_type operator ++(mat_type &t){ // prefix operator (++t)
if (t < compressed_rows) return t++;
else return dense;
}
mat_type operator ++(mat_type &t, int){ // postfix operator (t++)
mat_type d = t;
if (t < compressed_rows) t++;
else t = dense;
return d;
}
!1" Co)0ta)t0 B $o)0t)e00

0onstants in 011 are much more significant than in 0. n 0 language, the keyword
const just represents variable which cannot be changed and for which a memory
is always reserved. !nfortunately, this representation does not allows for usage of
consts in ranges of arrays in 0. The 011 allows for that for built in types but not
for user defined types.
const int size=20;
char buff[size]; // error in C, but not in C++
The consts should replace constants defined by preprocessor directive #define
in 011 because type checking is performed on consts.

The keypoint for usage of consts in array definitions is whether the const has
allocated memory for storage. f the memory allocation is necessary, than it cannot
be used in arrays definitions 5!T it still behaves like a constant i.e. the content of
the variable cannot be changed. The memory is allocated if'
1)extern modifier is used "default linkage of constants is static#
:# aggregated constants "struct or class type#
*# pointer to const is required "memory has to be reserved#

Pointers to constant can be defined like follows'


const int size=20;
const int* psize1=&size; // pointer to constant
int const* psize2=&size; // pointer to constant alternative def.
// the following line is invalid
// *size = 5;

0onstant pointers can be also defined in 011.


int size;
int* const psize=&size; // constant pointer
int buff[5];
// the following line is invalid
// psize = buff;

The only exception from the type checking is string literal where the assignment of
pointer to the array of constant characters is permitted to the pointer to non7constant
character.
char* str; // ordinary pointer to the character type
str = "Hello"; // str refers to the 'H' in the string Hello

The const specifier is also used for function arguments where it denotes that the
function does not modify their value inside function body. (rgument type of pointer
to a constant or constant reference are the most common used cases.
char* f(const char *str); // str[i] = 'a'; cannot be used within f()
char* g(const matrix &b); // b.get(i,j)=5.0; cannot be used within g()

=rdinary constants defined inside a class corresponds rather to 0 definition. 2or each
instance of the class, the memory is reserved for each const and all constants have
to be initiali6ed in the constructor initiali6er list. (fter initiali6ation, the value of the
constant remains the same during all existence of the instance. Thus the value of class
constants is set at run&ime.
class vector{
public:
const long n;
double *a;
vector(long size) : n(size) {a = new double[n];};
};

Com*ile'&ime constants at classes can be specified using static modifier. n such


the case, the 011 rules for constants are used in this case and for built in types no
memory is reserved.
class vector{
public:
static const double pi=3.14159265;
double angle_degrees(const vector &v);
};
!1"! Co)0ta)t0 /*t&*) $la00e0

nstance of class can be defined to be constant also. n the case of constant object,
ordinary methods cannot be called but only cons&an& me&hod. 0ompiler checks each
call of method whether it is constant and it also checks that the data attributes are not
changed in the definition of the constant method.
class vector{
public:
static const double pi=3.14159265;
const long n;
double *a;
vector(long size) : n(size) {a = new double[n];};
vector(long size, double *v) : n(size) {a = v;};
double angle_degrees (const vector &v) const; // constant method
};
const double[2] e = {1.0, 0.0};
const vector a(2, (double*)e);
vector b(2); b.a[0]=1.0; b.a[1]=1.0;
double phi = a.angle_degrees(b);
phi = b.angle_degrees(a); // this line is valid even if angle_degrees
// would not be constant method

(ll temporary objects are assumed to be constant "temporary objects are created by
passing arguments by value and returning objects by values from the methods#.
!3" Name02a$e0

2ames*aces help to solve problems with conflicts of type or variable names in the
large projects or in case of merging two independent projects together. =ne
namespace can involve several class definitions, several variables declarations or
another namespaces. The syntax of the namespace is like follows'
namespace ns_name {}
Example of namespace definition'
namespace MatVecCalc{
class vector{ public:
long n;
double *a;
double norm();
double dotprod (const vector &v);
};
class matrix{ public:
long m, n;
double *a;
matrix(long nr, long nc);
};
}

( namespace definition can be placed only at global scope, or nested within


another namespace.

;amespaces work similarly to nested classes but a namespace definition can be


concatenated over multiple header files using a syntax with the same name for the
given namespace.

Each module "cpp file# contains one unnamed namespace that can be added to by
namespace without identifier i.e. namespace {...}

Eembers of the given namespace can be accessed by the fully qualified name with
scope resolution operator ::, using directive or using declaration.
Example of using namespaces "assuming the previous definition EatHec0alc#'
double MatVecCalc::vector::norm(){ // fully qualified method name
double norm = 0.0;
for (long i=0; i<n; i++)
norm += a[i]*a[i];
return norm;
}
Example of using namspeces 7 continuation'
using namespace MatVecCalc; // using directive
// all declarations from the MatVecCalc can be used unqualified
double vector::dotprod (vector &v){
double ret=0.0;
for (long i=0; i<n; i++)
ret += a[i]*v.a[i];
return ret;
}
or
using MatVecCalc::vector; // using declaration
// declaration of class vector from the MatVecCalc
// can be used unqualified
double vector::dotprod (vector &v){
double ret=0.0;
for (long i=0; i<n; i++)
ret += a[i]*v.a[i];
return ret;
}

f the header file is included %ithout the suffix .h than the the using directive
or fully qualified names have to be used for standard library functions'
#include <cmath> // math.h C standard library
#include <iostream> // iostream.h C++ standard library

double phi=std::acos(0.2); // fully qualified name


or
using namespace std; // using directive
double phi=acos(0.2); // unqualified name

( line with system header file included %ith the suffix .h


#include <math.h> // math.h C standard library
#include <iostream.h> // iostream.h C++ standard library
is expanded by compiler like
#include <cmath>
#include <iostream>
using namespace std;
!3"! Name02a$e0 a)d &eader %*le0
!4" #ta)dard C++ L*brary

fstream, ifstream, ofstream "#include <fstream># 7 streams for file


input%output

stringstream, istringstream, ostringstream (#include


<sstream>) & streams #or string (char *) input"output

strstream, istrstream, ostrstream "#include <strstream># 7


streams for string "char *# input%output

cin, cout, clog, cerr "#include <iostream># 7 standard streams for


console input%output always opened

=pening of streams can be performed either by the constructor call or by the call of
open() method
!5" E:$e2t*o)0


!8" Tem2late0


!<" #ta)dard Tem2late L*brary

Templates for vector, array, queue, list, tables, autoKptr

iterators

functors
!?" Creat*)( "e:e %*le0 B l*brar*e0
$epending on the problem solved, the programming task can have two principal
results'

34ecu&able file . it can be single exe7file, several exe7files or exe7file"s# with


dynamic7link libraries "*.dll in /indows % lib*.so in )inux#
1) console5&erminal a**lica&ion 7 basic input%output interface provided by the
command line or input%output files
Pros: simple programming techniques "fprintf, fscanf, iostream#,
highly portable and fast code
'ons: not too user7friendly environment
2) a**lica&ion /i&h gra*hic in&erface . depends on the (P of the given operating
system and partially on the hardware used.
Pros: application can have highly user7friendly environment,
visual programming tools can be used for the application design
'ons: almost non7portable code "from both compiler and =& points of view#,
large overhead of source codes due to graphical environment

Librar, file . library file contains data and code of functions which are used for
similar purposes "solution of equation systems, export of results to the different file
formats, L #. These files can be provided by the compiler package "&tandard 0%011
library#, third7party libraries "numerical or graphic libraries# or it can be generated
from the user source files due to better management of the source code and%or due to
re7usability of code. There are two basic types of the library files'
1) 6&a&ic librar, 7 "*.lib in /indows or lib*.a in )inux#
These files are linked to the exe7file at compile time.
Pros: simple handling of the application "one exe7file, no additional source
code#, minor compatibility issues due to changes in =& or third7party
libraries
'ons: large%huge executable files slower application startup, higher
memory requirements, all application has to be recompiled due to
change in one library.
1) -,namic'lin7 librar, 7 "*.dll in /indows or *.so in )inux#
$ynamic7link library files are shipped together with the exe7files and they are
"un#linked%"un#loaded at runtime on request.
Pros: compact si6e of exe7file, program update can be done without
recompilation of the executable files, dynamic management of the
memory occupied by the program.
'ons: compatibility issues due to third7party or =& $)) libraries, additional
code is necessary for handling of $)) "loading%unloading%registering#
0ompilation of the source file is decomposed into three steps'
,RE,ROCESSIN- CO$,I.ATION .IN/IN-

8re*rocessing . all symbolic macros are replaced by their values, all header files are
included into the source file.
Preprocessing is performed by the *re*rocessor tool. The resulting file is sent to the
compiler.
Eost reported errors of the preprocessor'
() missing )eader #ile%
*) missing pairs #if&#endif.
The postprocessor does ;=T perform s$nta+ c)ec,ing nor semantic c)ec,ing.

E.g.,the preprocessor does not detect unmatched braces in source files nor in header
files and such errors can be hardly revealed.
2or these purposes, the preprocessor usually enables output of the preprocessing
result to the text file which can be reviewed in a text editor.
!?"! Com2*le B L*)*)( 'ro$e00e0

Com*ila&ion . compiler performs on the output from the preprocessor'


() le+ical anal$sis . decomposition of the source code to small pieces called tokens
"e.g. identifiers, symbols, keywords, ...#
*) s$ntactic anal$sis 7 parse tree is created, matching of braces is checked
-) semantic anal$sis . checking of correctness of types and performed operations
>esult is often written in the in&ermedia&e code.
$epending on the compiler options, the resulting intermediate code is o*&imi1ed.
E.g., inline expansion, dead code elimination, constant propagation, loop
transformation, register allocation or automatic paralleli6ation
=ptimi6ed intermediate code is translated into the na&ive machine code and depending
on the compiler options, the debug informa&ions are generated and added to the output
binary file.
>esulting binary file of the whole compilation is called ob)ec& file "*.obj in
/indows % *.o in )inux#.
The object files contain executable instructions in machine code but only with rela&ive
addresses or s,mbols they are ;=T stand7alone executable.

Lin7ing . resulting target is created by the lin7er, which assembles object files
generated by the compiler and used libraries together. The linker creates either exe7
file or library"ies#.
n the case of exe7file and dynamic7link libraries, the relative addresses in the used
object files are relocated to the final addressing system and the linker generates so
called reloca&ion &able.
n the case of static libraries, the object files are connected into one large file and the
table of the library content is appended. (ddresses still remain relative.
!nknown function or global variable are the most reported errors of the linker.
+# The function is reported as unknown in the cases'

missing o# corresponding librar$ #ile

missing o# corresponding object #ile


:# The global variable is reported as unknown in the case of missing defini&ion of
&he global variable, i.e., in just one file, the global variable must be declared
/T?=!T external keyword.
1.h
3.cpp 1.cpp 2.cpp
2.h 3.h
4.h
6.cpp 4.cpp 5.cpp
5.h 6.h
0ompiler 0ompiler
3.obj 1.obj 2.obj
main.cpp
main.obj
)inker
6.obj 4.obj 5.obj
)inker
Program.exe
auxlib.lib
C:\Projekt\prog\src
C:\Projekt\prog\auxlib\src
Target Program.exe Target auxlib.lib
MS Visual C++ Professional full edition for MS Windows development
1) integrated development environment,
2) 32-bit & 6 bit !ode generation for MS Windows platform onl",
3) grap#i!al debugger wit# remote debugging !apabilities
) Windows forms designer
$) MS Visual C++ Express - free edition for MS Windows development
%onl" 32-bit !ode generation, no remote debugging, no M&' and ()* libraries)
Embarcadero C++ Builder %former Borland '++ ,uilder)
1) integrated development environment,
2) 32-bit bit !ode generation for Windows and Ma! -S .,
3) grap#i!al debugger wit# remote debugging !apabilities
) /(0 tools for visual programming
GCC 123 '4'++ 'ompiler, free !ompiler %123 15* li!en!e) used in *inu6 environment espe!iall" %also Windows !lones)
1) !ommand line !ompiler
2) 32-bit & 6-bit !ode generation for *inu6 and t#e same for MS Windows wit# some limitations
Open Watcom C++ %former Wat!om '++) - free !ompiler '4'++ under t#e S"base -pen Wat!om 5ubli! *i!ense version 178
1) 9ntegrated development environment
2) 32-bit !ode generation for MS Windows, -S42, 0-S and *inu6
3) grap#i!al debugger wit# remote debugging !apabilities
Mars Digital C++ %former S"mante! '++)
1) integrated development environment,
2) 32-bit bit !ode generation for Windows,
3) grap#i!al debugger
!?"+ ,o0t U0ed Com2*ler0
There are two main principles for handling with multi7file projects in 0%011.

!tility 9a7e . application is created according to rules written in so called 9a7efile.


+# These rules are written in the Eakefile script language that was developed for !nix
originally.
:# Even very large projects can be handled effectively, with good knowledges of the
Eakefile language and good system of Eakefiles.
*# There are many clones and frameworks for Eakefiles which simplifies the creation
and maintenance of the project "cmake, automake, ...#.

0n&egra&ed develo*men& environmen& "$E# . integrates managing, editing,


compilation and debugging of source files into one "graphical# "intuitive# environment.
These environments can be either shipped with the given compiler "E& Hisual &tudio,
011 5uilder, =pen /atcom, Ears $igital 011# or standalone which can be supplied
with arbitrary command line compiler ";et5eans, M$evelop, Eclipse, L#.
There are also tools for version control of source files'
+# 0H& "/indows%)inux 7 =pen/atcom, Hisual &tudio, command line compilers#
:# &H; "/indows%)inux 7 command line compilers#
!?"1 I)0*de De7elo2me)t E)7*ro)me)t

Each application can be composed from several exe7files, static libraries "*.lib,
lib*.a#, dll7libraries "*.dll, lib*.so# and other resources. Nenerally, the
following steps are necessary in the particular $Es for the creation and managing of
the application'
+# 0reate new *ro)ec& "solu&ion . E& H&011%*ro)ec& grou* . 011 5uilder# 7 it
will contain all necessary files for the application build7up.
:# 0reate particular *ro)ec& &arge&s "*ro)ec& . E& H&011%*ro)ec& . 011 5uilder# .
each target represents one binary result such as exe7file, static library "*.lib,
lib*.a#, dll7library "*.dll, lib*.so# or other resource files.
*# &etup of &arge& o*&ions . the following items have to be specified especially'

type of the binary result "console executable, windowed executable, static


library, dll7library, ...#

output folder for object files "*.obj, *.o#

compiler options "path of include files, path of static libraries, debug info
options, optimi6ing switches, type of processor, L#

target dependencies . specification of the other targets whose results are


necessary for creation of the given target "=pen /atcom $E has automatic
creation of target dependencies#
,# :dd source files *.cpp|h "or other resources# to the individual targets.
!?"3 O2e) Cat$om !"? IDE
$E is launched by ide.exe
&tartup screen of $E' $ialog for 2e/ 8ro)ec&'
0reating of 2e/ ;arge& in the project'
&election of the output target folder
&pecification of the target type
(dding of new%existing source files'
>ight click menu
0alled automatically for empty project
&ource files options menu'
Paths for include files
$ebug options
=ptimi6ing options'
>ight click menu
Target linking option set'
0ompile file
2orce remake of all files in target
$ebug target
>un target Eake target
$ebug%>elease set of switches
?elp on compiler error message'
>ight click menu
2orce remake of all targets in project
Eake all targets in project
?andling with all targets'
+@" Debu((*)( B debu((er0
$im%le de+(gging techni:(es

Log messages, log files . errors are written to the output device "stdio%stderr%log file#

3rror handlers . special functions for error handling called after an error occurs.
Error context is indicated by the return value "error code# or%and error flag variable
"global variable#. This system is used in 0 library . errno, perror and
strerror.
Pros' fast execution, smaller generated code
'ons' large amount of source lines for the error handling "testing of return values#,
hard maintenance of the source code.

34ce*&ions . advanced method of error handling introduced in 011


Pros' unified approach built in language, the algorithm and error handling
can be distinguished clearly
'ons' huge amount of generated code, slower execution

Condi&ional com*ila&ion < source code used for the debugging purposes should be
made optional by the directive #ifdef __DEBUG__ #endif.

Commen&ing ou& . parts of source code can be commented out in order to identify the
source of error in the large code.
&oftware debugging tools'

0ebu((er . special software environment that allows for'


+# code execution and stepping over%into particular source lines,
:# stopping code execution on selected source lines or on selected conditions
*# inspecting%watching the content of variables,
,# memory viewing
-# restarting of the program
9# remote execution and controlling of the debugged program

$emory debu((er . a special kind of debugger which supports revealing of


memory errors like'
+# using of uninitiali6ed memory
:# reading%writing outside of dynamically allocated memory
*# memory leakage caused by incorrect deallocation of memory
;dvanced de+(gging techni:(es

$ebuggers use special informations connected with the generated machine code. The
generation of these debug informa&ions5s,mbols can be turn on%off within the
compiler. These informations are stored either directly in the exe7file or in the
separate file. The list of the most used debuggers follows'
+# /;$5N , E& Hisual &tudio . E& /indows, enables Edit70ontinue debugging
:# 011 5uilder debugger . E& /indows, enables Edit70ontinue debugging
*# /(T0=E debugger . E& /indows
,# N$5 . )inux
-# H()N>;$ . )inux memory debugger
9# T=T()HE/ . )inux, !nix, Eac =&< "even for debugging of parallel codes#

2ormats of debug symbols and corresponding file suffix in the case that they are
generated separately'
+# 0odeHiew . old E& format O.$5NP . E& Hisual &tudio -.4, /atcom 011,
:# Program $atabase . new E& format O.P$5P . E& Hisual &tudio 9.4 and later
*# T$& . 5orland Turbo $ebugger &ymbol O.T$&P . 011 5uilder, 5orland 011
,# $/(>2 . &tandardi6ed debugging format O.&QEP . /atcom, N$5, TotalHiew
The following terminology is used in most debuggers'

=rea7*oin& . &etting breakpoint on the given source line makes the program
stop at this line each time.

Condi&ional brea7*oin& . &etting conditional breakpoint on the given source


line makes the program stop at this line each time the condition is met. The
condition can be specified either by the pass counter or any other arbitrary
condition like in the 011 language. &N;20(;T)Q &)=/& $=/; T?E
P>=N>(E E<E0!T=;R

9emor, brea7*oin& . Part of memory can be specified as read or%and write


memory breakpoint. Each time the memory is read from or written to the
program stops and shows the actual line of code matching this breakpoint. t is
used for the memory debugging in case that no other memory debugging
support is available. E<T>EEE)Q &)=/& $=/; T?E P>=N>(E
E<E0!T=;R

Call56&ac7 &race5&ree . shows the actual call tree starting from the actual
function and finishing the main() function. The call tree represents the path
which was passed by the the program from the main() function to the current
source line.
The following terminology and commands are used in most debuggers'

>un%?o . runs the program until the next breakpoint or end of program

6&e*%;race over . actual source line is performed without stepping into function
call

6&e*%;race in&o . actual source line is performed and in the case of function call
the program stops at the first line of function called

>un un&il re&urn . the program runs until the return from the actual function

Local . shows the window with local variables

@a&ch50ns*ec& < displays the values of selected variables in the window

:ssembl, . shows the assembler instructions "machine code# of the given source
file%line.

9emor, . shows the window with the memory content starting from the given
address. $ifferent view to the memory content are supported usually 7 0har "8bit#,
/ord"+9bit#, $/ord "*:bit#, float, double, pointer, etc.

Das könnte Ihnen auch gefallen