1. Homepage of Dr. Zoltán Porkoláb
    1. Home
    2. Archive
  2. Teaching
    1. Timetable
    2. Bolyai College
    3. C++ (for mathematicians)
    4. Imperative programming (BSc)
    5. Multiparadigm programming (MSc)
    6. Programming (C in English)
    7. Programming languages (PhD)
    8. Software technology lab
    9. Theses proposals (BSc and MSc)
  3. Research
    1. CodeChecker
    2. CodeCompass
    3. Templight
    4. Projects
    5. Publications
    6. PhD students
  4. Affiliations
    1. Dept. of Programming Languages and Compilers
    2. Ericsson Hungary Ltd

3. The structure of C++ programs

C++ programs consist of

  • Comments
  • Preprocessor directives
  • C++ tokens

Comments:

1
2
3
4
5
6
7
8
9
10
11
  // single line comment (since C99) from // to end of line

  /* multi
     line    
     comments
     // hiding single line comments
   */

  /*
      /*  but must not be nested */
   */

No comments inside strings: “/* this is not comment */”

1
2
3
4
5
/*************************************\
*                                     *
*  exist in various style and format  *
*                                     *
\*************************************/

Preprocessor directives

starting with ‘#’

1
2
3
4
5
6
7
8
9
10
11
#ifdef 
#define MY_HEADER 
#include <header.h>

#if MY_PLATFORM
#define BUFFER 100
#else
#error platform not defined
#endif

#endif

… more on preprocessor in the next lecture

C++ tokens

keywords

all lowercase

identifyers

starts with letter (incl _underscore) continues with letters or numbers

literals

  • 1 decimal integer literal
  • 0x14 hexadecimal integer literal
  • 3.14 floating point literal
  • ‘x’ character literal
  • “Hello world” string literal

operators

  • unary e.g. -2
  • binary e.g. 2 + 4
  • ternary x<y ? x : y

separators

{ } , ;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//                   //   <---- comment  
// C++ style         //   <---- comment
//                   //   <---- comment
#include <iostream>  //   <---- preprocessor directvive
#include <string>    //   <---- preprocessor directvive

std::string myname();// std <-- namespace name: identifier
                     // string <-- class name: identifier
                     // myname <-- function name: identifier
                     // ::     <-- scope: operator
                     // ()     <-- function call: operator
int main()           // int    <-- type name: keyword
                     // main   <-- function name: identifier
                     // ()     <-- function call: operator
{                    // {      <-- block begin: separator
  std::cout          // cout   <-- variable: identifier
            <<       // <<     <-- output : operator
  "my name is: "     // <-- string literal, type char[13]
            <<       //
   myname()          // myname <-- function name: identifier
            <<       // ()     <-- function call: operator        
       std::endl;    // ;      <-- command-end: separator
  return 0;          // return <-- keyword
                     // 0      <-- decimal literal, type int
}                    // }      <-- block end: separator

Keywords

we will learn them …

Identifiers

  • starts with letter (underscore ‘_’ is a letter)
  • continues with letters and digits
  • no maximum length
  • but compilers should translate
  • only the first 63 letters (internal linkage)
  • only the first 31 letters (external linkage)
  • must not use keywords as identifiers
  • case sensitive

Different conventions:

  • camelCaseNotation
  • CTypenamesStartsWithUppercase
  • under_score_notation

A research on this: https://whathecode.wordpress.com/2011/02/10/camelcase-vs-underscores-scientific-showdown/

results on February 2015:

  • camelCase: 52.5 %
  • underscore: 47.5 %

MACRO_NAMES_ARE_ALL_UPPERCASE by convention

A paper on this: http://www.cs.loyola.edu/~binkley/papers/icpc09-clouds.pdf

Literals

void

Notes the return types of functions with no return value.

Integral types

  • decimal integral 12 type = int, value = 12
  • octal integral 014 type = int, value = 12
  • hexadecimal integral 0xC type = int, value = 12

  • long integer 12l type = long int, value = 12
  • long long integer (since C99)

  • unsigned integer 12u type = unsigned int, value = 12
  • signed integers are the same as integers

  • if an integer literal longer than integer 10000000 –> long or long long

  • int size is not known ==> the best for the compiler, machine word
