C++ syntax#

Important

This chapter is devoted to the basics of C++ language required to use XLiFE++. It is addressed to people who do not know C++.

C++ (inheriting from C) is a procedural langage (step-by-step execution of instructions) which is compiled, say translated to a low level langage (assembly langage). It provides powerful object programing concepts.

Instruction sequence#

An instruction is a sequence of items involving C++ syntax words, type names, variable names, numeric constants, operations, function names, … and ending with a semicolon:

float x = 2.; // a simple instruction defining a variable x as a float number

Only one blank character is required to separate items (except operators). An instruction may be written on several lines. .. code:

float x=2.
       +3.; // instruction on two lines

All C++ instructions are defined in block delimited by braces:

{
  instruction;
  instruction;
  ...
}

Instruction block may be nested in other ones:

{
  instruction;
  {
    instruction ;
    instruction ;
  }
  ...
}

and are naturally involved in tests, loops, … and functions.

A function is defined by its name, a list of input argument types, an output argument type and an instruction sequence in an instruction block:

out_type name_of_function(in_type1 a1, in_type2 a2, ...)
{
    instruction;
    instruction;
    ...
    return something of out_type;
}

The main program is a particular function (with or without input argument) returning an error code (int):

int main()
{
  ...
  return 0;  //no error
}

Variables#

In C++, any variable has to be declared, say defined by specifying its type. Fundamental types are:

  • integer number: int, size_t, short unsigned int (respectively replaced by Int, Number and Dimen in XLiFE++).

  • real number: float for single precision (32bits) or double (64bits) for double precision (replaced by Real in XLiFE++)

  • boolean: bool that takes true (1) or false (0) as value

  • character: char containing one of the standard ASCII character.

  • string: string containing a string of characters (replaced by String in XLiFE++).

See Basic types for more details.

All other types are derived types (pointer, reference) or classes (Complex, String for instance).

Tip

It is possible to use the auto type as soon as the compiler is able to infer the type of a variable.

auto i = 1;          // i is an int
auto r = 3.1415926;  // r is a double
auto a;              // error: type of a is undetermined

To use an automatic variable, the user must be able to know the actual type of the variable !

All variable names must start with a letter of the alphabet. Do not start by underscore (_) because as this is widely used by XLiFE++. After the first initial letter, variable names can also contain letters and numbers. No spaces or special characters, however, are allowed. Upper-case characters are distinct from lower-case characters.

A variable may be declared anywhere. When they are declared before the beginning of the main, they are available anywhere in the file where they are declared.

Hint

All variables declared in an instruction block are aumatically deleted at the end of the block.

Basic operations#

The C++ provides a lot of operators. The main ones are :

  • = : assignment

  • +, -, *, /: usual algebric operators on numbers

  • +=, -=, *=, /=: operation on left variable (self-overwriting)

  • ++, --: to increment by 1 (+=1) and decrement by 1 (-=1)

  • ==, !=, <, >, <=, >=, ! : comparaison operators and negation

  • &&, || : logical and, or

  • <<, >> : to insert in a stream (read, write)

All these operators may work on object of a class if they have been redefined for this class. See documentation of a class to know what operators it supports.

The operators +=, -=, *=, /= may be useful when they act on large structure because they, generally, do not modify their representation and avoid copy.

if, switch, for and while#

The syntax of a test is the following:

if (predicate)
{
  ...
}
else if (predicate2)
{
  ...
}
else
{
    ...
}

else if and else blocks are optional, and you can have as many else if blocks as you want. predicate is a boolean or an expression returning a boolean (true or false):

if ((x==3 && y<=2) || (! a>b))
{
  ...
}

For multiple choice, use the switch instruction:

switch (i)
{
  case 0:
  {
    ...
    break;
  }
  case 1:
  {
    ...
    break;
  }
  ...
  default:
  {
    ....
  }
}

The switch variable has to be of enumeration type (integer or explicit enumeration).

The syntax of the for loop is the following:

for (initialization; end_test; incrementing sequence)
{
  ...
}

