Table of Contents

1 C and C++ Tutorial

1.1 C int and long do not have default size but there are minimum ranges for those types.


1.2 C const char pointer and char poitner

  • char s[] = "abc"; is const char pointer, it can not be modified.
  • char* s = "abc"; is a pointer, it can be modified
void fun(char* arr){
   arr[0] = 'k';
}

// can not modify the const pointer 
char s[] = "abc";
fun(s);
printf("%s", s); // => abc

// modify the pointer
char* s1 = "abc";
fun(s1);
printf("%s", s1); // => kbc

1.3 C strlen and char* and char s[] problem.

  • The length of string is trick.

    char a[20]="ab";
    char b[20]={'a', 'b','\0'};
    char c[]={'a', 'b','\0'};
    char d[]={'a', 'b'};  // ERROR: can be any number
    printf("Length of string a = %ld \n",strlen(a));
    printf("Length of string b = %ld \n",strlen(b));
    printf("Length of string c = %ld \n",strlen(c));
    printf("Length of string d = %ld \n",strlen(d));
    

1.4 C strlen does not include '\0'

char s[] = "abc";
strlen(s); // => 3

1.5 C strncpy string copy, append a char to a string

char ch = 'd';
char* src = "abc";
char* dest = (char*)malloc(sizeof(char)*(strlen(s1) + 1));
// does not copy '\0'
// strlen(src) does not count '\0'
strncpy(dest, src, strlen(src));
dest[strlen(src)] = ch;
dest[strlen(src) + 1] = '\0';

// deallocate memory
if(dest)
  free(dest);

1.6 Reference in C and C++

  • reference is like static pointer which points to memory address of variable.
    • You can change the content of memory address. E.g.

      int num = 3;
      int* pt = #
      num = 5;
      printf("num=%d, pt=%d\n", num, *pt);
      
    • Pointer(int *pt) reference(int &ref) and const reference (const int& cref)

      • The content of ref can be changed.
      • The content of cref can not be changed.
      • ref is an alias to num and the content of ref can be modified.
      • cref is an alias to num but the content of cref can not be modifed.
      int num = 3;
      int &ref = num;  // ref is an alias to num
      const int& cref = num;  // cref is an alias to num but the content of num can not be modified via cref
      

1.7 Function return by reference

  • Return a reference if a variable is not local to the function.
int num = 3;
int& test(){
  return num;
}       
test() = 5;
printf("%d", num); // num => 5

1.8 Parameter passed by reference, int n, int& n and const int& n

Passed by value to a function, it means you only have the copy of the original of variable, you can change the value of variable out side the scope of the function

int fun(int num){
    n = n + 1;
    return n;
}

Pass reference to a function, it means you have access to the read-only memory address of the variable

void fun(int& num){
  num = num + 1;
}
int num = 1;
fun(num);
printf("num=%d", num); => 2

Pass const reference to a function, you can NOT modify the content of the read-only memory address

// NOTE: Compilation error
int fun(const int& num){
     num = num + 100;
     return num;
}

1.9 Get a pointer to std::vector

class Pt{
      int x;
      int y;
  public Pt(int x, int y){
         this.x = x;
         this.y = y;
  }
}
std::vector<Pt> vect;
vect.push_back(new Pt(1, 2));
int* ptr = &vect;
  // ptr will point to vect.

1.10 Get a pointer to std::vector data

  • Get a pointer to the first address of the data. Test Example
class Pt{
public:
    int x;
    int y;
public:
    Pt(){}
    Pt(int x_, int y_){
        x = x_;
        y = y_;
    }
};
std::vector<Pt> vect;
Pt p1;
p1.x = 1;
p1.y = 2;
Pt p2;
p2.x = 3;
p2.y = 4;

vect.push_back(p1);
vect.push_back(p2);
int expected[] = {
    1, 2, 3, 4
};
int* ptrToData = (int*) vect.data();
REQUIRE(compareArray(ptrToData, expected, 4) == true);

