C++ notes


  // Example 1 Vector of strings
#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
#include <list> //
using namespace std;
int main ()
{
 // Example 1
 std::vector<std::string> myVector;
 char msgname[16];
 for (int i = 1; i <= 5; i++)
  {
   sprintf (msgname, "SWITCH-%d", i);
   myVector.push_back (msgname);
  }

 for (std::vector<std::string>::iterator t = myVector.begin (); t != myVector.end (); ++t)
  {
   std::cout << *t << std::endl;
  }

}
SWITCH-1
SWITCH-2
SWITCH-3
SWITCH-4
SWITCH-5 

// Example 2 

#include <iostream>
#include <string>

int main ()
{
 // notes
 std::string test1 = "abcde";
 char test2[6] = "abcde";
 char test3[6];
 strcpy (test3, "abcde");

 std::cout << "test1: " << test1 << std::endl;
 std::cout << "test2: " << test3 << std::endl;
 std::cout << "test3: " << test3 << std::endl;
}

test1: abcde
test2: abcde
test3: abcde
// Example 3 structures inside List

#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
#include <list>
//using namespace std;
int main ()
{

 // Example 2
 struct myData
 {
  int id;
  std::string name;
 };

 typedef std::list<myData> myDataList;
 myDataList objMyDataList;
 char switchName[16];

 for (int i = 1; i <= 5; i++)
  {
   sprintf (switchName, "SWITCH-%d", i);
   myData objMyData;
   objMyData.id=i*100;
   objMyData.name = switchName;
   objMyDataList.push_back (objMyData);
  }

 for(std::list<myData>::iterator itt =objMyDataList.begin (); itt!= objMyDataList.end(); itt++){
    std::cout << " SW-ID: " << itt->id  << " , ";
    std::cout << " SW-Name: " <<  itt->name << std::endl;
  }
}

 SW-ID: 100 ,  SW-Name: SWITCH-1
 SW-ID: 200 ,  SW-Name: SWITCH-2
 SW-ID: 300 ,  SW-Name: SWITCH-3
 SW-ID: 400 ,  SW-Name: SWITCH-4
 SW-ID: 500 ,  SW-Name: SWITCH-5




// Example 4 structures inside STL List
 #include <iostream>
#include <string>
#include <vector>
#include <cstdio>
#include <list>

 using namespace std;

struct mystruct {
char name[20];
int grade;
};
int main ()
{
int i;
mystruct names;

list<mystruct> mylist;

for (i=0;i<5;i++) {
strcpy(names.name, "MOH");
names.grade = i+78;
mylist.push_back(names);
}

list<mystruct>::iterator it;
it = mylist.begin();
while (it != mylist.end()) {
cout << "Name: " << it->name << " Grade: " << it->grade << endl;
it++;
}

return 0;
}


Name: MOH Grade: 78
Name: MOH Grade: 79
Name: MOH Grade: 80
Name: MOH Grade: 81
Name: MOH Grade: 82



// Example 5  map – advance
#include<iostream>
#include<map>

using namespace std;

int main ()
{
 std::map <int, int> moh;
 for (int i = 0; i < 5; i++) {  moh[i] = 10 * i;  }

 auto iter = moh.begin ();
 while (iter != moh.end ())
  {
   std::cout << "index: " << iter->first << ", value: " << iter->second << "\n";
   ++iter;
  }

 auto it=moh.begin ();
 std::advance(it, 2);
 std::cout << "\nindex: " << it->first << ", value: " << it->second << std::endl;
}



index: 0, value: 0
index: 1, value: 10
index: 2, value: 20
index: 3, value: 30
index: 4, value: 40

index: 2, value: 20


// Example 6  map – erase 

#include<iostream>
#include<map>

using namespace std;