name example type value  
  decimali integer 25 int 25
  octal integer 031 int 25
  hexadecimal integer 0x19 int 25
  long integer 12L long in 12
  long long integer 12LL long long int 12
  unsigned integer 12u unsigned int 12
  unsigned … 12..u unsigned .. 12
   sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)
// at least 16 bit             at least 32 bit    at least 64 bit
  • also exist signed and unsigned versions, e.g. long <==> signed long

The representation of integers are not defined by the standard but many platforms use the two complement encoding.

alt text

Unsigned integer values are represented athe same way as the signed one, but instead of interpreted in the [-x…+x] interval, they are interpreted as [0..+2x].

Characters

  • character ‘A’ type = char, value = ascii value of ‘A’, likely 65
  • escape sequences:
    • ’'’ single quote
    • ’"’ double quote
    • ’\?’ question mark
    • ’\’ backslash
    • ‘\a’ bell (audio)
    • ‘\b’ backspace
    • ‘\f’ form feed – new page
    • ‘\n’ newline
    • ‘\r’ carriage return
    • ‘\t’ horizontal tab
    • ‘\v’ vertical tab
  • octal value: type = char
    • ‘\377’ -> 11111111
  • hexadecimal value type = char
    • ‘\xff’ -> 11111111
  • unicode value
    • ‘\U1234’ type = char16_t (min 16bit)
    • ‘\U12345678 type = char32_t (min 32bit)
  • wchar_t is the longest character type
  • signed char and unsigned char also exist, but here char not necessary the same as signed char
 1 == sizeof(char) < sizeof(char16_t) <= sizeof(char32_t) <= sizeof(wchar_t)
         char  ch = '\xff';
unsigned char uch = '\xff';
  signed char sch = '\xff';
:
uch > 0   /* true */
sch < 0   /* true */
 ch < 0   /* true on some platforms, false on others */

Boolean

Boolean type bool is considered as integral type.

1
2
3
4
5
6
#include <iostream>
int main()
{
  std:.cout << "bool == " (bool) 0.5 << "\t int == " << (int) 0.5;
  return 0;
}
$ ./a.out
bool == 1      int == 0

Floating point numbers

  • float 3.14f
  • double 3.14 (as double precision, default)
  • long double 3.14l

In modern computer architecture, floating point numbers are defined by the IEEE 754 standard.

precision #bits sign #exponent #fraction
single 32 1 23 8
double 64 1 52 11
extended 80 1 64 15
quadrouple 128 1 112 15

As an example, a 64 bit double precision floating number is represented this way:

alt text

Floating point operations can cause overflow or underflow . To handle these situations a few special values have been introduced:

  • Positive and negative infinites
  • Positive and negative zeroes
  • “Not a Number” NaN value

Never use floating point numbers when you need precise values, e.g. for salaries, tax, etc.

This is language independent, floating point operations may cause roundings. E.g. 1.03 - .42 easily can produce 0.6100000000000001 as the result.

The floting point numbers in C++:

C++ type example IEEE 754
float 3.14e-1f single precision
double 3.14e+2 double precision
long double 3.14e+1l extended or quadrouple prec.

s usual, exact sizes can be asked by the sizeof operator.

  sizeof(float) <= sizeof(double) <= sizeof(long double)

Complex floating points

Declared as a template type in <complex> header. The template parameter can be any floating point type.

Size of types are platform dependant

int ==> best for integral computation, “machine word”

double ==> best for floating point computation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//
// This is _very_ compiler/platform specific
//
#include <iostream>

int main()
{
  std::cout << sizeof(char) << std::endl;
  std::cout << sizeof(bool) << std::endl;
  std::cout << sizeof(short) << std::endl;
  std::cout << sizeof(long) << std::endl;
  std::cout << sizeof(long long) << std::endl; 
  std::cout << sizeof(float) << std::endl;
  std::cout << sizeof(double) << std::endl;
  std::cout << sizeof(long double) << std::endl;
  std::cout << sizeof(int*) << std::endl;
  std::cout << sizeof("Hello world") << std::endl;

  return 0;
}
$ ./a.out
1
1
2
4
8
8
4
8
16
8
12

There is a standard library header <limits> containing MIN and MAX values for various types.

Financed from the financial support ELTE won from the Higher Education Restructuring Fund of the Hungarian Government.