1.11 Convert String to digit.

#include 
#include 

// convert string to digits
//
// gcc -o try1 try1.c   on MacOSX
// Fri Jul 13 00:14:39 PDT 2018
//  
// 
int main () {
  char str[30] = "2030300 This 444 is test";
  char *ptr;
  long ret;

  ret = strtol(str, &ptr, 10);
  printf("The number(unsigned long integer) is %ld\n", ret);
  printf("String part is [%s]", ptr);

  return(0);
}

1.12 Initialize Array in C and C++

//C and C++ initialize array
int array[] = {1, 2, 3};    

1.13 Pointer points to array

// now pointer pt points to array
int* pt = array; 

1.14 C++ print out array

// print out the array
for(int i=0; i<3; i++){
    cout<<"["<<i<<"]="<<pt[i]<<endl;
}

1.15 Print out array with pointer.

// print out using the pointer
for(int i=0; i<3; i++){
    cout<<"["<<i<<"]="<<*(pt+i)<<endl;
}

1.16 Allocate memory in C dynamically.

// dynamically allocate memory in C
int size = 3;
int* pt1 = (int*)malloc(sizeof(int)*size);

// dellocate memory in C
free(pt1);

1.17 Allocate memory in C++/Cpp dynamically.

// dynamically allocate memory in C++
int *pt2 = new int[3];

// dellocate memory in C++
delete pt2;

1.18 Allocate two dimensions array in C

// allocate two dimension array in C
int col = 4;
int row = 3;
int** ppt;

// this is trick part
ppt = (int**)malloc(sizeof(int*)*col);
for(int j=0; j<col; j++){
    ppt[j] = (int*)malloc(sizeof(int)*row);
}
int c = 0;
for(int i=0; i < col; i++){
    for(int j=0; j < row; j++){
    ppt[i][j] = c++;
    }
}

  // Deallocate memory 2 dimensions.
  for(int j=0; j < col; j++){
  free(ppt[j]);
  }

Sorry, your browser does not support SVG.

1.19 Inheritence

  • Polygon, Rectangle and Triangle examples.
 class Polygon{
 protected:
 int m;
 int n;
 public:
 Polygon(){
     m = 0;
     n = 0;
 }
 Polygon(int m, int n){
     this -> m = m;
     this -> n = n;
 }
 };

 class Rectangle : public Polygon{
 public:
 Rectangle(){}
 Rectangle(int m, int n){
     Polygon(m, n);
 }
 public:
 double area(){
     return m*n;
 }
 };

 class Triangle : public Polygon{
 public:
 Triangle(){}
 Triangle(int m, int n){
     Polygon(m, n);
 }
 public:
 double area(){
     return m*n/2;
 }
 };


Rectangle* pRect = new Rectangle(1, 2);
cout<<"Rectangle Area"<<pRect->area();
Triangle* pTri = new Triangle(1, 2);
cout<<"Triangle Area"<<pTri->area();

1.20 Virtual Function, Pure Virtual.

  • Virtual function and non virtual function in C++

     class Base{
        public:
        virtual void fun() = 0;
     };
    
    class MyDerived : public virtual Base{
        public:
        virtual void fun(){
          cout<<"MyDerived =>"<<endl;
        }
    };
    
    MyDerived* derivedPt = new MyDerived();
    derivedPt -> fun();
    
    Base* basePt = (MyDerived*)(derivedPt);              // OK
    Base* basePt1 = dynamic_cast<MyDerived*>(derivedPt);  // OK
    basePt -> fun();
    
    delete(derivedPt);
    
    

cpp_virtual_function.png