int main ()
{
 std::map <int, int> moh;
 for (int i = 0; i < 5; i++)
  {
   moh[i] = 10 * i;
  }

 auto iter = moh.begin ();
 while (iter != moh.end ())
  {
   std::cout << "index: " << iter->first << ", value: " << iter->second << "\n";
   ++iter;
  }


 std::cout << "\nadvance iter to map2: " << "\n";
 auto it = moh.begin ();
 std::advance (it, 2);
 std::cout << "index: " << it->first << ", value: " << it->second << "\n\n";
 moh.erase (it);

 std::cout << "erase map 2: " << "\n";

 auto iterrr = moh.begin ();
 while (iterrr != moh.end ())
  {
   std::cout << "index: " << iterrr->first << ", value: " << iterrr->second << "\n";
   ++iterrr;
  }

}


index: 0, value: 0
index: 1, value: 10
index: 2, value: 20
index: 3, value: 30
index: 4, value: 40

advance iter to map2:
index: 2, value: 20

erase map 2:
index: 0, value: 0
index: 1, value: 10
index: 3, value: 30
index: 4, value: 40



// Example 7  vector – erase

vec.erase(iter) always returns the next valid iterator, if you erase the last element it will point to .end(). At the end of the loop ++iter is always called, so you increment .end() which is not allowed.
Here is an example of wrong usage of .erase():
#include <vector>
#include <iostream>

int
main (int argc, char* argv[])
{
 std::vector< int > moh;

 moh.push_back (1);
 moh.push_back (2);
 moh.push_back (3);
 moh.push_back (4);
 moh.push_back (5);
 moh.push_back (6);

 for (auto iter = moh.begin (); iter != moh.end (); ++iter)
  {
   if (*iter == 6) { moh.erase (iter); }
   std::cout << " vec = " << *iter << std::endl;
  }
}


The correct way of using  erase() is as follows,

#include <vector>
#include <iostream>
int
main (int argc, char* argv[])
{
 std::vector< int > moh;

 moh.push_back (1);
 moh.push_back (2);
 moh.push_back (3);
 moh.push_back (4);
 moh.push_back (5);
 moh.push_back (6);

 for (auto iter = moh.begin (); iter != moh.end (); )
  {
   if (*iter == 6)
    {
     moh.erase (iter);
    } else {
     ++iter;
     }

  }

  for (auto it = moh.begin (); it != moh.end (); ++it)
  {
       std::cout << " vec = " << *it  << std::endl;
   }
}



 vec = 1
 vec = 2
 vec = 3
 vec = 4
 vec = 5



// Example 8  INT vector – Next Prev Back End Begin
end() returns the iterator (not an element) past-the-end of the vector. 
back() returns a reference to the last element. It has a counterpart front() as well. 
Don't use * with back() and front().

#include <vector>
#include <iostream>

int main (int argc, char* argv[])
{
 std::vector< int > moh;
 moh.push_back (10);
 moh.push_back (20);
 moh.push_back (30);
 moh.push_back (40);
 moh.push_back (50);

 auto iterBegin = moh.begin ();
 auto iterNext = std::next (iterBegin, 3);
 auto iterPrev = std::prev (iterNext, 2);


  
auto iterFront= moh.front ();

 auto iterNextOut = std::next (iterBegin, 500); // out of range returns random number (sometimes zero)
 auto iterPrevOut = std::prev (iterBegin, 500);
// out of range returns random number  

 auto iterEnd = moh.end ();   // does NOT return ZERO
 auto iterBack = moh.back (); // returns the last element in the vector

 std::cout << " iterBegin = " << *iterBegin << std::endl;
 std::cout << " iterNext = " << *iterNext << std::endl;
 std::cout << " iterPrev = " << *iterPrev << std::endl;


std::cout << "\n iterFront = " <<  iterFront << std::endl;

 std::cout << "\n iterNextOut = " << *iterNextOut << std::endl;
 std::cout << " iterPrevOut = " << *iterPrevOut << std::endl;

 std::cout << "\n iterE = " << *iterEnd << std::endl;
 std::cout << " iterB = " << iterBack << std::endl;
}


 iterBegin = 10
 iterNext = 40
 iterPrev = 20


 iterFront = 10

 iterNextOut = 0
 iterPrevOut = 65537

 iterE = 32767
 iterB = 50


