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 |
- 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.
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
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;
}
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:
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.
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;
}
There is a standard library header <limits> containing MIN and MAX values for various types.