1.21 Smart pointer: unique pointer, shared pointer and weak pointer

  • What is smart pointer? Smart Pointer
    • Smart pointer is all about ownership, who owns the object
      • Unique pointer only allows ONE ownership
      • Shared pointer allow more than one ownership.
      • Weak pointer has no ownership.
    • Smart pointer can automatically deallocate memory.
  • What is unique pointer?
    • As the name implies, make sure exactly only one copy of object exists.
    • Unique pointer can not be copied. \( \Rightarrow \) no use_count() function.
    • You can transfer the pointer to other unique pointer using std::move(), then the origin unique pointer will be deleted.
  • What is shared pointer? sharedptr
    • Shared pointer is based on reference counting and can be used to store and pass reference beyond the current scope.

      class MyClass{
          public:
               MyClass(){}
          public:
               shared_pt<int> fun(){
                   shared_pt<int> pt(new int(9));
                   cout<<"fun pt.use_count()=" <<pt.use_count()<<endl; // pt.use_count() == 1
                   return pt;
               }
      }
      
          // main
          MyClass* cpt = new MyClass();
          shared_pt<int> pt1 = cpt -> fun();
          cout<<"main pt1.use_count()=" << pt1.use_count()<<endl;  // pt1.use_count() == 1
      
      
  • What is weak pointer?

1.22 C++ Template

  • Simple template example.

      template<typename T>
      T fun(T a, T b){
    return a + b;
      }
      template<class T>
      T fun(T a, T b){
        return a + b;
      }
    
  • Template class and typename

     template<class T>
     class MyClass{
    public T add(T a, T b){
           return a + b;
    }
     }
    
  • Template default type like function has default parameter.

      // function default parameter
      int sum(int a, int b = 0){
    return b == 0 ? a : a + b;
      }
      // template default type
      template<typename U, typename T = int>
      class my_class{
      U x;
      T y;
      };
    
  • The difference between struct and union

    • struct allocates memeory for each member variables
    • union share all the memory for all the member variables. (Allocate the maximum memory for all the member variables)
      union UType{
    int x;
    int y;
      };
      UType t;
      t.x = 100;
      printf("x=%d, y=%d\n", t.x, t.y);  // x = 100, y = 100
    
  • The difference between struct and class

    • The default access modifier in struct is public.
    • The default access modifier in class is private.
      struct my_struct{
    x;
      }
      my_struct t1;
      std::cout<<t1.x<<endl;
    
      struct my_class{
        public:
    x;
      }
      my_class c1;
      std::cout<<c1.x<<endl;
    

1.22.1 Cpp std::pair, C++ std::pair

using namespace std;

std::pair<int, int> p1; 
cout<<"first="<<p1.first<<" second="<<p1.second<<endl;
std::pair<int, int> p2(1, 2); 
cout<<"first="<<p2.first<<" second="<<p2.second<<endl;

vector<std::pair<int, int>> vp;
for(int i=0; i<4; i++){
std::pair<int, int> pp(i, i*i);
vp.push_back(pp);
}
for(int i=0; i<vp.size(); i++){
cout<<vp[i].first<<" "<<vp[i].second<<endl;
}

1.23 Cpp function return a temporary object causes issue. Function composition is deadly in C++.

using namespace std;
string fun(){
  string str("temporary object");
  return str;
}

string s1 = fun();
cout<<s1.c_str()<<endl;  // OK

const char* pt = fun().c_str();
cout<<pt<<endl;          // Cause error because fun() return a temporary object

1.24 RValue and LValue in C++

  • lvalue and rvalue
  • rvalue has no memory address, it is temporary variable in the code.

    int n = 3;        // 3 is rvalue
    int m = 3 + 4;    // 3 + 4 is rvalue
    
    int fun(int n){
      return n + 1;
    }
    
    int t = fun(3);  // the return value of fun(3) is temporary variable
    
  • lvalue has memory address. You can access the address with & operator.

    int n = 3;    // n is lvalue
    int m = n;    // m, n is lvalue
    

1.25 Two ampersands or double ampersands && operator, move semantic

Author: aaa

Created: 2023-02-22 Wed 13:21

Validate