// Example 9  Erasing from list

#include <iostream>
#include <list>

int main ()
{

 struct PakcetsToSend
 {
  unsigned int pktId;
 };
 typedef std::list<PakcetsToSend> PakcetsToSendList;
 PakcetsToSendList sentPakcetsList;



 // set some values:
 for (int i = 1; i <= 5; ++i)
  {
   PakcetsToSend pktSent;
   pktSent.pktId = 10 * i;
   sentPakcetsList.push_back (pktSent);
  }

 std::cout << "mylist contains:\n";

 std::list<PakcetsToSend>::iterator iter;
 iter = sentPakcetsList.begin ();
 int index = 0;
 while (iter != sentPakcetsList.end ())
  {
   std::cout << ++index << "  SQN: " << iter->pktId << "\n";
   iter++;
  }

    std::list<PakcetsToSend>::iterator it;
    it = sentPakcetsList.begin();

    while (it != sentPakcetsList.end()) {
        if (it->pktId == 30) {
            std::cout << "ackArrivedFreeBuffer erase : " << it->pktId << "\n";
            it = sentPakcetsList.erase(it);
            break;
        } else {
         std::cout << " SQN: " << it->pktId    << "\n";
            it++;
        }
    }

 std::cout << "\nmylist contains:\n";
 std::list<PakcetsToSend>::iterator iterrr;
 iterrr = sentPakcetsList.begin ();
 int index2 = 0;
 while (iterrr != sentPakcetsList.end ())
  {
   std::cout << ++index2 << "  SQN: " << iterrr->pktId << "\n";
   iterrr++;
  }

 return 0;
}



mylist contains:
1  SQN: 10
2  SQN: 20
3  SQN: 30
4  SQN: 40
5  SQN: 50
 SQN: 10
 SQN: 20
ackArrivedFreeBuffer erase : 30

mylist contains:
1  SQN: 10
2  SQN: 20
3  SQN: 40
4  SQN: 50



// Example 10  Random number generator using seeds

#include <iostream>
#include <sstream>
#include <ctime>
#include <random>

int main()
{
    int seedValue = 500;
    for (int i = 0; i < 5; i++) {
        srand(seedValue);  // wrong-- this should be called just once
        int selected = ((rand() % 4));
        std::cout << selected << "\n";
    }
}

??? WRONG
0
0
0
0
0


The correct code is as follows: 
#include <iostream>
#include <sstream>
#include <ctime>
#include <random>
int main()
{
    int seedValue = 500;

    srand(seedValue);  // get same values each run as we use same seedValue
  // to get different values use srand(time(NULL))
     for (int i = 0; i < 5; i++) {
        int selected = ((rand() % 4));
        std::cout << selected << "\n";
    }
}
// we get same values each run as we use same seedValue
0
1
1
1
2



// Example 11   mt19937: Pseudo-random number generation
 Example 11.a
#include <iostream>
#include <sstream>
#include <ctime>
#include <random>
int main()
{
    int arrivalRate = 250;
    for (int i = 0; i < 5; i++) {
        std::random_device rd;
        std::mt19937 rng(rd()); // mt19937: Pseudo-random number generation
        std::exponential_distribution<double> exp(arrivalRate);
        std::cout <<  exp.operator()(rng) << "\n";
    }
}


We get different output each run:
0.00277043
0.00323534
0.00313602
0.000435214
0.00498137


 Example 11.b
#include <iostream>
#include <sstream>
#include <ctime>
#include <random>
int main()
{

     std::random_device rd;
     int arrivalRate = 250;
     for (int i = 0; i < 5; i++) {
      // take this line out of the for loop
        std::mt19937 rng(rd()); // mt19937: Pseudo-random number generation
        std::exponential_distribution<double> exp(arrivalRate);
        std::cout <<  exp.operator()(rng) << "\n";
    }
}
  Same here, we get different output each run. 



 Example 11.c
