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
- 1.3. C strlen and char* and char s[] problem.
- 1.4. C strlen does not include '\0'
- 1.5. C strncpy string copy, append a char to a string
- 1.6. Reference in C and C++
- 1.7. Function return by reference
- 1.8. Parameter passed by reference, int n, int& n and const int& n
- 1.9. Get a pointer to
std::vector
- 1.10. Get a pointer to
std::vector
data - 1.11. Convert String to digit.
- 1.12. Initialize Array in C and C++
- 1.13. Pointer points to array
- 1.14. C++ print out array
- 1.15. Print out array with pointer.
- 1.16. Allocate memory in C dynamically.
- 1.17. Allocate memory in C++/Cpp dynamically.
- 1.18. Allocate two dimensions array in C
- 1.19. Inheritence
- 1.20. Virtual Function, Pure Virtual.
- 1.21. Smart pointer: unique pointer, shared pointer and weak pointer
- 1.22. C++ Template
- 1.23. Cpp function return a temporary object causes issue. Function composition is deadly in C++.
- 1.24. RValue and LValue in C++
- 1.25. Two ampersands or double ampersands && operator, move semantic
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]); }
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);
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.
- Smart pointer is all about ownership, who owns the object
- 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
- Move semantic
- What is double ampersands?
- When you should use?