The simplest loop is:

for (int i=0; i< n; i++)
{
  ...
}

Another example with no initializer and two incrementing values:

int i=1, j=10;
for(; i< n && j>0; i++, j--)
{
  ...
}

A for loop may be replaced by a while loop:

int i=0;
while (i<n)
{
  ...
  i++;
}

In/out operations#

The simplest way to print something on screen is to use the predefined output stream cout with operator << or the XLiFE++ output stream theCout (to print something on screen and on a print file at the same time):

Real x=2.25;
Number i=3;
String msg=" Xlife++ :";
cout << msg << " x=" << x << " i=" << i << eol;

eol is the XLiFE++ end of line, replacing the standard C++ endl . Any object of a class can be inserted in output stream as the operator << is defined for this class. Almost all XLiFE++ classes offer this feature.

To read information from keyboard, use the predefined input stream cin with operator >>:

Real x;
Number i=3;
cin >> i >> x;

The program waits for an input of a real value, then for an input of integer value.

To print on a file, the method is the same except that an output stream on a file has to be used :

ofstream out;
out.open("myfile");
Real x=2.25;
Number i=3;
String msg=" Xlife++ :";
out << msg << " x=" << x << " i=" << i << eol;
out.close();

To read from a file :

ifstream in;
in.open("myfile");
Real x;
Number i=3;
in >> i >> x;
in.close();

The file has to be compliant with data to read. The default separators are white space and carriage return (end of line).

To read and write on file in a same time, use fstream objects.

Tip

All stream stuff is defined in the C++ standard template library (STL). To use it, write at the beginning of c++ files :

#include <iostream>
#include <fstream>
...
using namespace std;

Using standard functions#

The STL library provides some fundamental functions such as abs, sqrt, power, exp, sin, … To use it, the cmath header file has to be included:

#include <cmath>
using namespace std;
...
double pi=4*atan(1);
double y=sqrt(x);
...

Use of classes#

The C++ allows defining new types of variable embedding complex structure: say class. A class may handle some data (member) and functions (member functions). A variable (instance) of a class is called an object.

In XLiFE++, end-users have only to use it, not to define new one. The main questions are : how to create an object of a class, how to access to its members and how to apply operations on it. To illustrate concepts, let’s use the very simple Complex class:

class Complex
{
  public:
  float x, y;
  Complex(float a=0, float b=0) : x(a), y(b) {}
  float abs() { return sqrt(x*x+y*y); }
  Complex& operator+=(const Complex& c) { x+=c.x;y+=c.y;return *this; }
  ...
};

Classes have special functions, called constructors, to create object. They have the name of the class and are invoked at the declaration of the object:

int main()
{
  Complex z1;          // default constructor
  Complex z2(1,0);     // explicit constructor
  Complex z4(z2);      // copy constructor
  Complex z5=z3;       // use copy constructor
  Complex z4=Complex(0,1);
}

Copy constructor and operator = are almost always defined. When operator = is used in a declaration, the copy constructor is invoked. The last instruction uses the explicit constructor and the copy constructor. In practice, compilers are optimized to avoid useless copy.

To address a member or a member function, use the operator point (.):

int main()
{
  Complex z(0,1);
  float r=z.x;
  float i=z.y;
  float a=z.abs();
}

and to use operators, use it as usual:

int main()
{
  Complex z1(0,1), z2(1,0);
  z1+=z2;
}

Most of XLiFE++ user’s classes have been developed to be close to natural usage.

Understanding memory usage#

In scientific computing, the computer memory is often asked intensively. So its usage has to be well managed:

  • Avoid copy of large structures (mainly TermMatrix).

  • Clear large object (generally it exists a clear() function). You do not have to delete objects, they are automatically destroyed at the end of the blocks where they have been declared !

  • When it is possible, use +=, -=, *=, /= operators instead of +, -, *, / operators which induce some additional copies.

  • In large linear combination of TermMatrix, do not use partial combinations which also induce unnecessary copies and more computation time.