Skip to content

liuxuanhai/Advanced-c-cpp-Programming-Tutorial

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

57 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Advanced C/C++ Programming Tutorial with Xcode

Indexes

Basics

Intermediate

Data Structures

Advanced

Basics

Hello World

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

void showExample00(){
       int number;
       cout << "Hello World" << endl;
       cout << "Please enter a number: " << endl;
       cin >> number;
       cin.ignore();
       cout << "You entered: "<< number << endl;
       cin.get(); // wait a press key to finish
   }

int main()
{
   showExample00();
   return 0 ;
}

Result

 Hello World
 Please enter a number:
 12
 You entered: 12

Contanst/Literals

Chars

Escape sequence	Meaning
\\ =	\ character
\' =	' character
\" =	" character
\? =	? character
\a =	Alert or bell
\b =	Backspace
\f =	Form feed
\n =	Newline
\r =	Carriage return
\t =	Horizontal tab
\v =	Vertical tab
\ooo =	Octal number of one to three digits
\xhh =	Hexadecimal number of one or more digits

Integer

212        // Legal
215u       // Legal
0xFeeL     // Legal
078        // Illegal: 8 is not an octal digit
032UU      // Illegal: cannot repeat a suffix
1223       // decimal
0213       // octal
0x4b       // hexadecimal
40         // int
10u        // unsigned int
10l        // long
20ul       // unsigned long

Floating-point

3.14159       // Legal
314159E-5L    // Legal
510E          // Illegal: incomplete exponent
210f          // Illegal: no decimal or exponent
.e55          // Illegal: missing integer or fraction

Constants

#define LENGTH 10
const int  LENGTH = 10;

Conditionals

#include <stdio.h>
#include <sstream>
#include <iostream>

using namespace std;

bool isMaxEq(int a, int b){
       return (a >= b);
   }

string formalizeString(bool result){
       return (result) ? "Yes" : "No"; // operador ternario [ if(result) "Yes" else "No" ]
   }

void showExample01() {
       int num1, num2;
       cout << "Please enter a number: " << endl;
       cin >> num1;
       cin.ignore();
       cout << "Please enter other number: " << endl;
       cin >> num2;
       cin.ignore();
       cout << "is " << num1 << " Max or Eq Than " << num2 << " ?" << endl;
       bool res = isMaxEq(num1, num2);
       string str = formalizeString(res);
       cout << "Result: "<< str << endl;
       cin.get();
   }

int main()
{
   showExample01();     
   return 0 ;
}

Result

 Please enter a number:
 32
 Please enter other number:
 3
 is 32 Max or Eq Than 3 ?
 Result: Yes

Loops

#include <iostream>
using namespace std;

void showExampleFor(){
  for ( int x = 0; x < 5; x++ ) {
      cout<< "For "<< x <<endl;
  }
  cin.get();
}

void showExampleWhile(){
       int x = 0;
       while ( x < 5 ) {
               cout<< "While " << x << endl;
               x++;
           }
       cin.get();
   }

void showExampleDoWhile(){
       int x = 0;
       do {
               cout<< "Do/While " << x << endl;
               x++;

           } while ( x < 5 );
       cin.get();
   }

int main(int argc, const char * argv[]) {

       showExampleFor();
       showExampleWhile();
       showExampleDoWhile();

       return 0;
   }

Result

For 0
For 1
For 2
For 3
For 4

While 0
While 1
While 2
While 3
While 4

Do/While 0
Do/While 1
Do/While 2
Do/While 3
Do/While 4

Switch

#include <iostream>

using namespace std;

int module2(int num){
       int mod = num % 2;
       switch ( mod ) {
               case 0:
                   return 0;
                   break;
               case 1:
                   return 1;
                   break;
               default:
                   return -1;
                   break;
           }
   }


void play()
{
   cout << "Play called" << endl;
}
void save()
{
   cout << "Save called" << endl;
}
void load()
{
   cout << "Load called" << endl;
}
void exit()
{
   cout << "Exit called" << endl;
}

void menu()
{
  int input;
  cout << "1. Play" << endl;
  cout << "2. Save" << endl;
  cout << "3. Load" << endl;
  cout << "4. Exit" << endl;
  cout << "Option: ";
  cin>> input;
  switch (input) {
       case 1: play(); break;
       case 2: save(); break;
       case 3: load(); break;
       case 4: exit(); break;
       default: cout<<"Error, Bad input"<< endl; break;
   }
  cin.get();
}

void showExample03(){
       cout<< "10 mod 2 = " << module2(10) << endl;
       cout<< "11 mod 2 = " << module2(11) << endl<<endl;

       menu();
   }

int main(int argc, const char * argv[]) {
       showExample03();
       return 0;
   }

Result

10 mod 2 = 0
11 mod 2 = 1

1. Play
2. Save
3. Load
4. Exit
Option: 2
Save called

Pointers

#include <iostream>

using namespace std;

void pointer() {

       int x;
       int* p;

       p = &x;
       cout << " int *p = &x " << endl;
       cout << " Please enter a number x = " << endl;
       cin >> x;
       cin.ignore();

       cout << "Value x = "<< x << endl;
       cout << "Address &x = "<< &x << endl;
       cout << "Pointer *p = "<< *p << endl;
       cout << "Set *p = "<< *p << endl;
       cin >> *p;
       cin.ignore();

       cout << "Value x = "<< x << endl;
       cout << "Address &x = "<< &x << endl;
       cout << "Pointer *p = "<< *p << endl;
       cout << "Set *p = "<< *p << endl;

       cin.get();
   }

void pointerFromFreeMemory(){

       int* ptr = new int;
       cout << " int* ptr = new int" << endl;
       cout << " Please enter a number *ptr =  " << endl;
       cin >> *ptr;
       cin.ignore();

       cout << "Address &prt = "<< &ptr << endl;
       cout << "Pointer *ptr = "<< *ptr << endl;

       cin.get();

       delete ptr;

       cout << "Delete ptr"<< endl;
   }

void showExample04(){
       pointer();
       pointerFromFreeMemory();
   }


int main(int argc, const char * argv[]) {
       showExample04();
       return 0;
   }

Result

int *p = &x
Please enter a number x =  22
Value x = 22
Address &x = 0x7fff5fbff6dc
Pointer *p = 22

Set *p = 12222
Value x = 12222
Address &x = 0x7fff5fbff6dc
Pointer *p = 12222
Set *p = 12222

int* ptr = new int
Please enter a number *ptr =  322
Address &prt = 0x7fff5fbff6c8
Pointer *ptr = 322

Delete ptr

Storages

Extern Modulo

#include "modulo.hpp"

extern int x;

int funcion(){
       return x;
   }

Head Modulo

#ifndef modulo_hpp
#define modulo_hpp

#include <stdio.h>
int funcion();
#endif /* modulo_hpp */
#include <iostream>
#include "modulo.hpp"
using namespace std;

/**
 * Variable que se crea en la ejecución de un ámbito temporal.
 * Destroy automático.
 * [auto] <tipo> <nombre_variable>;
 */
void _auto(){
       auto int month = 0;
       cout << "auto int month " << month << endl <<endl;
   }

/**
 * Indica al compilador una preferencia para que el objeto se almacene en un registro de la CPU, si es posible,
 * con el fin de optimizar su acceso, consiguiendo una mayor velocidad de ejecución.
 * static <tipo> <nombre_variable>;
 * static <tipo> <nombre_de_función>(<lista_parámetros>);
 */
void _register(register int *x){
       register char a = 'a';

       for(register int i=0; i < 10; i++) {
              cout << *x++ << " " << a++ << endl;
          }
       cout <<endl;
   }

int incremento() {
       static int x=10;
           x++;
       return x;
   }

/**
 * Asigna una dirección de memoria fija para el	objeto mientras el programa se esté ejecutando
 * No reside en memoria.
 * register <tipo> <nombre_variable>;
 */
void _static(){
      static int x=10;
      for(int i = 0; i < 10; i++){
               cout << i+1 << " : " << incremento() << endl;
           }
      cout<<endl;
  }

/**
 * Se usa para indicar que el almacenamiento y valor de una variable o la definición de una función están
 * definidos en otro módulo o fichero fuente.
 * extern <tipo> <nombre_variable>;
 * [extern] <tipo> <nombre_de_función>(<lista_parámetros>);
 */
int x = 100;
extern int funcion();
void _extern(){
       cout << funcion() << endl;
   }

/**
 * Sirve para que determinados miembros de un objeto de una estructura
 * o clase declarado como constante, puedan ser modificados.
 * class/struct <identificador_clase> { mutable <tipo> <nombre_variable>; }
 */
struct st {
       int y;
      mutable int x;
   };
void _mutable(){
       cout << "struct st { \nint y; \nmutable int x; \n};" << endl;
       const st A = {1, 2};
       cout << "x: "<< A.x << "y: " << A.y << endl;
       A.x = 0;
       cout << "A.x = 0; { x: "<< A.x << " y: " << A.y << " }" << endl;
   }

void showExample000(){
       _auto();
       int s[10] = {1, 2, 1, 5, 2, 7, 3, 1, 3, 0};
       _register(s);
       _static();
       _extern();
       _mutable();
   }

int main(int argc, const char * argv[]) {
       showExample000();
       return 0;
   }

Result

