#include <iostream>
using std::cout;
using std::endl
int main(int argc, char** args) {
cout<<"Hello World"<<endl;
return 0;
}
The entry point of standard C++ program is main()
. This is however depends on the platform of the application as well. In Windows' WIN32 has its entry point as WinMain()
function.
To display console output, firstly import the header file iostream
(using #include
, which will be discussed later). And then use the stream operator to std::cout
to put values into it. Stream can be chained so multiple value/variable can be chained at the same statement.
To end the line, put std::endl
at the end.
cout<<"Hello" <<" World"<<endl;
Statements in C++ are ended by ;
.
int a;
a = 100;
return;
Compound statements or blocks are grouped inside curly brackets {}
.
{
int a;
a = 100;
}
if
checks the condition and proceed with the following statement if the condition is true. else
, if presents, perform its following statement when the if
condition fails.
if(input % 2 == 0) std::cout << "Even Number" << std::endl;
else std::cout << "Odd Number" << std::endl;
switch
compare the input against all case
value. If the input is found, it start performing at the statements the case
label is placed at, until break
is found.
The case
label must contains constant numeric value. Thus it cannot be used with anything else rather than integer (enumerator can be used as well.). default
is a special label which tagged at the statement it should start at when the input does not match any other label.
For example:
switch(input) {
case 0:
std::cout << "ZERO" << std::endl;
break;
case 1:
std::cout << "ONE" << std::endl;
break;
case 7:
std::cout << "SEVEN" << std::endl;
default:
std::cout << "HEAVEN" << std::endl;
break;
}
From above example, if the input is 7, the output would be
SEVEN
HEAVEN
While other cases would print only one line. This phenomenal is called "fall-through".
while
statements checks the condition and proceed with the following statement if the condition is true. After the statement is executed, the condition is rechecked again. This is repeated until the condition is false.
while(input < 0) input--;
do
/while
performs the statement following do
keyword first, and then the condition is checked. If the condition is true then it re-perform the statement again. This is done repeatedly until the condition is false.
do input--;
while (input >= 0);
for
contains 3 clauses. Initialization, Condition, and Increment. These three are put inside a pair of parenthesis, separated by semicolon.
for (<Initialization>; <condition>; <increment>) statement;
The initialization is only performed once before everything else begin. After that the condition is checked. If the condition is true then the statement is performed. Then the increment is performed. Finally the condition is re-checked again and if it's true the statement is performed one more time. This is performed repeatedly until the condition is false.
For example:
for(int i =0; i< SIZE; i++)
std::cout<<i<<std::endl;
Variable in C++ can be declared as . For example int count
, char delimeter
, float average
, string name
.
Variables can be assigned its value by using assignment operator =
.
int a;
a = 100;
Variables can be also declared and assigned at the same statement.
int a = 100;
If the data type can be deduced from the value the variable is being assigned, the data type can be replace by the keyword auto
. This is useful in the context that the type is very complicated.
std::vector<int> vectorInt;
std::vector<int>::const_iterator iter1 = vectorInt.begin();
auto iter2 = vectorInt.begin();
Also auto
provides the cleaner, less error-prone code. Consider :-
int a = 100l; //variable is int, the value is long.
and
auto a = 100l; //both are long.
Variables can be constant by using keyword const
. Constant variable must be initialized right-away as the value cannot be updated afterward.
const int count = 100;
Data type can be either basic data type, pointer, reference (will be discussed later), or user define type e.g. struct
, class
, enum
.
bool
can be either true
or false
, but nothing else.
bool tautology = true;
Integer types are char
, wchar
, int
, short
, long
and long long
. They can be either signed or unsigned. To specify whether or not it is signed or unsigned, put the keyword signed
or unsigned
, respectively, just before the integer data type name.
The size of these type are guarantee to be specific size, but is not necessarily exact to the number. For example short
and long
might be exactly the same size (e.g. 64-bit).
Integer literal may contains suffix to denote the type of the value. Eg. l
for long
, u
for unsigned
, ll
for long long
, ul
for unsigned long
, and ull
for unsigned long long
.
unsigned long long superLargeInt = 12345678901234567890ull;
char
and wchar_t
(wide character) are types used specifically for characters. char
is strictly 8-bit character, while wchar_t
is 16-bit or larger. Character literal is a single character inside single quote, with a prefix l
for wide character.
char a = 'a';
wchar_t b = l'b';
Floating points are float
and double
. These are IEEE754 encoded floating points, with float
being being single-precision (32-bit) and double
being double-precision (64-bit).
Floating point literal requires decimal point .
to be present in the value, or use the exponential form (not discussed here), otherwise it will be treated as integer. Floating point literals are by default double
. To make it float
use f
prefix.
float a = 10.0f;
double b = 3.14;
Enumerators are data types which has predefined set of possible value. To define an enumerator use enum
or enum class
keyword.
enum DAY { DAY_MONDAY, DAY_TUESDAY, DAY_WEDNESDAY, DAY_THURSDAY, DAY_FRIDAY, DAY_SATURDAY};
enum class Month { January, February, March, April, May, June, July, August, September, October, November, December };
enum class
was added in C++11. It is not available in any version before C++11 standard.
The value defined in enumerator are constant integer, it works almost the same way as a constant with an exception as it cannot be referred by reference operator (as it's not an variable). Value defined in enum
are exposed globally, while the enum class
contains the value within its name. For example
DAY day = DAY_MONDAY;
Month month = Month::April;
The value name defined in enum
may clashes with other code, so it's advised to begin the name with the type name. Since enum class
contains the value under its name already, this is already enforced.
Each value in an enumerator is an constant integer, the first value is 0, and the next one is larger then the other by 1. Each value can be assigned with a different value manually using assignment operator =
. The value that is not specified explicitly will be larger then the one before by 1.
enum class Numeric {
ONE = 1,
TWO,
THREE,
FOUR,
ZERO = 0
};
Reference is simply an alias to a variable. To define a reference, simply put &
before the variable name. Reference required its value to be assigned immediately. The right-hand side of the assignment operator is needed to be a variable.
For example.
int avar = 100;
int &alias = avar; //alias is now an alias of avar
avar
and alias
are practically the same variable. Any assignment operation made to alias
will change the value of avar
as well.
alias += 100; //avar is now 200
A reference is expected to be the same type as the variable it refers to. Below code is illegal
int avar = 100;
float &alias = avar; // Illegal.
Reference can be auto
as well.
int avar;
auto &alias = avar; //alias is int&
Pointers are the type whose store a reference. To define a reference, put *
before the variable name.
int *ptr;
The term referece here usually means a memory address where a data is stored. This can be a value returned by reference operator &
, as well as a value returned by new
operator.
int var = 100;
int *ptrToAvar = &avar;
int *ptrToSomeValue = new int(200); //new will be discuss later.
Pointer can also points to another pointer as well. Put more *
in front of the variable name to do so.
int var = 100;
int *ptrToVar = &var;
int **ptrToPtrToVar = &ptrToVar;
int ***ptrToPtrToPtrToVar = &ptrToPtrToVar;
Pointers that points to constant variable needs a const
keyword like below:
const int a = 100;
const int* ptr = &a; //(*ptr) cannot be reassigned, like a.
//However ptr can be reassigned to point to some other const int.
And pointers can be constant as well (which mean the cannot be reassigned), by putting the keyword after the asterisk.
int a = 100;
int* const ptr = &a; //any assignment to ptr after this is illegal, however (*ptr) is reassignable.
And finally constant pointer to constant variable.
const int a = 100;
const int* const ptr = &a; // both ptr and (*ptr) is not reassignable.
NULL
and nullptr
are a special reference value which basically means nothing. They are used for placeholder for pointer which do not point to anywhere just yet.
int *ptr = nullptr;
int *ptrA = NULL;
Operation made to pointers updates the reference value it holds, not the value of the data referred by the reference (operator will be discuss later). For example.
int avar = 100;
int *ptrToAvar = &avar;
ptrToAvar += 1; //avar remains 100, ptrToAvar now points to something else.
To update the value of the data the pointer points to, use dereference operator *
.
int var = 100;
int *ptrToVar = &var;
*ptrToVar += 1; //var is now 101.
Addition and subtraction, as well as increment and decrement operation, can be done to pointers. Adding 1 into a pointer results in the next value of the same time of the value it used to pointed to. For example :
// Array will be discussed in the next section.
int array[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int *p = &array[0];//p points to array[0]
std::cout<<*p<<std::endl; // 0
std::cout<<*(p+1)<<std::endl; // 1
std::cout<<*(p+5)<<std::endl; // 5
p += 4; // p is now pointed to array[4]
std::cout<<*p<<std::endl; //4
std::cout<<*(p-2)<<std::endl; // 2
p -= 1 //p is now pointed to array[3]
Arrays are a group of data with the same type, sitting next to each other. To declare an array, use []
after the variable name.
int intArray[200];
char charArray[5000];
The number of element of data it holds is finite, and must be known to the compiler at compile time. The following code is invalid.
int count = 200;
int intArray[count]; //compile error.
Also the number of element cannot be dynamically obtained in code. So in the case that the size must be known, #define
a macro and use it as the size constant.
#define BUFFER_SIZE 500
int buffer[BUFFER_SIZE];
In C++11 the const_expr
can be used in this context, but Visual C++ 2012 does not support the keyword.
Arrays can be initialized with a list of value, using {}
with a list of comma-seperated value. In this case the size can be omitted.
int intArray[] = {0, 1, 2, 3, 4, 5};
char charArray[] = {'h', 'e', 'l', 'l', 'o'};
To access to an element inside an array, put an index number inside []
. Eg.
std::cout << intArray[50];
intArray[20] = 50;
The index number of an array can be any number from [0:n), which means 0<i<n, where n is the number of element the array is holding. Accessing an array using index which falls outside of this interval results in undefined behavior (mostlikely SEGFAULT).
In C++, a string literal is an character array ended with '\0'
or NULL. The NULL character is added automatically by the compiler. String literal is a sequence of characters inside a pair of double quote ""
. This is the construct inherit from C. It can be assigned to a character array, like :-
char str[] = "Hello World"; // This array has 12 elements, with the last one is '\0'.
This is commonly called C-String.
A string literal can be assigned to a character pointer as well. This is not recommended and might results in warning with modern C++ compilers. However this form is even more common than the array form.
char *str = "Hello World"; //same as char str[].
new
operator can be used to dynamically allocate memory inside heap/free store area. This operator returns a reference which must be assigned to a pointer.
new
operator can be used to allocate a single instance of a data type, or an adjacent area with a number of instance of the same data type. For example.
int *pInt = new int;
int *pIntArray = new int[50];
The latter is called dynamic array. Dynamic array are created and allocated at the runtime. The size can be vary and is not required to be known to the compiler at compile time (as opposed to the static array).
int count = 200;
// int intArray[count]; results in compile error. Instead use this.
int *intArray = new int[count];
Dynamic array works the similar way to static array and works with the same syntax.
After finishing using the memory allocated by new
, these instances have to be deallocated manually using delete
or delete[]
operator, depends on whether it is single instance or a dynamic array. Failing to do so results in memory leak.
int *pInt = new int;
int *pIntArray = new int[50];
// ... snipped
delete pInt;
delete[] pIntArray;
Using delete
on dynamic array results in memory leak (as only the first element is freed). Using delete[]
on single instance results in undefined behavior (mostlikely SEGFAULT).
Variables have their own lifetime, based on the scope it is declared. When an variable is declared outside any blocks, it's a global variable which lives in the global scope. If a variable is declared inside a block, it's a local variable.
Variable declared in a global scope will be created before the program begins (eg. main()
is executed). Variable declared in a local scope will be created when the program runs into the line it is declared.
Keep in mind that
- Variable has to be declared before it can be used. The code that refers to this variable must be in the same or inner scope, must be written under the variable is declared.
- No variables with the same can be in the same scope. They can be however declared in different scope level, in this case the code that refers to the name refers to the variable closest to the scope the code lives.
For example:
std::cout << a << std::endl; //error, a is not declared at this point.
int a = 10;
int main(int argc, char** argv) {
std::cout<< a <<std::endl; // error, a is not declared at this point.
return 0;
}
int a = 10;
When the enclosing scope ends, the variable is destroyed and becomes invalid. The name cannot be referred in the code anymore.
It's possible to have a pointer points to this destroyed variable. If the value is accessed through this pointer, it results in undefined behavior (mostlikely SEGFAULT). This phenomenal is called dangling pointer
For example:
int *a;
if (input > 0) {
int b = 20;
a = &b;
}
std::cout << a << endl; //The program would crash here.
Functions are a set of command grouped into a single procedure. To define a function, use the syntax :
<returntype> <function name> (<parameter list>) {
<body>
}
For example :
int max(int a, int b) {
return a > b ? a: b;
}
return
keyword is used to return the following value back to the function caller.
For function that does not return anything, use return type void
.
void print(char str[]) { cout<<std::str<<endl;}
A function has to be declared before it can be use. The code above the function definition cannot refers to the function. For example, below code does not compile.
int main(int argc, char** argv){
std::cout<< max(5, 10);
}
int max(int a, int b) {
return a > b ? a: b;
}
Function can be forward declared, by placing the function's signature somewhere in the code. For example.
int max(int a, int b);
int main(int argc, char** argv){
std::cout<< max(5, 10);
}
int max(int a, int b) {
return a > b ? a: b;
}
A function can also be used in another file, given that it is forward declared.
// max.cpp
int max(int a, int b) {
return a > b ? a: b;
}
// main.cpp
int max(int a, int b);
int main(int argc, char** argv){
std::cout<< max(5, 10);
}
The forward declaration can be even placed into a separated file, called header files, and then use #include
directive to include the function declaration into the file. #include
directive basically take a content of a file and replace it self by that content.
// max.h A header file containing max()
#ifndef MAX_H
#define MAX_H
int max(int a, int b);
#endif
#include "max.h"
//main.cpp A file that use max()
int main(int argc, char** argv){
std::cout<< max(5, 10);
}
#include "max.h"
//max.cpp A file that define max()
int max(int a, int b) {
return a > b ? a: b;
}
Function overloads are functions with the same name but different parameter list and/or return type
// max.cpp
int max(int a, int b) {
return a > b ? a: b;
}
double max(double a, double b) {
return a > b ? a: b;
}
Exception is a way to handling errors. In c++, the exception value can be any type. For example:
if(value == nullptr) throw 0;
To catch the exception, use try
/catch
keyword.
#include <iostream>
int test(char a[]) {
throw 0;
}
int main(int argc, char** argv) {
try{
test("abcdefg");
} catch (int errorCode) {
std::cout<<"Error Code : " << errorCode << std::endl;
}
return 0;
}
catch
clause can be chained when the expected code might throw multiple type of value.
try{
test("abcdefg");
} catch (int errorCode) {
std::cout<<"Error Code : " << errorCode << std::endl;
} catch (std::string errorText) {
std::cout<<"Error : " << errorText << std::endl;
}
use catch(...)
to handle the case the type of exception might be unknown.
try {
test("abcdefg");
} catch (int errorCode) {
std::cout<<"Error Code : " << errorCode << std::endl;
} catch (std::string errorText) {
std::cout<<"Error : " << errorText << std::endl;
} catch (...) {
std::cout<<"Unknown error"<< std::endl;
}