Upgrade to Pro — share decks privately, control downloads, hide ads and more …

C C++ notes for C/C++ engineers

C C++ notes for C/C++ engineers

There is some common things that the software engineers should know when they use C/C++.

Avatar for Trung Huynh

Trung Huynh

July 01, 2014

More Decks by Trung Huynh

Other Decks in Programming

Transcript

  1. Distinguish value reference vs address reference • We have two

    cases: void function( int & a); void function( int a); How about void function( int * a) ?
  2. Case 1 #include <stdio.h> #include <stdlib.h> void swap(int &a, int

    &b){ int c; // c = a; // a = b; // b = c; } int main() { int a = 5; int b = 10; swap(&a, &b); printf("a: %d", a); printf("b: %d", b); } Output: a = 10 b = 5
  3. Case 2 #include <stdio.h> #include <stdlib.h> int swap2(int a, int

    b){ int c; c = a; a = b; b = c; } int main(){ int a = 5; int b = 10; swap2(a, b); printf("a: %d, b: %d\n", a, b); } Output: a = 5 b = 10
  4. Case 3 #include <stdio.h> #include <stdlib.h> int swap3(int* a, int*

    b){ int c; c = *b; *b = *a; *a = c; } int main(){ int *a = (int*) malloc(sizeof(int)); int *b = (int*) malloc(sizeof(int)); *a = 5; *b = 10; swap3(a, b); printf("a: %d", *a); printf("b: %d", *b); } Output: a = 10 b = 5
  5. • Summary 1: – Cần phải phân biệt case 1

    và case 3, cả hai đều có khả năng thay đổi giá trị tại một vùng nhớ nào đó. Nhưng nguyên lý truyền đối số vào cho hàm là hoàn toàn khác nhau. – Nên nhớ rằng case 3 chỉ có khả năng thay đổi giá trị ở vùng mà nó trỏ tới chứ hoàn toàn không thay đổi được giá trị địa chỉ các con trỏ a, b.
  6. Lập trình hướng đối tượng 1 Interface: định nghĩa một

    “vỏ bọc”. Dùng đại diện cho một số class hiện thực. Public interface people { tuổi; nghề nghiệp; void ăn(); void làm việc(); } Class doctor implement people{ private: tuổi; nghề nghiệp; public: void ăn(); void làm việc(); } Class engineer implement people{ private: tuổi; nghề nghiệp; public: void ăn(); void làm việc(); } Class main_program{ void main() { people trung = new doctor(); people lan = new engineer(); }
  7. Tính thừa kế • Đa thừa kế hoặc đơn thừa

    kế – Java đơn thừa kế – C++ đa thừa kế • Khởi tạo và hủy đối tượng trong thừa kế – Đối tượng cha luôn được tạo trước đối tượng con. – Đối tượng con luôn được hũy trước đối tượng cha. • Con có thể sử dụng tiền của cha, nhưng cha không được phép sử dụng tiền của con. – > Đối tượng con có thể sử dụng thuộc tính và hàm của con.
  8. Tính thường trú(persistence) • Trong OOP, sự tồn tại của

    một object độc lập hoàn toàn với thực thể tạo ra nó. – Object phải tồn tại khi còn ít nhất một tham khảo đến nó. – Object phải bị xóa nếu không còn tham khảo nào tới nó. Chưa hiểu tính đa xạ, tính tổng quát sẽ phải tìm hiểu sau
  9. Relationship trong OOP • Aggregation: Tính bao gộp. Tức là

    lớp A có xài hiện thực của lớp B trong định nghĩa class. Lúc đó ta nói A bao gộp B. • Quan hệ tương thích tổng quát:???(con/cha)
  10. Template trong OOP • Có hai loại template là function

    template và class template. – Function template được hiểu như một hàm mẩu, định nghĩa một hàm chung thao tác trên kiểu dử liệu tổng quát, các class tổng quát. – Class template đặt tả một loạt các class có các thuộc tính và phương thức giống nhau như chỉ khác nhau trên kiểu dử liệu/class đối tượng mà nó thao tác. – Cần phải nghiên cứu thêm về cách khái báo, và sử dụng nó khi cài đặt chương trình
  11. Cách giao tiếp giữa các đối tượng (message trong OOP)

    Các object chỉ được gọi các phương thức hay thuộc tính của object khác thông qua tham trị hoặc tham biến. Vd: tham trị: a.setNumberOfMoney(100);// a la object Tham biến: a->setNumberOfMoney(100);//a la con trỏ đến object
  12. Summary phần hướng đối tượng • Dường như còn thiếu

    một số mối quan hệ như composition... • Chưa hiểu được cách dịch của chương trình hướng đối tượng. Nên đọc lại tài liệu vê cách dịch này.
  13. C/C++ • Việc khai báo biến tập trung và rãi

    rác khi nào cần mới sài cũng cần phải cân nhắc khi tối ưu hóa code của mình. • Rỏ ràng việc khai báo biến tập trung sẽ giúp mình dễ quản lý, đồng thời trong một số trường hợp nếu khai báo biến trong vòng lặp, thì chi phí khởi tạo và hủy biến đôi khi lại lớn hơn chi phí cấp phát sẵn một vùng nhớ cho một biến mà chưa biết chắc chắn nó sẽ được sài đến. • Một điều nữa khi khai báo biến phân tán còn có một lợi điểm nữa là giúp chúng ta giới hạn tầm vực sửng dụng của biến. Khi chương trinh chạy ra khỏi {} nó sẽ bị hủy và tạo lại nếu nó khi vào {} • Summary: Khai báo biến tập trung: Ưu điểm: Dễ quản lý, tiết kiệm chi chí trong trường hợp vòng lặp Khuyết điểm: Sẽ dễ bị lãng phí vùng nhớ nếu chường trinh không đi vào nhánh có sử dụng biến Khai báo rãi rác: Ưu điểm: Tiết kiệm vùng nhớ, Giới hạn tầm vực của biến tốt. Khuyết điểm: Có thể trong một số trường hợp sẽ tốn chí phí nhiều hơn chi phí cấp phát vùng nhớ trong một số trường hợp vòng lặp. Khó quản lý biến hơn cách trên.
  14. Protected/Private • Protected: được sử dụng trong class đó, và

    các lớp con thừa kế public, hoặc các lớp friend • Private: chỉ được truy cập trong các hàm của class đó.
  15. Pointer • Con trỏ là một biến, một biến nguyên,

    chứa một số 32bit hoặc 64bit. Giá trị của nó chứa là địa chỉ của một vùng nhớ ảo. • int *a: có nghĩa khai báo một biến con trỏ, mà vùng địa chỉ nó chứa là chứa biến int. Còn biến a vẫn là một biến nguyên có độ dài 32bit/64bit. • Khai báo và khởi tạo là hai việc hòan tòan khác nhau. • Sau khi khởi tạo, vd: p=&a thì *p tương đương với biến a.
  16. Pointer • Con trỏ void *p là một con trỏ

    mà chưa quy định loại biến mà nó trỏ tới do đó có thể ép kiểu cho nó, để nó có thể trỏ tới bất kì biến nào. – char* gets(char* str); – Tôi rất tin vào cách viết chuẩn mực của Microsoft, vì thế tôi cũng khuyên các bạn code theo chuẩn mực này : + trong câu lệnh khai báo con trỏ tôi viết * gần tên con trỏ + khi viết kiểu dữ liệu tôi viết * đứng gần kiểu dữ liệu cơ bản : cụ thể ở kiểu dữ liệu trả về của hàm, ở tiêu đề và nguyên mẫu hàm + Ở câu lệnh ép kiểu thì manual theo bạn muốn, có thể viết cách ra cho thoáng code
  17. Hằng con trỏ vs con trỏ hằng • Hằng con

    trỏ:trỏ cố định vào một vùng nhớ không có khả năng trỏ vào vùng nhớ khác. Nhưng có thể thay đổi được nội dung vùng nhớ đó • Con trỏ hằng: trỏ vào một vùng nhớ cố định, con trỏ chỉ có tác dụng trỏ đến, chứ không thay đổi giá trị vùng nhớ này, giống với phương thức hằng trong OOP
  18. Hằng con trỏ vs con trỏ hằng Ex1: Const int

    *a Int const *a -> Con trỏ hằng. a là một con trỏ trỏ tới một vùng nhớ chứa một giá trị integer. Giá trị integer này không đổi theo thời gian. Nhưng con trỏ a có thể thay đổi được. Ex2: Int *const a -> Hằng con trỏ . a là một pointer chứa giá trị là một địa chỉ bộ nhớ. Và không đổi theo thời gian. Printf(“%d”, a)  luôn luôn ra một giá trị. Và không thay đổi được. Ex3: Const int *const a ->Hằng con trỏ trỏ tới một hằng integer
  19. Nguyên tắc khi gọi hàm • Khi gọi một hàm,

    thì nó sẽ tạo ra môt bản sao các tham số, copy giá trị của tham số vào đó. Chỉ ngoại lệ nếu ta khai báo hàm theo kiểu tham chiếu (&) thì nó sẽ tạo một alias đến các tham số. • \0 khác với NULL: – \0 là một hằng kí tự 0; – NULL là hằng số nguyên
  20. Nguyên tắc khi hàm trả về(1) Ex: int& sum(int &a,

    int &b) { int sum = a + b ; return &sum; // Trả về tham chiếu của biến local. Và biến local không được } -> trả về tham chiếu. Cũng chính là trả về biến sum. Lúc này sum có thể được truy suất bên ngoài tầm vực hàm. Chường trình sẽ gây ra lỗi nếu sum cấp phát cho lời gọi hàm kế tiếp.
  21. Nguyên tắc khi gọi hàm(2) Ex: int sum(int &a, int

    &b) { int sum = a + b ; return sum; // Trả về tham chiếu của biến local. Và biến local không được } -> Trả về giá trị của biến sum.
  22. Nguyên tắc khi gọi hàm(3) Ex: int* sum(int &a, int

    &b) { int sum = a + b ; return &sum; // Trả về tham chiếu của biến local. Và biến local không được } -> trả về địa chỉ của vùng nhớ sum. Biến sum sẽ được pob ra khỏi stack. Và sẽ cấp phát cho lần gọi hàm khác. Do đó sẽ có thể gây ra lỗi  demo
  23. template template <typename T> // this is the template parameter

    declaration T max(T tX, T tY) { return (tX > tY) ? tX : tY; } keyword Keyword: typename/class Typename shows that T is a type not a class int nValue = max(3, 7); // returns 7 double dValue = max(6.34, 18.523); // returns 18.523 char chValue = max('a', '6'); // returns 'a'
  24. Template • #ifndef ARRAY_H • #define ARRAY_H • • #include

    <assert.h> // for assert() • • template <typename T> • class Array • { • private: • int m_nLength; • T *m_ptData; • • public: • Array() • { • m_nLength = 0; • m_ptData = 0; • } • • Array(int nLength) • { • m_ptData= new T[nLength]; • m_nLength = nLength; • } • • ~Array() • { • delete[] m_ptData; • } • • void Erase() • { • delete[] m_ptData; • // We need to make sure we set m_pnData to 0 here, otherwise it will • // be left pointing at deallocated memory! • m_ptData= 0; • m_nLength = 0; • } • • T& operator[](int nIndex) • { • assert(nIndex >= 0 && nIndex < m_nLength); • return m_ptData[nIndex]; • } • • // The length of the array is always an integer • // It does not depend on the data type of the array • int GetLength(); // templated GetLength() function defined below • }; •
  25. PROTECTED vs PRIVATE • PROTECTED VS PRIVATE • Protected members

    is accessed from class that declare them and derived Class codes which inherit with public from Base class, also from friend class. • Private members is accessed only from class that declare them.
  26. Use or not Used namespace • Using sẽ chỉ ra

    rỏ ràng các element của name- space mà ta muốn dùng • Nếu dùng theo các using thì nói chung không lãng phí tài nguyên để khái báo các element mà ta không dùng.
  27. Inheritance A B Create C class instance Class A constructor

    Class B constructor Class C constructor Delete C class instance Class C deconstructor Class B deconstructor Class A deconstructor Out put Rule: 1. Class A object will be created first, then Class B object. 2. Class B object will be destroyed first, then class A object. #include <stdio.h> #include <stdlib.h> #include "iostream" class A { public: A(){ printf("Class A constructor \n"); } ~A(){ printf("Class A deconstructor \n"); } }; class B { public: B(){ printf("Class B constructor\n"); } ~B(){ printf("Class B deconstructor\n"); } }; class C:public A, public B { public: C(){ printf("Class C constructor\n"); } ~C(){ printf("Class C deconstructor\n"); } }; int main(){ printf("Create C class instance\n"); C *c = new C; printf("Delete C class instance \n"); delete c; } C
  28. Multiple Inheritance(constructor) A B C D A instance A instance

    C instance B instance D instance Rule: When a child instance is created, Every parent instances will be created before
  29. Multiple Inheritance(constructor) A B C D A instance A instance

    D instance C instance B instance Rule: When a child instance is created, Every parent instances will be created before
  30. Variables • There are three kinds of variables in C/C++

    – Class variable: the variable with “static” declaring ?? – Local variable: Normal variable with function level ? – Instance variable: public attribute ??
  31. GDB basic Start: gdb binaryFile b 1 -> đặt breakpoint

    tại line 1. b main -> đặt breakpoint tại hàm main run -> chạy chương trình next -> chạy hết lệnh hiện tại đang trỏ tới. step -> chạy tiếp chương trình cho đến khi tới dòng code tiếp theo. stepin-> là step instruction