auto int month 0

1 a
2 b
1 c
5 d
2 e
7 f
3 g
1 h
3 i
0 j

1 : 11
2 : 12
3 : 13
4 : 14
5 : 15
6 : 16
7 : 17
8 : 18
9 : 19
10 : 20

100

struct st {
   int y;
   mutable int x;
   };

x: 2 y: 1
A.x = 0;
x: 0 y: 1

Struct

#include <string>       // std::string
#include <iostream>     // std::cout
#include <sstream>      // std::stringstream, std::stringbuf

using namespace std;


struct basicStruct {
       string name;
       int id_number;
       int age;
       float salary;
       string toString() {
               stringstream stream;
               stream << "name: " << this->name << " id: " << this->id_number
                     << " age: " << this->age << " salary: "<< this->salary << endl;
               return stream.str();
           }
   };


basicStruct basicStructure(basicStruct _struct){
       _struct.name = "Victor Bolinches";
       _struct.id_number = 1;
       _struct.age = 29;
       _struct.salary = 400000;
       return _struct;
   }

/** (*_struct).name is same as _struct->name **/
basicStruct* basicStructurePointer(basicStruct* _struct){
       (*_struct).name = "Victor Bolinches Pointer";
       _struct->id_number = 1232;
       (*_struct).age = 29;
       _struct->salary = 500000;
       return _struct;
   }

void showExample05(){
       basicStruct person;
       basicStruct res = basicStructure(person);
       cout << res.toString() << endl;

       basicStruct *personPointer;
       personPointer = &person;
       basicStruct* resPointer = basicStructurePointer(personPointer);
       cout << resPointer->toString() << endl;
   }

int main(int argc, const char * argv[]) {
       showExample05();
       return 0;
   }

Result

name: Victor Bolinches id: 1 age: 29 salary: 400000
name: Victor Bolinches Pointer id: 1232 age: 29 salary: 500000

Arrays

#include <iostream>
using namespace std;
const int MAX = 3;

void intArrayPointer(){
       int  var[MAX] = {99, 100, 20};
       int *ptr[MAX];

       for(int i = 0; i < MAX; i++)
       {
               ptr[i] = &var[i]; // assign the address of integer.
               cout << "Value of var[" << i << "] = ";
               cout << *ptr[i] << endl;
           }
      cout << endl;
  }

void charArrayPointer(){
       //Equivalent, but does not allow "char* _names[MAX] ..." in c++11·
       char* _names[MAX] = { "Victor", "Manuel", "Bolinches"};
       string names[MAX] = { "Victor", "Manuel","Bolinches"};

       for (int i = 0; i < MAX; i++)
       {
           cout << "Value of names[" << i << "] = ";
           cout << _names[i] << " "<< names[i] << endl;
       }

       cout << endl;
   }

void pointerToArray(){
       double sizes[3] = { 2.45, 23.4, 33.3 };
       double* p;

       p = sizes;
       cout << "Array values using pointer" << endl;
       for(int i= 0;i < 3 ; i++){
               cout << "*(p + " << i << ") : ";
               cout << *(p+i)<<endl;
        }
       cout << "Array values using balance as address " << endl;
       for ( int i = 0; i < 3; i++ )
       {
               cout << "*(size + " << i << ") : ";
               cout << *(sizes + i) << endl;
       }

   }

void showExample06(){
       intArrayPointer();
       charArrayPointer();
       pointerToArray();
   }

int main(int argc, const char * argv[]) {
       showExample06();
       return 0;
   }

Result

Value of var[0] = 99
Value of var[1] = 100
Value of var[2] = 20

Value of names[0] = Victor Victor
Value of names[1] = Manuel Manuel
Value of names[2] = Bolinches Bolinches

Array values using pointer
*(p + 0) : 2.45
*(p + 1) : 23.4
*(p + 2) : 33.3

Array values using balance as address
*(size + 0) : 2.45
*(size + 1) : 23.4
*(size + 2) : 33.3

Pointer vs Arrays

#include <iostream>

using namespace std;

const int SIZE = 3;

void showExample08(){
       int  array[SIZE] = {111, 222, 333};
       for (register int i = 0; i < SIZE; i++)
       {
           cout << "Value of array[" << i << "] = ";
           cout << *array << endl;
           //set values - An array name generates a pointer constant
           *array = i;    // This is a correct syntax
           //array++;        This is incorrect.
       }
   }

int main (int argc, const char * argv[])
{
    showExample08();
    return 0;
}

Result

Value of array[0] = 111
Value of array[1] = 0
Value of array[2] = 1

** Internal Array values
Value of array[0] = 111
Value of array[1] = 222
Value of array[2] = 333
i = 0
Value of array[0] = 0
Value of array[1] = 222
Value of array[2] = 333
i = 1
Value of array[0] = 1
Value of array[1] = 222
Value of array[2] = 333
i = 2
Value of array[0] = 2
Value of array[1] = 222
Value of array[2] = 333

Array of Pointers

#include <iostream>

using namespace std;
const int MAX = 5;

void showExample09(){
       int nums[MAX] = {11,22,33,44,55};
       int *p[MAX];

       for(register int i = 0; i< MAX ; i++ ){
        cout << "p["<< i << "]= &nums["<<i<<"]"<<endl;
        p[i] = &nums[i];
    }

       for(register int i = 0; i< MAX ; i++ ){
              cout << "*p["<< i << "]= "<< *p[i]<<endl;
          }
   }

int main(int argc, const char * argv[]) {
      showExample09();
      return 0;
  }

Result

p[0]= &nums[0]
p[1]= &nums[1]
p[2]= &nums[2]
p[3]= &nums[3]
p[4]= &nums[4]

*p[0]= 11
*p[1]= 22
*p[2]= 33
*p[3]= 44
*p[4]= 55

Pointer to Pointer (Multiple Indirection)

#include <iostream>

using namespace std;

void showExample10(){
       int factor;
       int *p;
       int **pp;

       factor = 100;

       p = &factor;
       pp = &p;

       cout << "Value of factor :" << factor << endl;
       cout << "Value available at *p :" << *p << endl;
       cout << "Value available at **pp :" << **pp << endl <<endl;

       factor = 200;
       cout << "factor = " << factor << endl;
       cout << "Value available at *p :" << *p << endl;
       cout << "Value available at **pp :" << **pp << endl<<endl;

       *p = 300;
       cout << "*p = " << *p << endl;
       cout << "Value of factor :" << factor << endl;
       cout << "Value available at **pp :" << **pp << endl<<endl;

       **pp = 44;
       cout << "**pp  = " << **pp << endl;
       cout << "Value of factor :" << factor << endl;
       cout << "Value available at *p :" << *p << endl;
   }

Result

Value of factor :100
Value available at *p :100
Value available at **pp :100

factor = 200
Value available at *p :200
Value available at **pp :200

*p = 300
Value of factor :300
Value available at **pp :300

**pp  = 44
Value of factor :44
Value available at *p :44

References vs Points

Las referencias son frecuentemente confundidas con los punteros.
 Hay tres diferencias:
    1: Las referencias nunca pueden ser NULL.
    2: Una referencias inicializada en un objeto no puede ser referenciada a otro objeto.
    3: Una referencia debe de ser inicializada cuando se crea el objeto.

References

#include <iostream>
#include <sstream>

using namespace std;

void variablesAndReferences(){

    int fooInt;
    double fooDouble;
    
    int &fooRefInt = fooInt;
    double &fooRefDouble = fooDouble;
    
    fooInt = 100;
    fooDouble = 777.7;
    
    cout << "Value fooInt : " << fooInt << endl;
    cout << "Value fooRefInt : " << fooRefInt  << endl;
   
    cout << "fooDouble : " << fooDouble << endl;
    cout << "fooRefDouble : " << fooRefDouble  << endl;
}

void showExample11(){
    variablesAndReferences();
}

int main(int argc, const char * argv[]) {
    showExample11();
    return 0;
}

Result

Value fooInt : 100
Value fooRefInt : 100
fooDouble : 777.7
fooRefDouble : 777.7

Parameter by References

#include <iostream>
#include <sstream>

using namespace std;

void swap(string& str1, string& str2);
void swap(int& x, int& y);

void exampleString(){
    string hello = "World !!!!";
    string world = "Hello";
    
    cout << hello <<" "<< world <<endl;
    
    swap(hello, world);
    
    cout << hello <<" "<< world <<endl;
}

void exampleInt(){
    int x = 100;
    int y = 200;
    
    cout << "Value x: "<< x <<" Value y: "<< y <<endl;
    
    swap(x, y);
    
    cout << "Value x: "<< x <<" Value y: "<< y <<endl;
}

void exampleIntPointer(){
    int _x = 300;
    int _y = 400;
    int* x = &_x;
    int* y = &_y;
    
    cout << "Value x: "<< *x <<" Value y: "<< *y <<endl;
    
    swap(*x, *y);
    
    cout << "Value x: "<< *x <<" Value y: "<< *y <<endl;
}


void showExample12(){
    exampleString();
    exampleInt();
    exampleIntPointer();
}

void swap(string& str1, string& str2){
    string tmp;
    tmp = str1;
    str1 = str2;
    str2 = tmp;
    
    return ;
}

void swap(int& str1, int& str2){
    int tmp;
    tmp = str1;
    str1 = str2;
    str2 = tmp;
    
    return ;
}

int main(int argc, const char * argv[]) {
    showExample12();
    return 0;
}

Result

World !!!! Hello
Hello World !!!!
Value x: 100 Value y: 200
Value x: 200 Value y: 100
Value *x: 300 Value *y: 400
Value *x: 400 Value *y: 300

Returning values by reference

#include <iostream>
using namespace std;

int& set(int obj [], int i )
{
    return obj[i];
}

void showExample13(){
    
    int arrayInt [] = {0,1,2,3,4,5};
    
    int size = 6;
    for (int i = 0; i< size; i++) {
        cout << "arrayInt[" << i << "] = ";
        cout << arrayInt[i] << endl;
    }
    
    cout <<""<< endl;
    cout <<"set(arrayInt,0) = 999;"<< endl;
    cout <<"set(arrayInt,1) = 444;"<< endl;
    cout <<""<< endl;
    
    set(arrayInt,0) = 999;
    set(arrayInt,1) = 444;
    
    for (int i = 0; i< size; i++) {
        cout << "arrayInt[" << i << "] = ";
        cout << arrayInt[i] << endl;
    }
    
}

int main(int argc, const char * argv[]) {
    showExample13();
    return 0;
}

Result

arrayInt[0] = 0
arrayInt[1] = 1
arrayInt[2] = 2
arrayInt[3] = 3
arrayInt[4] = 4
arrayInt[5] = 5

set(arrayInt,0) = 999;
set(arrayInt,1) = 444;

arrayInt[0] = 999
arrayInt[1] = 444
arrayInt[2] = 2
arrayInt[3] = 3
arrayInt[4] = 4
arrayInt[5] = 5

Date and Time Structs

#include <iostream>
#include <ctime>

using namespace std;

/** 
  ctime
 
struct tm {
 int tm_sec;  int tm_mday;  int tm_wday;
 int tm_min;  int tm_mon;   int tm_yday;
 int tm_hour; int tm_year;  int tm_isdst;
 };  
 */

void showExample14(){
    time_t clock = time(0);
    char* _date = ctime(&clock);
    tm* clockLocal = localtime(&clock);
    
    cout << _date << endl;
    
    cout << "Year: "<< 1900 + clockLocal->tm_year << endl;
    cout << "Month: "<< 1 + clockLocal->tm_mon<< endl;
    cout << "Day: "<<  clockLocal->tm_mday << endl;
    cout << "Time: "<< 1 + clockLocal->tm_hour << ":";
    cout << 1 + clockLocal->tm_min << ":";
    cout << 1 + clockLocal->tm_sec << endl;
    
}

int main(int argc, const char * argv[]) {
    showExample14();
    return 0;
}

Result

Sun Nov 22 20:12:53 2015

Year: 2015
Month: 11
Day: 22
Time: 21:13:54

File Input/Output

#include <iostream>
#include <sstream>
#include <fstream>

using namespace std;


void readFile(){
    string line;
    ifstream file_r("File.txt");
    bool isOpen = file_r.is_open();
    if (!isOpen)
    {
        cout << "Error file : Unable to open";
        return ;
    }
    
    while (getline (file_r,line) )
    {
        cout << line << '\n';
    }
    file_r.close();
}

void writeFile(){
    ofstream file_w("File.txt", ios::app);
    bool isOpen = file_w.is_open();
    if (!isOpen)
    {
        cout << "Error file : Unable to open";
        return ;
    }

    file_w << "\n\n";
    file_w << "Victor Bolinches Marin";
    file_w.close();
}

void showExample15(){
    readFile();
    writeFile();
    readFile();
}

int main(int argc, const char * argv[]) {
    showExample15();
    return 0;
}

Result

"Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit ...

"Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit ...


Victor Bolinches Marin

Typecasting

void cast(){
    for ( int x = 65; x <= 90; x++ ) {
        cout<< x <<" - "<< (char)x <<"   ";
    }
}

void staticCast(){
    for ( int x = 97; x <= 122; x++ ) {
        cout<< x <<" - "<< static_cast<char>(x) <<"   ";
    }
    
}
void showExample(){
    cast();
    staticCast();
}


int main(int argc, const char * argv[]) {
    showExample();
    return 0;
}

Result

Cast
65 - A   66 - B   67 - C   68 - D   69 - E   70 - F   71 - G   72 - H   73 - I   74 - J   75 - K   76 - L   77 - M   78 - N 79 - O   80 - P   81 - Q   82 - R   83 - S   84 - T   85 - U   86 - V   87 - W   88 - X   89 - Y   90 - Z  

static_cast<T>
97 - a   98 - b   99 - c   100 - d   101 - e   102 - f   103 - g   104 - h   105 - i   106 - j   107 - k   108 - l   109 -m 110 - n  111 - o  112 - p  113 - q   114 - r   115 - s   116 - t   117 - u   118 - v   119 - w   120 - x   121 - y  122 - z


Data Struct

#include <iostream>
#include <sstream>

using namespace std;

struct Client set(string name,string surname,string city, string phone, int _id);

struct Client
{
    char  name[50];
    char  surname[50];
    char  city[100];
    char  phone[9];
    int   id;
};

struct Client set(string name,string surname,string city, string phone, int _id){
    struct Client client;
    
    strcpy(client.name,name.c_str());
    strcpy(client.surname, surname.c_str());
    strcpy(client.city, city.c_str());
    strcpy(client.phone, phone.c_str());
    client.id = _id;
    
    return client;
}

void toString(struct Client cliente){
    
    cout << "Client name : " << cliente.name <<endl;
    cout << "Client surname : " << cliente.surname <<endl;
    cout << "Client city : " << cliente.city <<endl;
    cout << "Client phone : " << cliente.phone <<endl;
    cout << "Client id : " << cliente.id << endl << endl;
}

void showExample(){
    struct Client c1 = set("Victor","Bolinches","Madrid","567654321",0);
    struct Client c2 = set("Manuel","Lopez","Madrid","098654321",1);
    
    toString(c1);
    toString(c2);
}

int main(int argc, const char * argv[]) {
    showExample();
    return 0;
}

Result

Client name : Victor
Client surname : Bolinches
Client city : Madrid
Client phone : 567654321
Client id : 0

Client name : Manuel
Client surname : Lopez
Client city : Madrid
Client phone : 098654321
Client id : 1

Data Struct Pointer

#include <iostream>
#include <sstream>

using namespace std;


typedef struct Client
{
    char  name[50];
    char  surname[50];
    char  city[100];
    char  phone[9];
    int   id;
    
} Client;

void toString(Client* cliente);
static Client& set(string name,string surname,string city, string phone, int _id);


static Client& set(string name,string surname,string city, string phone, int _id){
    static Client client;
    strcpy(client.name,name.c_str());
    strcpy(client.surname, surname.c_str());
    strcpy(client.city, city.c_str());
    strcpy(client.phone, phone.c_str());
    client.id = _id;
    
    return client;
}

void toString(struct Client* cliente){
    
    cout << "Client name : " << cliente->name <<endl;
    cout << "Client surname : " << cliente->surname <<endl;
    cout << "Client city : " << cliente->city <<endl;
    cout << "Client phone : " << cliente->phone <<endl;
    cout << "Client id : " << cliente->id << endl << endl;
}

void showExample(){
    Client c1 = set("Victor","Bolinches","Madrid","567654321",0);
    Client c2 = set("Manuel","Lopez","Barcelona","098654321",1);
    
    Client* p1 = &c1;  //toString(&c1);
    Client* p2 = &c2;  //toString(&c2);
    
    toString(p1);
    toString(p2);
}

int main(int argc, const char * argv[]) {
    showExample();
    return 0;
}

Intermediate

Classes

#include <iostream>
#include <cmath>
using namespace std;

class Point {
private:
   int x;
   int y;

public:
   Point(int x, int y) : x(x), y(y) { }

   int getX() const {
        return x;
   }

   void setX(int x) {
        this->x = x;
    }

   int getY() const {
        return y;
    }

   void setY(int y) {
        this->y = y;
    }

   void setXY(int x, int y) {
        this->x = x;
        this->y = y;
    }

   double getMagnitude() const {
        return sqrt(x*x + y*y);
    }

   double getArgument() const {
        return atan2(y, x);
    }

   void print() const {
        cout << "(" << x << "," << y << ")" << endl;
    }
};

int main()
{
    Point p1(1, 2);
    p1.print();
    cout << "x: " << p1.getX() << endl;
    cout << "y: " << p1.getY() << endl;
    cout << "mag: " << p1.getMagnitude() << endl;
    cout << "arg: " << p1.getArgument() << endl;
    p1.setX(5);
    p1.setY(9);
    p1.print();

    p1.setXY(2, 4);
    p1.print();

    return 0;
}

Result

(1,2)
x: 1
y: 2
mag: 2.23607
arg: 1.10715
(5,9)
(2,4)

Interface

#include <iostream>
using namespace std;

//Interface
class IDemo
{
public:
    virtual ~IDemo() {}
    virtual void OverrideMe() = 0;
};

class Child : public IDemo
{
    public:
    
        virtual void OverrideMe()
        {
            cout<< "I am a child and I override IDemo method" <<endl;
        }
};

void example1(){
    Child child;
    child.OverrideMe();
}