#include <iostream>
#include <sstream>
#include <ctime>
#include <random>
int main()
{
     int seedValue = 500;
    int arrivalRate = 250;
    for (int i = 0; i < 5; i++) {
        std::mt19937 rng(seedValue); // mt19937: Pseudo-random number generation
        std::exponential_distribution<double> exp(arrivalRate);
        std::cout <<  exp.operator()(rng) << "\n";
    }
}


??? WRONG results
0.000310729
0.000310729
0.000310729
0.000310729
0.000310729
  Example 11.d
#include <iostream>
#include <sstream>
#include <ctime>
#include <random>
int main()
{
     int seedValue = 500;
    int arrivalRate = 250;
    std::mt19937 rng(seedValue); // mt19937: Pseudo-random number generation
    for (int i = 0; i < 5; i++) {
        std::exponential_distribution<double> exp(arrivalRate);
        std::cout <<  exp.operator()(rng) << "\n";
    }
}
 // we get same values each run as we use same seedValue
0.000310729
0.00294197
0.000185657
0.0155086
0.00229585



// Example 12   exponential_distribution    
#include <iostream>
#include <sstream>
#include <ctime>
#include <random>
int main()
{
    int seedValue = 100;
    int arrivalRate = 1;
    // srand(seedValue);
    std::mt19937 PRNG;
    std::exponential_distribution<double> expDistribution;
    PRNG = std::mt19937(seedValue);
    expDistribution = std::exponential_distribution<double> (arrivalRate);
    for (int i = 0; i < 5; i++) {
        double getExp = expDistribution.operator()(PRNG);
         std::cout << getExp << "\n";
    }

}


 // we get same values each run as we use same seedValue
1.11217
0.531107
0.747355
0.160879
0.170446




// Example 13    Function pointer

#include <iostream>
using namespace std;

int add(int a, int b){ return a+b; }
void hi(){ cout << "Hi there! \n";  }
void hello(char* name){ cout << "Hello Mr. " << name << "\n";  }

int  main ()
{

 int (*funptr)(int,int);
 funptr = add;
 cout << funptr(2,4) << "\n";


 void (*funptr2)();
 funptr2 = hi;
 funptr2();

 void (*funptr3)(char*);
 funptr3 = hello;
 char *name ="Moh";
 funptr3(name) ;


 return 0;
}


 6
Hi there!
Hello Mr. Moh



// Example 14    callback 


#include <iostream>
using namespace std;

int addFun(int a, int b , int (*funptr)(int,int)){
 return a + b + funptr(a,b)  ; 
// funptr(a,b) is callback to add
 }

int add(int a, int b){  return a+b; }

int main (int argc, char** argv)
{
 cout << " result = " << addFun(5,5,add) << "\n";
 return 0;
}


 result = 20


// Example 15    callback

this is the hi function


// Example 16    

ampersand


#include <string>
#include <vector>
#include <iostream>

 int main(int argc, char *argv[])
 {
     std::cout << "Have " << argc << " arguments:" << std::endl;
     for (int i = 0; i < argc; ++i) {
         std::cout << argv[i] << std::endl;
     }
     
     std::string my_var(argv[2]);
     std::cout << my_var << std::endl;
     
     
     return 0;

 }


 g++ test.cpp
 ./a.out hello1  hello2  hello3 


Have 4 arguments:
./a.out
hello1
hello2
hello3

hello2

// Example 17
 
 Pass vector by reference 
 
#include <vector>
#include <iostream>
using namespace std;

void myVecfunction(std::vector<int>& vec) {
    //    vec.push_back(40);
    //    vec.pop_back();
    delete &vec;
}

int main() {

    std::vector<int> *myVec = new std::vector<int>;
    myVec->push_back(10);
    myVec->push_back(20);
    myVec->push_back(30);
    std::cout << myVec->size() << " \n";
    myVecfunction(*myVec);


    return 0;
}



No comments: