# Advanced Introduction to C++, Scientific Computing and Machine Learning

Claudius Gros, WS 2021/22

Institut für theoretische Physik
Goethe-University Frankfurt a.M.

# controlling the flow

• do different things depending on circumstances

# logical operators

• comparison and logics
SymbolDescriptionExamples
<  <=  >  >= less/-equal, greater/-equal if (i<=8) {}
==   !=equal, unequal if (i==3) {}
&&   ||   !logical AND, OR, NOT if ((a==0)&&(b!=3)) {}

• the outcome of a logical operation is boolean
#include <iostream>
#include <stdio.h>
#include <typeinfo>
using namespace std;

int main(int argLength, char* argValues[])   // parsing command line arguments
{
printf("type of   333          : %s\n",typeid(333).name());
printf("type of   1.0          : %s\n",typeid(1.0).name());
printf("\n");
printf("type of   argLength    : %s\n",typeid(argLength).name());
printf("type of  &argLength    : %s\n",typeid(&argLength).name());
printf("\n");
printf("type of   argValues    : %s\n",typeid(argValues).name());
printf("type of   argValues[0] : %s\n",typeid(argValues[0]).name());
printf("type of  *argValues[0] : %s\n",typeid(*argValues[0]).name());
printf("\n");
printf("type of  (1==2)        : %s\n",typeid(1==2).name());
return 0;
}


# conditional if

### conditional – if … then … else

• in C++ no 'then':
if (condition) { statements; } else { statements; }
•  c = (x) ? {y} : {z}     is a shortcut for
if (x)
c = y;
else
c = z;


#include <iostream>
#include <stdio.h>
using namespace std;

int main(int argLength, char* argValues[])
{
int a,b;
printf("\n");
printf("please enter two integer numbers: ");
cin >> a >> b;
if (a>b)
printf("ordered by size: %d %d\n",a,b);
else
printf("ordered by size: %d %d\n",b,a);
printf("\n");
//
string strOrder;
strOrder = (a>b) ? "a is larger than b\n" : "b is larger than a\n";
printf("%s",strOrder.c_str());
return 0;
}


# conditional switch; break

• switch (expression) { case constant-expression: statements; }
break : breaks loops
• enum newType {a,b,c}; defines new types via enumeration
#include <iostream>
#include <stdio.h>       // for printf
#include <cstdlib>       // for atof
#include <typeinfo>      // for typeid
using namespace std;

int main(int argLength, char* argValues[])
{
//double inputDouble  = atof(argValues[1]);    // casting string to double
//  int    inputInteger = (int)inputDouble;      // casting double to integer

int i = atof(argValues[1]);      // casting input string
switch (i)
{
case 1: printf("case 1: %d\n",i);
case 2: printf("case 2: %d\n",i);
case 3: {                       // necessary because of
int x = 333;           // this declaration
printf("case 3: %d and value of x: %d\n",i,x);
}                      // scope of 'x' ends here
case 4:
case 5: printf("case 5: %d\n",i);
break;                       //execution of subsequent statements is terminated
case 6: printf("case 6: %d\n",i);
case 7: printf("case 7: %d\n",i);
break;
default: printf("default : %d\n",i); // if no valid case is found
}

printf("\n");

// when enumerations are used in a switch statement, many compilers
// issue warnings if one of the enumerators is not handled

enum myColors {RED, GREEN, BLUE, myNiceColor, superPink};
myColors colorVariable = BLUE;        // declare a variable of type 'myColors'
switch(colorVariable)
{
case RED:   cout << "red\n";
cout << "typeid of colorVariable: "
<< typeid(colorVariable).name() << '\n';
break;
case GREEN: cout << "green\n";
cout << "typeid of colorVariable: "
<< typeid(colorVariable).name() << '\n';
break;
case BLUE:  cout << "blue\n";
cout << "typeid of colorVariable:  "
<< typeid(colorVariable).name() << '\n';
break;
}

return 0;
}


# control Flow: loop while

• while (condition) { statement(s); }
• run program with time ./a.out
#include <iostream>
#include <stdio.h>    /* for printf */
#include <ctime>      /* runtime measurment (from c) */

using namespace std;