void example2(){
    Child child;
    IDemo* demo = &child;
    demo->OverrideMe();
    delete demo;
}

void showExample002(){
    example1();
    example2();
    
}

int main(int argc, const char * argv[]) {
    showExample002();
    return 0;
}

Result

I am a child and I override IDemo method
I am a child and I override IDemo method

Abstract Classes

#include <iostream>

using namespace std;

class Abstract {
public:
    Abstract();
    virtual void f() = 0; // pure virtual
    virtual ~Abstract();
};

class Concrete : public Abstract {
public:
    Concrete();
    void f() override {}; // non-pure virtual
    virtual void g();     // non-pure virtual
    virtual ~Concrete();
};


void showExample003(){
    Concrete b;
    Abstract& a = b;
    a.f();
}

int main(int argc, const char * argv[]) {
    showExample003();
    return 0;
}

Dynamic Memory

#include <iostream>
using namespace std;

class MyClass {
    
public:
    int data[100];
    MyClass() {
        std::cout << "constructed [" << this << "]" <<endl;
    }
};

void showExample004(){
    std::cout << "1: ";
    MyClass * p1 = new MyClass();
    std::cout << "2: ";
    MyClass * p2 = new (std::nothrow) MyClass();
    std::cout << "3: ";
    new (p2) MyClass();
    std::cout << "4: ";
    MyClass * p3 = (MyClass*) ::operator new (sizeof(MyClass));
    
    delete p1;
    delete p2;
    delete p3;
}

int main(int argc, const char * argv[]) {
    showExample004();
    return 0;
}

Result

1: constructed [0x100300360]
2: constructed [0x100102650]
3: constructed [0x100102650]
4: 

Polymorphism - Pointers to base class

#include <iostream>
using namespace std;

class Polygon {
    
protected:
    int width, height;

public:
    void set_values (int a, int b)
        {
            width = a;
            height = b;
        }
};

class Rectangle: public Polygon {
    
public:
    int area()
        {
            return (width*height);
        }
};

class Triangle: public Polygon {
    
public:
    int area()
        {
            return (width*height)/2;
        }
};

void showExample005(){
    Rectangle rect;
    Triangle trgl;
    Polygon * ppoly1 = &rect;
    Polygon * ppoly2 = &trgl;
    ppoly1->set_values (4,5);
    ppoly2->set_values (4,5);
    cout << rect.area() << '\n';
    cout << trgl.area() << '\n';
}


int main(int argc, const char * argv[]) {
    showExample005();
    return 0;
}

Result

20
10

Polymorphism - Virtual members

#include <iostream>
using namespace std;

class Polygon {
    
protected:
    int width, height;
public:
    void set_values (int a, int b)
    {
        width = a;
        height = b;
    }
    virtual int area ()
    {
        return 0;
    }
};

class Rectangle: public Polygon {
public:
    int area ()
    {
        return width * height;
    }
};

class Triangle: public Polygon {
public:
    int area ()
    {
        return (width * height / 2);
    }
};

void showExample006(){
    Rectangle rect;
    Triangle trgl;
    Polygon poly;
    Polygon * ppoly1 = &rect;
    Polygon * ppoly2 = &trgl;
    Polygon * ppoly3 = &poly;
    ppoly1->set_values (4,5);
    ppoly2->set_values (4,5);
    ppoly3->set_values (4,5);
    cout << ppoly1->area() << '\n';
    cout << ppoly2->area() << '\n';
    cout << ppoly3->area() << '\n';
    
}

int main(int argc, const char * argv[]) {
    showExample006();
    return 0;
}

Result

20
10
0

Dynamic Allocation and Polymorphism

#include <iostream>
using namespace std;

class Polygon {
protected:
    int width, height;
public:
    Polygon (int a, int b) : width(a), height(b) {}
    virtual ~ Polygon(){
        cout <<"Destructor Polygon"<< this <<endl;
    }
    virtual int area (void) = 0;
    void printarea()
    {
        cout << this->area() << '\n';
    }
};

class Rectangle: public Polygon {
public:
    Rectangle(int a,int b) : Polygon(a,b) {}
    virtual ~Rectangle(){
        cout <<"Destructor Rectangle"<< this <<endl;
    }
    int area()
    {
        return width*height;
    }
};

class Triangle: public Polygon {
    public:
    Triangle(int a,int b) : Polygon(a,b) {}
    virtual ~Triangle(){
        cout <<"Destructor Triangle "<< this <<endl;
    }
    int area()
    {
        return width*height/2;
    }
};


void showExample006(){
    Polygon * ppoly1 = new Rectangle (4,5);
    Polygon * ppoly2 = new Triangle (4,5);
    ppoly1->printarea();
    ppoly2->printarea();
    delete ppoly1;
    delete ppoly2;
}

int main(int argc, const char * argv[]) {
    showExample006();
    return 0;
}

Result

20
10
Destructor Rectangle0x1002000a0
Destructor Polygon0x1002000a0

Destructor Triangle 0x1002000b0
Destructor Polygon0x1002000b0

Type Enums

#include <iostream>
using namespace std;

enum Foo { Head, Two, Three, Last };
enum FooNumeric { HeadNum = 100 , TwoNum = 3, ThreeNum = -22, LastNum = 0 };

void showExample19(){
    
    for ( int fooInt = Head; fooInt != Last; fooInt++ )
    {
        Foo foo = static_cast<Foo>(fooInt);
        cout << "Enum: " << fooInt << " - " << foo << endl;
    }
}

int main(int argc, const char * argv[]) {
    showExample19();
    return 0;
}

Result

Enum: 0 - 0
Enum: 1 - 1
Enum: 2 - 2

InLine Function

Funciones InLine

#include <iostream>
using namespace std;

inline double cubo(double x){
    return x * x * x;
}

void showExample20(){
    double resutl = cubo(10);   // double resutl = (10 * 10 * 10);
    cout << resutl << endl;
}

int main(int argc, const char * argv[]) {
        showExample20();
    return 0;
}

Result

1000

Clean Code

Files.hpp

#ifndef Figura_hpp
#define Figura_hpp

#include <stdio.h>
#include <sstream>

using namespace std;
class Figura {
    
protected:
    float base;
    float altura;

public:
    Figura();
    void captura();
    virtual string toString();
    virtual float perimetro() = 0;
    virtual float area() = 0;
};

#endif /* Figura_hpp */

#ifndef Triangulo_hpp
#define Triangulo_hpp

#include <stdio.h>
#include "Triangulo.hpp"
#include "Figura.hpp"
#include <iostream>
#include <sstream>
using namespace std;

class Triangulo: public Figura {
    
public:
    Triangulo(){}
    string toString();
    float perimetro();
    float area();

};

#endif /* Triangulo_hpp */

#ifndef Cuadrado_hpp
#define Cuadrado_hpp

#include <stdio.h>
#include "Triangulo.hpp"
#include "Figura.hpp"
#include <iostream>
#include <sstream>
using namespace std;

class Cuadrado: public Figura {
    
public:
    Cuadrado(){}
    string toString();
    float perimetro();
    float area();
    
};

#endif /* Cuadrado_hpp */

Files.cpp

#include "Figura.hpp"
#include <iostream>
using namespace std;

Figura::Figura(){

}

void Figura::captura()
{
    cout << "CALCULO DEL AREA Y PERIMETRO" << endl;
    cout << "Escriba la altura: ";
    cin >> altura;
    cout << endl;
    cout << "Escribe la base: ";
    cin >> base;
    cout << endl;
}

string Figura::toString() {
    return "";
}

#include "Triangulo.hpp"
#include "Figura.hpp"
#include <iostream>
#include <sstream>
using namespace std;

string Triangulo::toString(){
    stringstream str;
    float perimetro = this->perimetro();
    float area = this->area();
    str << "Perimetro " << perimetro << " - Area: " << area << " del Triangulo";
    return str.str();
}
    
float Triangulo::perimetro(){
    return (2 * (base + altura));
}
    
float Triangulo::area(){
    return (base * altura);
}

#include "Cuadrado.hpp"
#include "Figura.hpp"
#include <iostream>
#include <sstream>

using namespace std;

string Cuadrado::toString(){
    stringstream str;
    float perimetro = this->perimetro();
    float area = this->area();
    str << "Perimetro " << perimetro << " - Area: " << area << " del cuadrado";
    return str.str();
}

float Cuadrado::perimetro(){
    return (2 * (base + altura));
}

float Cuadrado::area(){
    return (base * altura)/2;
}

Main

#include <iostream>
#include "Figura.hpp"
#include "Triangulo.hpp"
#include "Cuadrado.hpp"

using namespace std;

void showExample008(){
    Figura* triangulo = new Triangulo();
    Figura* cuadrado = new Cuadrado();
    
    triangulo->captura();
    cout << triangulo->toString() << endl;
    
    cuadrado->captura();
    cout << cuadrado->toString() << endl;
}

int main(int argc, const char * argv[]) {
    showExample008();
    return 0;
}

Result

CALCULO DEL AREA Y PERIMETRO
Escriba la altura: 321
Escribe la base: 4
Perimetro 650 - Area: 1284 del Triangulo

CALCULO DEL AREA Y PERIMETRO
Escriba la altura: 432
Escribe la base: 432
Perimetro 1728 - Area: 93312 del Cuadrado

Recursion

#include <iostream>
using namespace std;

double factorial(int num){
    if(num <= 0)
        return 1;
    return num * factorial(num-1);
}

double fibonacci(int num){
    if(num <= 1)
        return num;
    else
        return fibonacci(num - 1) + fibonacci(num - 2);
}

double hanoi(int num){
    if(num <= 1)
        return 1;
    else
        return 2 * hanoi(num - 1) + 1;
}


double MCD(int x, int y){
    if( y <= 0 )
        return x;
    else
        return MCD(y, x % y);
}

string reverse(string str){
    
    string newReverse="";
    for( long i = str.length(); i>=0; i--){
        newReverse += str[i];
    }
    
    return newReverse ;
}


string reverseR(string str){
    
    if (str.length() <= 0)
        return "";
    else
    {
        char lastChar = str[str.length()-1];
        str.erase(str.length()-1);
        string newReverse = reverseR(str);
        return lastChar+newReverse;
    }
}

void showExample(){
    
    
    for(int i = 0; i < 10 ; i++){
        cout << factorial(i) << endl;
    }
    
    for(int i = 0; i < 10 ; i++){
        cout << fibonacci(i) << endl;
    }
    
    for(int i = 0; i < 10 ; i++){
        cout << hanoi(i) << endl;
    }
    
    for(int i = 0; i < 10 ; i++){
        cout << MCD(i * 2 , i * 3) << endl;
    }
    
    string list [] = {"Reverse", "Victor", "Bolinches"};
    for(int i = 0; i < 3 ; i++){
        cout <<  list[i] << " - " << reverse(list[i])<< endl;
    }
    
    for(int i = 0; i < 3 ; i++){
        cout <<  list[i] << " - " << reverseR(list[i])<< endl;
    }
}

int main(int argc, const char * argv[]) {
    showExample();
    return 0;
}

Result

Factorial 
1
1
2
6
24
120
720
5040
40320
362880

Fibonacci
0
1
1
2
3
5
8
13
21
34

Torres de Hanoi
1
1
3
7
15
31
63
127
255
511

MCD
0
1
2
3
4
5
6
7
8
9

REVERSE
Reverse - esreveR
Victor - rotciV
Bolinches - sehcniloB

Templates

hpp

#ifndef Box_hpp
#define Box_hpp

#include <stdio.h>

template <class T>
class Box {
    T a, b;
public:
    Box (T first, T second)
    {
        a = first;
        b = second;
    }
    
    T getmax();
    T component1();
    T component2();
};



#include "Box.cpp"
#endif /* Pair_hpp */

cpp

#ifdef Box_hpp

template <class T>
T Box<T>::getmax ()
{
    return  (T) a > b ? a : b;
}

template <class T>
T Box<T>::component1(){
    return this->a;
}

template <class T>
T Box<T>::component2(){
    return this->b;
}

#endif

Main

#include "Box.hpp"
#include <iostream>
using namespace std;


void showExample(){
    Box<int> *myobject = new Box<int>(100, 7500);
    cout << "Box< "<< myobject->component1() <<" , " << myobject->component2() << " >" << endl;
    cout << "Max: "<< myobject->getmax() <<endl;
}

int main (int argc, const char * argv[]) {
    showExample();
    return 0;
}

Result

Double
Box< 100.123 , 7500.22 >
Max: 7500.22

Float
Box< 100e+03 , 7500e+03 >
Max: 7500Ex1233

Int
Box< 100 , 7500 >
Max: 7500

Templates Specialization

hpp

#ifndef Pair_hpp
#define Pair_hpp

#include <stdio.h>

template <class T1,class T2>
class Pair {
    T1 a;
    T2 b;
public:
    Pair (T1 first, T2 second)
    {
        a = first;
        b = second;
    }
    
    T1 component1();
    T2 component2();
};
#include "Pair.cpp"
#endif /* Pair_hpp */

cpp

#ifdef Pair_hpp

template <class T1,class T2 >
T1 Pair<T1,T2>::component1()
{
    return a;
}

template <class T1,class T2 >
T2 Pair<T1,T2>::component2(){
    return this->b;
}


#endif

Main

#include "Pair.hpp"
#include <iostream>
using namespace std;


void pair_Int_Int(){
    Pair<int,int> *pair = new Pair<int,int>(100, 75);
    cout << "Pair < "<< pair->component1() << " , " << pair->component2() <<" >" << endl;
}

void pair_int_string(){
    Pair<int,string> *pair2 = new Pair<int,string>(100, "Victor Bolinches");
    cout << "Pair < "<< pair2->component1() << " , " << pair2->component2() <<" >" << endl;
}

void pair_string_int(){
    Pair<string,int> *pair3 = new Pair<string,int>("Hola Mundo", 75);
    cout << "Pair < "<< pair3->component1() << " , " << pair3->component2() <<" >" << endl;
}

void pair_double_float(){
    Pair<double,float> *pair4 = new Pair<double,float>(99.9992213, 7550043);
    cout << "Pair < "<< pair4->component1() << " , " << pair4->component2() <<" >" << endl;
}

void showExample010(){
    pair_Int_Int();
    pair_int_string();
    pair_string_int();
    pair_double_float();
}

int main (int argc, const char * argv[]) {
    showExample010();
    return 0;
}

Result

Pair < 100 , 75 >
Pair < 100 , Victor Bolinches >
Pair < Hola Mundo , 75 >
Pair < 99.9992 , 7.55004e+06 >

Templates Classes Vs Classes Templates

Class template is a template used to generate template classes.
Template class is an instance of a class template.

Template Functions

hpp

#ifndef Casteable_hpp
#define Casteable_hpp

#include <stdio.h>

template <class T>
    class Casteable {
    
    public :
    Casteable();
    ~Casteable();
   
template <class T2>
    T add(T2 arg, T2 arg2);
};

#include "Casteable.cpp"
#endif /* Casteable_hpp */

cpp

#ifdef Casteable_hpp

template <class T>
Casteable<T>::Casteable(){

}

template <class T>
template <class T2>
T Casteable<T>::add(T2 arg, T2 arg2){
    return arg + arg2;
    }

#endif

Main

#include <iostream>
#include "Casteable.hpp"
#include <sstream>

using namespace std;

void showExample(){
    Casteable<double> *casting = new Casteable<double>();
    double cast = casting->add<double>(1.0 , 3.0);
    std::cout << "Casting '1 + 3' to " << cast << std::endl;
}

int main(int argc, const char * argv[]) {
    showExample();
    return 0;
}

Result

Casting '1 + 3' to 4

Data Structures

Sequences

Vector

#include <iostream>
#include <sstream>
#include <vector>

using namespace std;

void _vector(){
    vector<int> *v = new vector<int>();
    
    
    cout<< "Empty " << v->empty() << endl;

    v->push_back(1);
    v->push_back(12222);
    v->push_back(2);
    v->push_back(3);
   
    for(const int &i : *v) // access by const reference
        cout << i << ' ';
    cout << '\n';
    
    cout<< "size " << v->size() << endl;
    
    auto it = v->begin();
    v->erase(it+0);

   
    for(auto i: *v) // access by value, the type of i is int
        cout << i << ' ';
    cout << '\n';
    
    cout<< "size " << v->size() << endl;

    v->insert(it,10);
    
    for(auto&& i: *v) // access by reference, the type of i is int&
        cout << i << ' ';
    cout << '\n';

    cout<< "size " << v->size() << endl;
    
    vector<int>::const_iterator cii;
    for(cii = v->begin(); cii != v->end(); cii++) // access by iterator
    {
        cout << *cii << " ";
    }
     v->pop_back();
     v->pop_back();
     v->pop_back();
    
    cout <<endl;

    cout<< "Size " << v->size() << endl;
    cout<< "Empty " << v->empty() << endl;
    v->clear();
    cout<< "Clear " << endl;
    cout<< "Empty " << v->empty() << endl;
}

void showExample014(){
    _vector();
}

int main(int argc, const char * argv[]) {
    showExample014();
    return 0;
}

Result

Empty 1
1 12222 2 3 
size 4
12222 2 3 
size 3
10 12222 2 3 
size 4
10 12222 2 3 
Size 1
Empty 0
Clear 
Empty 1

List

#include <iostream>
#include <sstream>
#include <list>

using namespace std;

void _list(){
    list<int> *_list = new list<int>();
    
    int isEmpty = _list->empty();
    cout<< "Empty " << isEmpty << endl;
    
    if(isEmpty){
      _list->push_back(15);
      _list->push_back(13);
      _list->push_back(81);
      _list->push_back(29);
      _list->push_back(37);
      _list->push_back(84);
      _list->push_back(29);
    }
    
    for(auto&& i: *_list)
        cout << i << ' ';
    cout << '\n';
    
    cout<< "size " << _list->size() << endl;

    _list->sort();
    
    
    for(auto&& i: *_list)
        cout << i << ' ';
    cout << '\n';
    
    cout<< "Size " << _list->size() << endl;
    cout<< "Empty " << _list->empty() << endl;
    _list->clear();
    cout<< "Clear " << endl;
    cout<< "Empty " << _list->empty() << endl;

}

void showExample014(){
    _list();
}

int main(int argc, const char * argv[]) {
    showExample014();
    return 0;
}