int main()
{
clock_t startingTime = clock();
clock_t actualTime;
double elapsedSeconds = 0.0;
double oldTime = 0.0;
while (elapsedSeconds<8.0)          // run for 8 seconds
{
actualTime = clock();             // actual time
elapsedSeconds = double(actualTime-startingTime) / CLOCKS_PER_SEC;
if (elapsedSeconds-oldTime>0.1)   // print only every
{                               // 0.1 seconds
oldTime = elapsedSeconds;
printf("%6.3f  %10.1f\n",elapsedSeconds,double(actualTime));
}
}
return 0;
}


# do … while - loop

•  do { statement(s); } while (condition)
#include <iostream>
#include <stdio.h>    /* for printf  */
#include <stdlib.h>   /* srand, rand */
#include <unistd.h>   /* for sleep   */

using namespace std;

int main()
{
srand(time(NULL));   // initialize random number gnerator with current time
do
{
int randomNumber = rand();
double probability = randomNumber/(double)RAND_MAX;
printf("probability / random integer:   %8.5f %12d\n",probability,randomNumber);
sleep(1);          // make the programme to wait for 1 second
if (probability>0.9)
break;
}
while (true);      // infinite loop
}


# for-loops; continue

•  for (init; condition; increment) { statement(s); }       is used 99% of times
• continue : re-enter the loop at top
#include <iostream>
#include <stdio.h>    /* for printf  */
#include <stdlib.h>   /* srand, rand */
#include <unistd.h>   /* for sleep   */

using namespace std;

int main()
{
for (int count=20; count>0; count=count-3)
{
if ((count%4)!=0)
continue;       // got to top of loop
cout << count << endl;
}
}


# throwing and catching exceptions

### exception – try … catch

• exceptions are non regular program events
exceptions are thrown whenever something goes wrong, like
• division by zero (runtime)
• trying to open a non existent file (IO)
• ...
a program will never crash if all exceptions are handled correctly
• exceptions are handled by wrapping the dangerous operation with a
try {} catch () {}  bracket
cerr << (...); is the standard error output stream
#include <iostream>
using namespace std;

double throwDivision(int a, int b)
{                         // division throwing an exception
if(b==0)
throw "Division by zero condition!";
return (a*1.0/b);        // (a/b) would yield an integer
}

int main(int argLength, char* argValues[])
{
cout << endl;
cout << "i" << "  " << "24/i" << endl;
cout << endl;
for (int count=9; count>=0; count--)
if (argLength==1)      // try with and without arguments
try {
cout << count << "  " << throwDivision(24,count) << endl;
} catch (const char* msg)
{
cerr << msg << endl;
}
else
cout << count << "  " << (24/count) << endl;
//
cout << "\n" << "happy loop completion" << endl;
//
//
cout << "\n" << "happy program ending?" << endl;
//
return 1;
}


# List of C++ operators

LevelPrecedence groupOperatorDescriptionGrouping
1Scope::scope qualifierLeft-to-right
2Postfix (unary)++ --postfix increment / decrementLeft-to-right
()functional forms
[]subscript
. ->member access
3Prefix (unary)++ --prefix increment / decrementRight-to-left
~ !bitwise NOT / logical NOT
+ -unary prefix
& *reference / dereference
new deleteallocation / deallocation
sizeofparameter pack
(type)C-style type-casting
4Pointer-to-member.* ->*access pointerLeft-to-right
5Arithmetic: scaling* / %multiply, divide, moduloLeft-to-right
6Arithmetic: addition+ -addition, subtractionLeft-to-right
7Bitwise shift<< >>shift left, shift rightLeft-to-right
8Relational< > <= >=comparison operatorsLeft-to-right
9Equality== !=equality / inequalityLeft-to-right
10And&bitwise ANDLeft-to-right
11Exclusive or^bitwise XORLeft-to-right
12Inclusive or|bitwise ORLeft-to-right
13Conjunction&&logical ANDLeft-to-right
14Disjunction||logical ORLeft-to-right
15Assignment-level expressions= *= /= %= += -= >>= <<= &= ^= |=assignment / compound assignmentRight-to-left
?:conditional operator
16Sequencing,comma separatorLeft-to-right