Result

Empty 1
15 13 81 29 37 84 29 
size 7
13 15 29 29 37 81 84 
Size 7
Empty 0
Clear 
Empty 1

Vector vs List in STL

vector:

* Contiguous memory.
* Pre-allocates space for future elements, so extra space required beyond what's necessary for the elements themselves.
* Each element only requires the space for the element type itself (no extra pointers).
* Can re-allocate memory for the entire vector any time that you add an element.
* Insertions at the end are constant, amortized time, but insertions elsewhere are a costly O(n).
* Erasures at the end of the vector are constant time, but for the rest it's O(n).
* You can randomly access its elements.
* Iterators are invalidated if you add or remove elements to or from the vector.
* You can easily get at the underlying array if you need an array of the elements.

list:

* Non-contiguous memory.
* No pre-allocated memory. The memory overhead for the list itself is constant.
* Each element requires extra space for the node which holds the element, including pointers to the next and previous elements in the list.
* Never has to re-allocate memory for the whole list just because you add an element.
* Insertions and erasures are cheap no matter where in the list they occur.
* It's cheap to combine lists with splicing.
* You cannot randomly access elements, so getting at a particular element in the list can be expensive.
* Iterators remain valid even when you add or remove elements from the list.
* If you need an array of the elements, you'll have to create a new one and add them all to it, since there is no underlying array.

Stack

#include <iostream>
#include <sstream>
#include <stack>


using namespace std;

void _stack(){
    stack<string> *_stack = new stack<string>();
    
    int isEmpty = _stack->empty();
    cout<< "Empty " << isEmpty << endl;
    cout<< "Size " << _stack->size() << endl;

    _stack->push("Hola");
    _stack->push("Mundo");
    
    while(!_stack->empty()){
        cout <<  _stack->top() << ' ';
        _stack->pop();
    }
    
    cout << '\n';
    
    _stack->push("Victor");
    _stack->push("Bolinches");
    
    while(!_stack->empty()){
        cout <<  _stack->top() << ' ';
        _stack->pop();
    }
    
    cout << '\n';
    
    cout<< "Size " << _stack->size() << endl;
    
}

void showExample014(){
    _stack();
}

int main(int argc, const char * argv[]) {
    showExample014();
    return 0;
}

Result

Empty 1
Size 0
Mundo Hola 
Bolinches Victor 
Size 0

Qeque

#include <iostream>
#include <sstream>
#include <queue>

using namespace std;

void _queue(){
    queue<string> *_queue = new queue<string>();
    
    int isEmpty = _queue->empty();
    cout<< "Empty " << isEmpty << endl;
    cout<< "Size " << _queue->size() << endl;
    
    _queue->push("Hola");
    _queue->push("Mundo");
    
    while(!_queue->empty()){
        cout <<  _queue->front() << ' ';
        _queue->pop();
    }
    
    cout << '\n';
    
    _queue->push("Victor");
    _queue->push("Bolinches");
    
    cout<< "Back " << _queue->back() << endl;
    cout<< "Front " << _queue->front() << endl;
    
    while(!_queue->empty()){
        cout <<  _queue->front() << ' ';
        _queue->pop();
    }
  
    cout << '\n';
    
    cout<< "Size " << _queue->size() << endl;
}


void showExample014(){
    _queue();
}

int main(int argc, const char * argv[]) {
    showExample014();
    return 0;
}

Result

Empty 1
Size 0
Hola Mundo 
Back: Bolinches
Front: Victor
Victor Bolinches 
Size 0

Associative

Set

Sets are containers that store unique elements following a specific order.

#include <iostream>
#include <sstream>
#include <set>


using namespace std;

void _set(){
    set<string> *_set = new set<string>();
    
    int isEmpty = _set->empty();
    cout<< "Empty " << isEmpty << endl;
    cout<< "Size " << _set->size() << endl;
    
    _set->insert("Hello");
    _set->insert("World");
    _set->insert("Victor");
    _set->insert("Bolinches");
    
    for(auto&& i : *_set)
        cout << i << ' ';
    cout << '\n';

    
    cout<< "Insert Alberto | Hello " << endl;
    _set->insert("Alberto");
    _set->insert("Hello");

    cout<< "Count Hello " << _set->count("Hello") << endl;

    for(auto&& i : *_set)
        cout << i << ' ';
    cout << '\n';
    
    cout<< "Erase " << _set->erase("Alberto") << endl;
    cout<< "Erase " << _set->erase("Bolinches") << endl;
    cout<< "Erase " << _set->erase("Victor") << endl;
    
    for(auto&& i : *_set)
        cout << i << ' ';
    cout << '\n';
}

void showExample014(){
    _set();
}

int main(int argc, const char * argv[]) {
    showExample014();
    return 0;
}

Resutl

Empty 1
Size 0
Bolinches Hello Victor World 
Insert Alberto | Hello 
Count Hello 1
Alberto Bolinches Hello Victor World 
Erase 1
Erase 1
Erase 1
Hello World 

Multiset

Multisets are containers that store elements following a specific order, and where multiple elements can have equivalent values.

#include <iostream>
#include <sstream>
#include <set>

using namespace std;

void _multiset(){
    
    int a[ 10 ] = { 7, 22, 9, 1, 18, 30, 100, 22, 85, 13 };
    int aSize = sizeof(a) / sizeof(int);
    multiset< int, std::less< int > > intMultiset(a, a + aSize);
    
    for ( auto it = intMultiset.begin(); it != intMultiset.end(); ++it)
        cout  << *it << "  ";
    cout << endl << endl;
    
    std::ostream_iterator< int > output( cout, " " );
    
    cout << intMultiset.count( 99 ) << " values of 15 in the multiset\n\n";
    
    intMultiset.insert( 99 );
    intMultiset.insert( 99 );
    
    cout << intMultiset.count( 99 ) << " values of 15 in the multiset\n\n";
    
    for ( auto it = intMultiset.begin(); it != intMultiset.end(); ++it)
        cout << "  " << *it;
    cout << endl << endl;

}

void showExample014(){
    _multiset();
}

int main(int argc, const char * argv[]) {
    showExample014();
    return 0;
}

Result

1  7  9  13  18  22  22  30  85  100  

0 values of 99 in the multiset

2 values of 99 in the multiset

1  7  9  13  18  22  22  30  85  99 99 100

Map

The map<key, set<value>> will only store each value once for a specific key. 
To do that, it will have to be able to compare the values, not just the keys.

#include <iostream>
#include <sstream>
#include <map>


using namespace std;


void _map(){
    map<string,int> *_map = new map<string,int>();
    
    int isEmpty = _map->empty();
    cout<< "Empty " << isEmpty << endl;
    cout<< "Size " << _map->size() << endl;
    
    _map->insert(pair<string,int>("Hello",100));
    _map->insert(pair<string,int>("World",11));
    _map->insert(pair<string,int>("Victor",32));
    _map->insert(pair<string,int>("Bolinches",4324));
    
    map<string,int>::iterator it = _map->begin();
    for (it=_map->begin(); it!=_map->end(); ++it)
        cout << it->first << " => " << it->second << '\n';
    
    cout<< "Insert Alberto" << endl;
    _map->insert(pair<string,int>("Alberto",3233));
    
    cout<< "size " << _map->size() << endl;
    
    for(it = _map->begin() ; it != _map->end() ; ++it)
         cout << it->first << " => " << it->second << '\n';
    
    _map->clear();
    
    cout<< "size " << _map->size() << endl;
}

void showExample014(){
    _map();
}

int main(int argc, const char * argv[]) {
    showExample014();
    return 0;
}

Result

Empty 1
Size 0
Bolinches => 4324
Hello => 100
Victor => 32
World => 11
Insert Alberto
size 5
Alberto => 3233
Bolinches => 4324
Hello => 100
Victor => 32
World => 11
size 0

MultiMap

The multimap stores pairs of (key, value) where both key and value can appear several times.

#include <iostream>
#include <sstream>
#include <map>

using namespace std;

void _multimap(){
    multimap<string, int> *_multimap = new multimap<string, int>();
    
    _multimap->insert(pair<string, int>("a", 1));
    _multimap->insert(pair<string, int>("c", 2));
    _multimap->insert(pair<string, int>("b", 3));
    _multimap->insert(pair<string, int>("b", 4));
    _multimap->insert(pair<string, int>("a", 5));
    _multimap->insert(pair<string, int>("b", 6));

    cout << "Key a: " << _multimap->count("a") << endl;
    cout << "Key b: " << _multimap->count("b") << endl;
    cout << "Key c: " << _multimap->count("c") << endl;
    
    for (auto it = _multimap->begin(); it != _multimap->end(); ++it)
        cout << "  [" << it->first << ", " << it->second << "]" << endl;
   
    pair<multimap<string, int>::iterator, multimap<string, int>::iterator> ppp;
    
    ppp = _multimap->equal_range("b");

    cout << endl << "Range of \"b\" elements:" << endl;
    for (auto it2 = ppp.first;it2 != ppp.second; ++it2)
        cout << "  [" << (*it2).first << ", " << (*it2).second << "]" << endl;
    
    _multimap->clear();
}

void showExample014(){
    _multimap();
}

int main(int argc, const char * argv[]) {
    showExample014();
    return 0;
}

Result

Key a: 2
Key b: 3
Key c: 1
  [a, 1]
  [a, 5]
  [b, 3]
  [b, 4]
  [b, 6]
  [c, 2]

Range of "b" elements:
  [b, 3]
  [b, 4]
  [b, 6]
  

#Advanced

Binary File

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

void showExample000(){
    streampos size;
    char* memblock;
    
    ifstream file("File.bin", ios::in | ios::binary | ios::ate);
    if (!file.is_open()){
        cout << "Unable to open file";
        return ;
    }
    
    size = file.tellg();
    memblock = new char [size];
    file.seekg (0, ios::beg);
    file.read (memblock, size);
    file.close();
    
    cout << "the entire file content is in memory";
    cout << memblock <<endl;
    cout << "delete[] memblock;" << endl << endl;
    delete[] memblock;
}

int main(int argc, const char * argv[]) {
    showExample000();
    return 0;
}

Result

"Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit ...

"Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit ...


Victor Bolinches Marin
delete[] memblock;

Bitwise Operators

#include <iostream>
using namespace std;

void _and(){
    
    unsigned int a = 60;	  // 0011 1100
    unsigned int b = 13;	  // 0000 1101
    
    cout << "  (60 = 0011 1100) " << endl;
    cout << " &(13 = 0000 1101) " << endl;
    cout << "____________________" << endl;
    cout << "   " << (a & b ) << " = 0000 1100 " << endl << endl;
    
    
    unsigned int c = 50;	  // 0011 1100
    unsigned int d = 35;	  // 0000 1101
    
    cout << "  (50 = 0011 0010) " << endl;
    cout << " &(35 = 0010 0011) " << endl;
    cout << "____________________" << endl;
    cout << "   " << (c & d ) << " = 0010 0010 " << endl << endl;
    
}

void _or(){
    
    unsigned int a = 60;	  // 0011 1100
    unsigned int b = 13;	  // 0000 1101
    
    cout << "  (60 = 0011 1100) " << endl;
    cout << " |(13 = 0000 1101) " << endl;
    cout << "____________________" << endl;
    cout << "   " << (a | b ) << " = 0011 1101 " << endl << endl;
    
    
    unsigned int c = 50;	  // 0011 1100
    unsigned int d = 35;	  // 0000 1101
    
    cout << "  (50 = 0011 0010) " << endl;
    cout << " |(35 = 0010 0011) " << endl;
    cout << "____________________" << endl;
    cout << "   " << (c | d ) << " = 0011 0011 " << endl << endl;

}

void _xor(){
    unsigned int a = 60;	  // 0011 1100
    unsigned int b = 13;	  // 0000 1101
    
    cout << "  (60 = 0011 1100) "  << endl;
    cout << " ^(13 = 0000 1101) "  << endl;
    cout << "____________________" << endl;
    cout << "   " << (a ^ b ) << " = 0011 0001 " << endl << endl;
    
    
    unsigned int c = 50;	  // 0011 1100
    unsigned int d = 35;	  // 0000 1101
    
    cout << "  (50 = 0011 0010) "  << endl;
    cout << " ^(35 = 0010 0011) "  << endl;
    cout << "____________________" << endl;
    cout << "   " << (c ^ d ) << " = 0010 0001 " << endl << endl;
}


void complement(){
    cout << "4 = 0100" << endl;
    cout << "~4 = 1111 1011 = " << (~4) << endl;
    cout << "~4 & 0x0F = 0000 1011 = " << (~4 & 0x0F) << endl << endl;
    
    unsigned int a = 4;
    cout << "unsigned ~4 = ... 1111 1111 1011 = " << (~a) << endl;
    cout << "4 = 0000 0100" << endl;
    cout << "~4 = 1111 1011 = " << (~4) << endl;
    cout << "~4 & 0xFF = 1111 1011 = " << (~4 & 0xFF) << endl << endl;
}


void leftShift(){
    cout << "3 = 0011" << endl;
    cout << "3 << 1 = 0011 << 1 = 0110 = " << (3 << 1) << endl;
    cout << "3 << 2 = 0011 << 2 = 1100 = " << (3 << 2) << endl;
    cout << "3 << 3 = 0011 << 3 = 0001 1000 = " << (3 << 3) << endl;
    cout << "(3 << 3) & 0x0F = 0011 << 3 = 1000 = " << ((3 << 3) & 0x0F) << endl << endl;
}

void rigthShift(){
    cout << "12 = 1100" << endl;
    cout << "12 >> 1 = 1100 >> 1 = 0110 = " << (12 >> 1) << endl;
    cout << "12 >> 2 = 1100 >> 2 = 0011 = " << (12 >> 2) << endl;
    cout << "12 >> 3 = 1100 >> 3 = 0001 = " << (12 >> 3) << endl;
    cout << "(12 >> 4) & 0x0F = 1100 >> 4 = 0000 = " << ((12 >> 4) & 0x0F) << endl;
}


void showExample001(){
    _and();
    _or();
    _xor();
    complement();
    leftShift();
    rigthShift();
}

int main(int argc, const char * argv[]) {
    showExample001();
    return 0;
}

Result

  (60 = 0011 1100) 
 &(13 = 0000 1101) 
____________________
   12 = 0000 1100 

  (50 = 0011 0010) 
 &(35 = 0010 0011) 
____________________
   34 = 0010 0010 

  (60 = 0011 1100) 
 |(13 = 0000 1101) 
____________________
   61 = 0011 1101 

  (50 = 0011 0010) 
 |(35 = 0010 0011) 
____________________
   51 = 0011 0011 

  (60 = 0011 1100) 
 ^(13 = 0000 1101) 
____________________
   49 = 0011 0001 

  (50 = 0011 0010) 
 ^(35 = 0010 0011) 
____________________
   17 = 0010 0001 

4 = 0100
~4 = 1111 1011 = -5
~4 & 0x0F = 0000 1011 = 11

unsigned ~4 = ... 1111 1111 1011 = 4294967291
4 = 0000 0100
~4 = 1111 1011 = -5
~4 & 0xFF = 1111 1011 = 251

3 = 0011
3 << 1 = 0011 << 1 = 0110 = 6
3 << 2 = 0011 << 2 = 1100 = 12
3 << 3 = 0011 << 3 = 0001 1000 = 24
(3 << 3) & 0x0F = 0011 << 3 = 1000 = 8

12 = 1100
12 >> 1 = 1100 >> 1 = 0110 = 6
12 >> 2 = 1100 >> 2 = 0011 = 3
12 >> 3 = 1100 >> 3 = 0001 = 1
(12 >> 4) & 0x0F = 1100 >> 4 = 0000 = 0

Bit Mask

#include <iostream>
using namespace std;

void showExample002(){
    const unsigned int lowMask = 0xF; // 0000 1111
    
    int num = 0xFF;
    cout << "0xFF = 1111 1111 = 255" <<endl;
    
    num &= lowMask;
    
    std::cout << "The 4 low bits have value: " << num << endl;
}

int main(int argc, const char * argv[]) {
    showExample002();
    return 0;
}

Result

0xFF = 1111 1111 = 255
The 4 low bits have value: 15

Bitset

#include <bitset>
#include <iostream>
using namespace std;

enum BitOptions
{
    OPTION_1 = 0,
    OPTION_2 = 1,
    OPTION_3 = 2,
    OPTION_4 = 3,
    OPTION_5 = 4,
    OPTION_6 = 5,
    OPTION_7 = 6,
    OPTION_8 = 7
};

void showExample003(){
    bitset<8> *bits = new bitset<8>(0x2); // 0000 0010
    bits->set(OPTION_5);                  // 0001 0010
    bits->flip(OPTION_6);                 // 0011 0010
    bits->reset(OPTION_6);                // 0001 0010
    
    cout << "Bit 4 has value: " << bits->test(OPTION_5) << '\n';
    cout << "Bit 5 has value: " << bits->test(OPTION_6) << '\n';
    cout << "All the bits: " << bits << '\n';
    
}

int main(int argc, const char * argv[]) {
    showExample003();
    return 0;
}

Result

Bit 4 has value: 1
Bit 5 has value: 0
All the bits: 0001 0010

XOR Encrytion/Decryption

#include <iostream>
#include <sstream>
using namespace std;

static char key = 'Z';
static int mask = 999009909;

void showExample004(){
    
    string name = "Victor Bolinches Marin";
    cout << name << endl;
    cout << "Encrytion" << endl;
    for(auto i = 0 ; i < name.size() ; i++ ){
        name[i] = name[i] ^ key + mask;
    }
    
    cout << name << endl;
    cout << "Decryption" << endl;
    
    for(auto i = 0 ; i < name.size() ; i++ ){
        name[i] = name[i] ^ key + mask;
    }
    
    cout << name << endl;
}

int main(int argc, const char * argv[]) {
    showExample004();
    return 0;
}

Result

Victor Bolinches Marin

Encrytion
\231\246\254\273\240\275\243\246\241\254\247\252\274\275\246\241

Decryption
Victor Bolinches Marin

Streams

#include <iostream>
#include <fstream>

using namespace std;

void showExample005(){
    streampos size;
    char * memblock;
    
    ifstream file ("file.bin", ios::in|ios::binary|ios::ate);
    if (file.is_open())
    {
        size = file.tellg();
        memblock = new char [size];
        file.tellg();
        file.seekg (0, ios::beg);
        file.read (memblock, size);
        file.close();
        
        cout << "Content is in memory: " << (size) << "bytes"<< endl;
        cout << memblock << endl;
        
        delete[] memblock;
    }
    else
        cout << "Unable to open file";
}

int main(int argc, const char * argv[]) {
    showExample005();
    return 0;
}

Result

Content is in memory: 1929bytes
get and put stream positioning
All i/o streams objects keep internally -at least- one internal position:
...

Function Pointers

#include <iostream>
using namespace std;

int Muestra1();
int Muestra2();

int (*pMuestra)();
void (*pEjecuta)(int);

int Muestra1() {
    cout << "Muestra 1" << endl;
    return 1;
}

int Muestra2() {
    cout << "Muestra 2" << endl;
    return 2;
}

void Ejecuta(int resutl){
    cout << " y ejecuta: "  << resutl << endl;
}


void showExample006(){

        int num;
        pEjecuta = &Ejecuta;
    
        
        do {
            cout << "Introduce un número entre 1 y 2, " << "0 para salir: ";
            cin >> num;
            if(num >= 1 && num <=2) {
                switch(num) {
                    case 1:
                        pMuestra = &Muestra1;
                        break;
                    case 2:
                        pMuestra = &Muestra2;
                        break;
                }
                if(num != 0 )
                    pEjecuta(pMuestra());
            }
        } while(num != 0);
    }
    
    
int main(int argc, const char * argv[]) {
    showExample006();
    return 0;
}

Result

Introduce un número entre 1 y 2, 0 para salir: 2
Muestra 2
 y ejecuta: 2
Introduce un número entre 1 y 2, 0 para salir: 1
Muestra 1
 y ejecuta: 1
Introduce un número entre 1 y 2, 0 para salir: 0

Functors

#include <iostream>
using namespace std;

class Math
{
private:
    int _x;
    
public:
    
    Math (int x) : _x( x ) {}
    
    int operator+ (int y) { return _x + y; }
    int operator- (int y) { return _x - y; }
    int operator* (int y) { return _x * y; }
};


void showExample007(){
    Math *math =  new Math(50);
    cout << "50 math->operator+(69) = " << math->operator+(69) << endl;
    cout << "50 math->operator-(69) = " << math->operator-(69) << endl;
    cout << "50 math->operator*(69) = " << math->operator*(69) << endl;

}

int main(int argc, const char * argv[]) {
    showExample007();
    return 0;
}

Result

50 math->operator+(69) = 119
50 math->operator-(69) = -19
50 math->operator*(69) = -19

Lambdas

#include <iostream>
#include <vector>

using namespace std;

void functionLambda(){
    vector<int> c { 1,2,3,4,5,6,7 };
    int x = 5;
    c.erase(
            std::remove_if(
                           c.begin(),
                           c.end(),
                           [x](int n) { return n < x; } ),
            c.end()
        );
    
    cout << "c: ";
    
    for (auto i: c) {
        std::cout << i << ' ';
    }
    
    cout << '\n';
    
    function<int (int)> func = [](int i) { return i + 4; };
    cout << "func: " << func(6) << '\n';
}

void functionVoidInline(){
    auto func = [] () { cout << "function Void Inline" << endl; };
    func();
}

void functionIntInline(){
    auto func = [] () -> int { cout << "function Int Inline" << endl << "result: "; return -999; };
    cout  << func()  << endl;
}

void bucles(){
    vector<int> *vec = new vector<int>();
    vec->push_back(123);
    vec->push_back(221);
    vec->push_back(32);
    vec->push_back(1);
    for_each( vec->begin(), vec->end(), [] (int val)
    {
        cout << val << endl;
    });
}

void showExample008(){
    functionVoidInline();
    functionIntInline();
    bucles();
    functionLambda();
}

int main(int argc, const char * argv[]) {
    showExample008();
    return 0;
}

Result

function Void Inline
function Int Inline
result: -999
123
221
32
1
c: 5 6 7 
func: 10

Auto_ptr

#include <iostream>
#include <vector>

using namespace std;

void dynamicMemory(){
    vector<int> *v = new vector<int>();
    v->push_back(1);
    v->push_back(22);
    v->push_back(333);
    
    for(auto&& i : *v){
        cout<< i << endl;
    }
    
    delete v;
}

void Auto_PTR(){
    auto_ptr<vector<int>> v(new vector<int>());
    
    v->push_back(123);
    v->push_back(6213);
    v->push_back(7784);
    
    for(auto&& i : *v){
        cout<< i << endl;
    }
    
    
}

void showExample009(){
    dynamicMemory();
    Auto_PTR();
}

int main(int argc, const char * argv[]) {
    showExample009();
    return 0;
}

Result

1
22
333
123
6213
7784

Dynamic Memory vs Auto_ptr

The Good

    auto_ptr objects store pointers and handle deleting the pointer when the auto_ptr object goes out of scope
    Using auto_ptr helps avoid memory leaks associated with exceptions and minimizes the amount of cleanup code required

Gotchas

    Copying an auto_ptr changes the object being copied by setting the contents to NULL
    auto_ptr objects are not guaranteed to work correctly with the standard template library containers

Double Free attack

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define BUFSIZER1   512
#define BUFSIZER2   ((BUFSIZER1/2) - 8)

void showExample010(int argc, const char * argv[]){
    char *buf1R1;
    char *buf2R1;
    char *buf2R2;
    char *buf3R2;
    
    buf1R1 = (char *) malloc(BUFSIZER1);
    buf2R1 = (char *) malloc(BUFSIZER1);
    
    free(buf2R1);
    printf("char *buf2R1 = %c,  Address = %u\n", *buf2R1, &buf2R1);

    
    buf2R2 = (char *) malloc(BUFSIZER2);
    buf3R2 = (char *) malloc(BUFSIZER2);
    
    strncpy(buf2R1, *argv+1, BUFSIZER1-1);
   
    free(buf1R1);
    printf("char *buf1R1 = %c,  Address = %u\n", *buf1R1, &buf1R1);
    free(buf2R2);
    printf("char *buf2R2 = %c,  Address = %u\n", *buf2R2, &buf2R2);
    free(buf3R2);
    printf("char *buf3R2 = %c,  Address = %u\n", *buf3R2, &buf3R2);
    
}

int main(int argc, const char * argv[]) {
    showExample010(argc, argv);
    return 0;
}

Result

char *buf2R1 = (null),  Address = 1606416240
char *buf1R1 = (null),  Address = 1606416248
char *buf2R2 = (null),  Address = 1606416232
char *buf3R2 = (null),  Address = 1606416224

Multiple Inheritance

#include <iostream>

class A {
    public :
    virtual void f();
};

class B {
    public:
    virtual void f();
};

class C : public A ,public B {
    public :
    void f(){}
};

void showExample011(){
    C *pc = new C;
    pc->f();
    pc->A::f();
    pc->B::f();
    
    A* pa = pc;
    pc->f();

}

int main(int argc, const char * argv[]) {
    showExample011();
    return 0;
}

Virtual Inheritance

#include <iostream>
#include <string>
using namespace std;

class Base {
public:
protected:
    int data_;
};

class Child1 : public virtual Base {
    public:
           ...
};

class Child2 : public virtual Base {
    
    public:
             ...
};

class Join : public Child1, public Child2 {
public:
    int method()
    {
        data_ = 1;
        return data_;
    }
};

void showExample012()
{
    Join *j = new Join();
    Base *b = j;
    
    cout << j->method() << endl;
    cout << b << endl;
}

int main(int argc, const char * argv[]) {
    showExample012();
    return 0;
}

Result

1
0x1002000b0

Virtual Destructors

#include <iostream>
using namespace std;

class Base
{
    
public:
    Base(){
        cout << "Constructing Base" << endl;
    }
    
    ~Base(){
        cout << "Destroying Base" << endl;
    }
};

class BaseVirtual
{
    
public:
    BaseVirtual(){
        cout << "Constructing BaseVirtual" << endl;
    }
    
   virtual ~BaseVirtual(){
        cout << "Destroying BaseVirtual" << endl;
    }
};


class Derive: public Base, public BaseVirtual
{
    
public:
    Derive(){
        cout <<  "Constructing Derive"<< endl;
    }
    
    ~Derive(){
        cout << "Destroying Derive"<< endl;
    }
};


void showExample013(){
    Base *basePtr = new Derive();
    delete basePtr;
    
    cout<< endl;

    BaseVirtual *BaseVirtualPtr = new Derive();
    delete BaseVirtualPtr;
    
    cout<< endl;
    
    auto_ptr<BaseVirtual> auto_BaseVirtualPtr(new Derive());
    
}

int main(int argc, const char * argv[]) {
    showExample013();
    return 0;
}

Result

Constructing Base
Constructing BaseVirtual
Constructing Derive
Destroying Base

Constructing Base
Constructing BaseVirtual
Constructing Derive
Destroying Derive
Destroying BaseVirtual
Destroying Base

Constructing Base
Constructing BaseVirtual
Constructing Derive
Destroying Derive
Destroying BaseVirtual
Destroying Base

References :

About

Advanced c/c++ Programming Tutorial with XCode

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 98.2%
  • C 1.8%