Home

C++ notes - basic

Written by ZHANG Rushan

0. Cautions

    01. be careful with the 'single quotes' and "double quotes" for char and string;
    02. do not forget "break" for switch
    03. be careful with the "==" in logics
    04. be careful not mistakenly use for(;;); and while();
    05. expressions in for loop should be seperated with ; not , i.e.for(;;)
    06. be careful with integer devision
    07. check ;
    08. forgetting to define variable before use
    09. forgetting to return
    10. forgetting to initialize
    11. char[length + 1] for string (for \0)
    12. new int*[] is a pointer int**, not int*
    13. deleting dynamic array with delete [] x;
    14. the index of the last element of x[N] is x[N-1]
    15. you cannot pass a const array to another function requiring non-const array
    16. assigning a string to a char array directly: x = "abc" is not allowed, strcpy(a, b) is needed
    17. expected ';' after "struct" definition and "enum" definition
    18. be careful not to pass by reference a nullptr
    19. the "*" and "&" goes with the variable, not the data type!
    20. can only assign ptr to const object to ptr to const object
    21. use const reference variable for "struct" as default
    22. "struct" will not help you initialize automatically
    23. always think about recursion
    24. forget object_name. for "struct" and "class"
    25. forget +1 in recursive count
    26. recursive/iterative: try to run the first few cases in heart!
    27. add "const" whenever possible

00. Good programming practice

    1. always use extra "()" when in doubt, or to improve readability
    2. "writing loops"
        "when writing the loop, consider:"
            initial situation
            update for the next loop
            exit the loop at the right point
        "try to verify:"
            The first iteration
            The second iteration
            The last iteration
    3.use const to replace numbers
        "convension: set const value name with all upper cases"
            "more readable"
            "more easy to update"
            "type-checked during compilation"
        1. const int PI = 3.14159
            or
        2. #define PI 3.14159
            // define is only substituting PI with 3.14159, and it does not have a type

01. datatype

    //datatype: how you store data
    1."integer, character and character strings"
        int     //integers
        char    //characters
            'single quotes'
            //text, letters
            special characters: 
                '\t'    //tab
                '\n'    //newling
                '\b'    //backspace
                '\n'    //null character
        string  //a sequence of basic char
            "double quotes"
    2."float"
        float       single-precision decimal numbers
        double      double-precision decimal numbers
        precision
            floating-point          sign-bit + mantissa + exponent
            exponent+   larger real number
            mantissa+   higher precision
        IEEE 754 floating-point standard:
            1 sign-bit + 23 (52) mantissa + 8 (11) exponent

        all float literals will be seen as double
        to specify a float, you need to add an "f"
        e.g. 1.23f
    3."boolean"
        every number except 0 is true
        0 is false
        true = 1
        false = 0
    4."size of datatypes"
        on 32-bit machine:
        type        size        range
        bool        1           {true, false};
        char        1           [-128, 127];
        short       2           [-32768, 32767];
        int         4           [-2147483648, 2147483647];
        long        4           [-2147483648, 2147483647];
        float       4
        double      8
        // you cannot compare two float values with ==
        // the proper way is to do abs(x - y) < epsilon
        unsigned    "not negative, get double maximum"
    5."coercion"
        the automatic conversion of the data type
            e.g.
            float + int -> float + float
                // float has more information
            char - char -> int - int
                // integral promotion
                // it is converted to int, then converted back to char
            // rules:
                if either is long double, then it will be converted to long double
                if either is double, then it will be converted to double
                if either is float, then it will be converted to double
                else it will run integral promotion (for the char case)
    6."manual type casting"
        "to change a variable to another type: manual type casting "
            static_cast<data-type> (variable/value)
            e.g.
                int k = 5;
                float x = static_cast<double>(k);
    7."enum"
        internally: integers
        act like: const int
        e.g.
            enum shapes { TEXT, LINE, RECT, CIRCLE };
                // 0, 1, 2, 3
            enum bloodtype { A, B, AB = 10, O }; 
                // 0, 1, 10, 11

02. identifiers - name of functions, variables and constant

    1."usable characters"
        numbers
            //The first character cannot be a digit (0–9).
        letters (lowercase or uppercase)
            //C++ is case sensitive
        underscore _
    2."reserver words"
        you do not really have to memorise
        when you use a reserver word, you will get an error right away
    3."ways_to_separate_words"
        capitalize  "TwoSeparatedWords"
        underscore  "two_separated_words"

03. variables

    1."principle"
        named memory location that we can write to, retrieve from, and manipulate
    2."terminologies"
        "definition"
            allocate memory space for a variable
        "declaration"
            declare that a variable exist (often in sepearted compilations)
        "initialization"
            assign the initial value for a variable
        
        when you "define" a variable:
            a space is allocated to this variable
        when you "initialize" a variable:
            a space is allocated and the value is set
        when you pass by value:
            a new space is allocated, with the same value as the previous one
        when you pass by reference:
            a new name is created for the same previous memory space
    
        "illegal without initialization"
            const variables
            reference variable
            const pointer
        "pointer to const object okay!"
        "default initialized to 0"
            global variable
            "otherwise, without initialization, garbage data!"
    
    3."lvalue and rvalue"
        lvalue: the location of the variable
            read and write
        rvalue: value in storage
            read only
            e.g.
                (x + 6) = 3;
                    //incorrect
                    LHS: the value of expression (x + 6) //rvalue
                cout << ++++++x;
                    //correct, print out x + 3
                    returns a "lvalue"
                    "similar to rbr"
                cout << x++++++;
                    //incorrect
                    returns an "rvalue"
                    "similar to rbv"
        reference operation:
            &x
            //the location of x
    4."constants"
        literal constants
            char constants:  'a', '5', '\n'
            string constants:  "hello world"
            int constants:  123, 456, -89
            double constants:  123.456, -2.90E+11
                // all float literals will be seen as double
        symbolic constants
            must be initialized when definition
            cannot be changed
            in most cases, no memory is allocated for constants

04. operators

    1."arithmetic"
            Assignment
        +	
            Addition
        -	
            Subtraction
        *	
            Multiplication
        /	
            Division
        %	
            Modulus
            "strictly speaking, only defined on positive integers"
                "a % b = a - (a / b) * b"
                "If it is negative, it may be different on different compilers"
                "Only used on integers"
            "int and float"
                "Arithmetic expressions involving only integers use integerarithmetic"
                "Arithmetic expressions involving only floating-point numbersuse floating-point arithmetic"
                "be careful with integer devision!"
    2."increment operators"
        x++ "post-increment"
        ++x "pre-increment"
            adding 1 to x
        x--
        --x
            subtracting 1 from x
        "difference between putting it before or putting it after"
            "++x returns the lvalue of the incremented variable"
            "x++ returns the rvalue of the original variable"
            e.g.
            int x = 3, y;
            y = x++;   
            //you get x = 4 and y = 3
            //this is because adding 1 to x happens after assigning x to y

            int x = 3, y;
            y = ++x;
            //you get x = 4 and y = 4
            //this is because adding 1 to x happens before assigning x to y
    
            e.g.
            int x = 3;
            cout << x++;
            //you get 3
    
            int x = 3;
            cout << ++x;
            //you get 4
    3."shorthand assignment"
        +=
        -=
        *=
        /=
        %=
        ...
    4."relation"
        ==
            Equal to
        !=
            Not equal to
        >
        <
        >=
        <=
        "the value of =, e.g. x = y, will be the final value of x"
        "therefore, statements like x = 3 will always be true, since its value is 3"
    5."logical"
        &&
            And
        ||
            Or
        !
            Negation
        e.g.
            !(a > 10)
            a <= 10
    	"0 is regarded as false"
    6."Precedence"
        //left-right
            .
            ->
            a++
            a--
        //right-left
            *a //dereferencing operator
            ! //logical not
            -a   //minus
            ++a
            --a
        //left-right
            *
            /
            %
        //left-right
            +
            -
        //left-right
            > < >= <=
        //left-right
            == !=
        //left-right
            &&  //and
        //left-right
            ||  //or
        //right-left
            =   //assignment

05. expression and statement

    1."statement"
        statement does not have a value
        statement is an expression that ends with a semicolumn ";"
    2."expression"
        expression has a value
    3."return values of an expression"
        x = y
            the final value of x
        x == y
            the true value of the statement
        

06. choices

    1."if-else"
        if (/* condition */)
        {
            /* code */
        }
        else if (/* condition */)
        {
            /* code */
        }
        else
        {
            /* code */
        }
        //if there is only one line, then the braces "{}" are not necessary
        "else always belongs to the nearest if"

    2."ternary choice"
        e.g.
        grade = (percentile >= 85) ? 'A'
        : ((percentile >= 85) ? 'B'
            : ((percentile >= 85) ? 'C'
                : ((percentile >= 85) ? 'D': 'F'
                )
            )
        );
    
        or
    
        grade = (percentile >= 85) ? 'A'
                                   : ((percentile >= 85) ? 'B'
                                                         : ((percentile >= 85) ? 'C'
                                                                               : ((percentile >= 85) ? 'D' : 'F')));
    
        or
        grade = (percentile >= 85) ? 'A': (percentile >= 85) ? 'B': 
                (percentile >= 85) ? 'C': (percentile >= 85) ? 'D' : 'F';
    3."switch"
        switch (expression)
        {
        case /* constant-expression */:
            /* code */
            break;
        case /* constant-expression */:
        case /* constant-expression */:
            /* code */    
            break;
        
        default:
            break;
        }
        "case is the entry point"
        "break is the exit point"
        "if no break, it will execute till the end of the switch"

07. iterations

    1."while loop"
        while (/* condition */)
        {
            /* code */  //this can be empty
        }

        "if you do this:"
            while (x > 0);
            {
                /* code */  //this can be empty
            }
            // if x > 0, it will get stuck
    
        "you can ask for input using:"
            while (cin >> x)
            {
                /* code */
            }
    
        "when writing the loop, consider:"
            initial situation
            update for the next loop
            exit the loop at the right point
        "try to verify:"
            The first iteration
            The second iteration
            The last iteration
    2."do-while loop"
        do
        {
            /* code */
        } while (/* condition */);
    3."difference:"
        while will check the condition before entering the loop
        do-while will ensure the loop will be executed at least once
    4."for l```op"
        ## for  initialization"; "exit condition"; "change of loop variable
        ```c++
            /* code */
        }
        // the "initialization" will be excecuted once before entering the loop
        sequence:
            1."initialization"
            2."exit condition"
            3./* code */
            4."change of loop variable"
            5.back to 2.
    
        the "initialization"; "exit condition"; "change of loop variable" can be empty
            but the semi column ";" should stay
    
        "you can even have a for loop in one line:"
            for (int j = 1; j <= number; factorial *= j++);
    5.
        break;      jump out of loop
        continue;   skip one iteration

08. function

    1."parameter"
        <formal-parameter-list>
            "in function definition"
            a list of variable "declarations" separated by commas
        <actual-parameter-list>
            "in function call"
            a list of "objects" passed to the called function
    2."principles"
        when you call a function:
            1. the control flow goes from caller function to the callee function
            2. the parameters are passed to the function
        when to return back to the caller:
            1. when it goes to the end of function
            2. or when there is a return
                // only one value can be returned
        "to return more than one thing"
            1. "to return a class"
            2. "use array"
            3. "use Pass By Reference"
    3."passing variables in functions"
        if no variable is needed, write "void", or nothing
        for return type, if nothing is returned, write "void"
        if you want to exit the whole program, write exit()
            to return something to the system, write exit(/* the thing you want to return */)
        "PBV: pass by value"
            only the value is allocated to the function variable
        "PBR: pass by reference"
            reference variable: a variable with a "&" symble
                another name of the previous variable
            it can refer to an array element
            "must be initialized when definition"
            "cannot be rebound"
            more efficient for larger variable passing
            const int &x "read only PBR"
                callee function cannot modify the variable
            "syntex errors involving PBR"
                const int &x
                    const variable          √
                    a specific number       √
                    changeable variable     √
                int &x
                    const variable          ×
                    a specific number       ×
                    changeable variable     √
        "RBV: return by value"
            int function_name()
        "RBR: return by reference"
            int& function_name()
            // the access right is also passed
            it is not allowed to do this:
                int& find_larger(const int &x, const int &y);
            should be:
                const int& find_larger(const int &x, const int &y);
        "the use of global variable is not encouraged"
    4."function prototype or interface"
        "return type"
        "name"
        "signature"
            the input variables and its type
    5."declaration and definition"
        "declaration"
            "writing down the prototype"
            "you can only call the functions that is declared before the caller function"
        "definition"
            "writing down the prototype" and "the body"
            "can be defined only once, but declared for many times"
        "forward declaration"
            you can declare all the functions at the very top of your code,
                so that you do not need to check the interference between the functions
            "it is also possible to declare inside the caller function"
    6."overloading"
        only the signature will be considered
            i.e. "input variables numbers and type"
        it will compare all the functions already declared, and determine which one to call
            i.e. "the one that fits most will be called"
            a. exact match
            b. match after type promotion
                char/bool/short -> int -> long
                float -> double
            c. match after standard type conversion
                integral <-> floating
    7."default arguments"
        "all at the end of the formal parameter list"
        "can be in function declaration or definition, but not both"
        e.g. void func(int, float&, char = 'M', bool = true);

09. array

    1."general rules"
        "should be of the same type"
        cannot be reference variable
        can be pointers
        the size of array must be set with a constant value
            e.g. // you cannot do this, but some compiler allow this:
                int n = 3;
                double x[n];
            // even this is not allowed:
                int a; const int b;
                cin >> a;
                b = a;
                double x[b];
        range:
            the size of array cannot be set negative
            you cannot use negative index
            you cannot use index out of [0, N-1]
                // even though this may work, this is just your luck!
        "the index of the last element of x[N] is x[N-1]"
        array definition
            int b[5] = {1, 2};      //{1, 2, 0, 0, 0}
            int c[5] = {};          //{0, 0, 0, 0, 0}
            int d[] = {1, 2, 3};    //{1, 2, 3}
            int c[5];               //5 garbage data
            int e[5] = c;           not allowed
            "once defined, the above syntaxes are no longer allowed:"
                e = {1, 2, 3};          not allowed
                f = e;                  not allowed
            "you cannot define an array of reference variables:"
                int &e[3] = {x, y, z};  not allowed
            "you can define a constant array:"
                const int x[5] = {1, 2, 3, 4, 5}
    2."how does array work?"
        all elements are located consecutively
        the location of the array is calculated
    3."when you pass an array to a function, it is always done by pass by pointer"
        to avoid an accident change:
        use constant array:
            e.g.
            int function_name(const int x[])
        "you cannot pass a const array to another function requiring non-const array"
    4."high-dimensional array"
        "to improve readability:"
            int x[5][4] = { 
                {2, 3, 4, 1},
                {2, 2, 1, 3},
                {2, 4, 1, 3},
                {6, 2, 3, 1},
                {2, 1, 4, 3}};
        "when passing a high-dimensional array to a function, the number of column is necessary"
            int function_name(int x[][4])

10. c string

    1."initialization"
        char x[] = "string";    //allowed
        after initialization
            "you have to use strcpy to copy a string to another string"
        when you assign a string to a char array
            e.g. char x[8] = "abc";
            the rest of the array will be initialized as '\0'
            i.e. x[8] = {'a', 'b', 'c', '\0', '\0', '\0', '\0', '\0'};
    2."principles"
        for a string of length N, there will be another char '\0' as the (N + 1)th element
            e.g.
            "string" == {'s','t','r','i','n','g','\0'};
        "Do not forget to prepare an additional space for the '\0'"
            if the '\0' is forgoten, it will keep printing out garbage data until it meets '\0'
        "you are not allowed to print out any array except a "char" array"
        if you have an array of strings
            it will be a 2-D array
            e.g. char x[3][6] = {
                "str_1",
                "str_2",
                "str_3"
            }
            you are allowed to write:
                cout << x[2];
    3."getting input"
        if you get input with 
            char x[20]; cin >> x;
            "it will keep getting input until it reaches a white space"
        to get a sentence with white spaces:
            cin.getline(char_array, max_number_of_char, terminator);
                "the terminator will be removed"
            e.g. cin.getline(char_array, 8, '$');
                this will get input and store it into str_variable
                it will stop geting input after pressing "enter" if:
                    your input exceeds "8 - 1 = 7" or your input contains $
                else: it will keep getting input even if you pressed "enter"
            if you do not specify terminator, it will be automatically set to "enter"
            e.g. cin.getline(char_array, 8);

11. recursive algorithm

    think recursively
    write recursive function
        1. validation
        2. base cases (e.g. 0)
        3. recursive cases
    you may call more than one recursive functions
    "draw backs compared to iterated solution (e.g. for loop, while loop)"
        1. more memory required
        2. repeat calculation

12. scope

    1."global scope"
        "file scope"
            outside functions
        "global variables"
            "when defined, automatically initialized to 0"
    2."local scope"
        "function scope"
            inside functions
        "block scope"
            inside structures
                e.g.
                    for
                    while
                    if
    3."general rule"
        "all variable exists only after it is defined,"
        "and disappears when it reaches the end of its scope"
        "all functions also only exists (can be called) after it is declared"
        the usage of global variable is not recommended
        we can have two identifiers of the different scope
            "the inner most is to be called"

13. separate compilation

    1."basic rules"
        include libraries again
        define global const variables again
            // in both main.cpp and other_function.cpp
            e.g.
            const int MAX_CALLS = 40;
        declare global variables with extern // not define
            // this should be defined in main.cpp
            // in other_function.cpp
            e.g.
            extern bool debug;
        declare external functions with extern // not define
            // in both main.cpp and other_function.cpp
            e.g.
            extern bool odd(int);
    2."header file"
        basically putting the codes into where it used to be
        e.g.
        my_include.h
        // in both main.cpp and other_function.cpp
            // system or user defined header files
            #include <iostream>
            using namespace std;
            // constants definitions
            const int ONE = 1;
            // external function declaration
            extern int add(int x);
        external_variables_declaration.h
        // in other_function.cpp
            extern bool debug;
        external_variables_definition.h
        // in main.cpp
    3."basic model"
        my_include.h
        // in both main.cpp and other_function.cpp
            // user defined datatype
            // library (other headerfiles, like iostream)
            // global constant definitions
            // external function definitions
        external_variable_declaration.h
        // in other_function.cpp
            // global variable declaration
        external_variable_definition.h
        // in main.cpp
            // global variable definition

14. structure

    "defining a new datatype"
        struct Point
        {
            double x;
            double y;
        };
    "defining a struct variable"
        Point a = { 24.5, 123.0 };  // can no longer be used after definition
        Point b;
    "accessing a struct content"
        p.x
        p.y
        // <struct_variable>.<member_variable>
    "memberwise copy"
        // you are allowed to copy two struct directly
        Point a, b;
        a.x = 3; a.y = 4;
        b = a;
        // b.x = 3; b.y = 4;
        "even if there is an array in the struct, this is also allowed"
        "this copy is a bit-to-bit copy"
    "assignment"
        // Separate memberwise assignments 
            b.x = 24.5;
            b.y = 123.0;
            "for a relatively big struct, you may write a function to do that"
        or
        // memberwise copy
            b = a;
    "initialization"
        e.g.
        struct Date
        {
            unsigned int year;
            unsigned int month;
            unsigned int day;
        };
        enum Dept { CSE, ECE, MATH };
        struct record
        {
            char name[32];
            unsigned int& id;
            char gender;
            Dept dept;
            Date entry;
        };
        Student a = {"Adam", 2718, 'M', CSE, {2017, 9, 1}}
                 // {char array, int, char, enum, struct}
                 "there is a struct within a struct"
    "function passing"
        // it is wise to pass a struct by reference
        // to avoid accident modification, set it to const 
    "always ask youself: what is the data type? what is the rule for this type?"
    "we can have an array of structures"

15. pointer

    1."basic syntaxes"
        "you need to specify the type of the pointer you are pointing to"
        e.g.
        "int x" // = 20
            0x7ffeeb6b9836 // the address of x
            0x7ffeeb6b9837
            0x7ffeeb6b9838
            0x7ffeeb6b9839
            "definition: saving the address of x"
                int *c = &x;
                // the type is strict
            "reading the content of that address"
            "dereferencing operation" jump back!
                *c; // 20
                this is a lvalue, which can be edited

            "reading the address"
                c;  // 0x7ffeeb6b9836
    2."size of pointer"
        "the size of address"
            // and therefore all pointers have the same size
            // exact size is system dependent
    3."pointers can point to:"
        basic types: char short int long float double etc;
        user defined: struct class etc;
        another pointer;
        function;
    4."const"
        int x = 5, y = 10;
        "const pointer""life long merrage"
        int* const xcp = &x;    // must initialize when definition
            // during the whole execution, xcp is binded to x;
            cout << *xcp;       // allowed
            *xcp = 6            // allowed
            // xcp = &y;        wrong!!
        "pointer to const object"
        const int* xp_c = &x;   // may not initialize when definition
            // xp_c can point to other variables, but cannot change the value of the variables
            xp_c = &y;           // allowed
            // *xp_c = 5         wrong!
            y = 5;              // allowed
        "const pointer to const object"
        const int* const xcp_c = &x; // must do initialization when defining
            // xcp_c = &y;        wrong!
            // *xcp_c = 5         wrong!
            x = 6               // allowed
            *xcp = 7            // allowed
        small tip:
            read from right to left
            int* "pointer" const "constant" xcp = &x;
            const "to constant object" int* "pointer" xp_c = &x;
            const "to constant object" int* "pointer" const "constant" xcp_c = &x;
    5."pointer to struct"
        struct Point
        {
            double x;
            double y;
        };
        Point a;    // a contains garbage data
        Point* ap = &a;
        "the dereferencing way:"
            (*ap).x = 3.5;
            (*ap).y = 9.7;
        "the -> operator:"
            ap -> x = 3.5;
            ap -> y = 9.7;
        // ap -> x is the same as (*ap).x
        // always ask yourself: what is the data type?
    6."special notice"
        a."on passing by pointer"
            if you have a function header with pointer variable,
                you have to send the address to that function
                e.g.
                void print(const int* x)
                {
                    cout << *x;
                }
                // in main:
                print(&x); // sending the address
        b."on array"
            we can create an array of pointers, but not an array of references

16. dynamic memory allocation

    1."static object and dynamic object"
        "static object" (float int ...)
            usually allocated sequently (inverse) in the stack
            the allocation and deallocation is done automatically
                have a fixed size at definition;
                if out of scope: deallocated
        "dynamic object"
            usually allocated sequently (positive) in the heap
            memory allocation and deallocation at run time
                always write new, delete in a pair
            "it will not be deallocated automatically, so it is not restricted by the scope"
            
    2."operator new"
        "find from heap an amount of memory equal to the size of the datatype and return the address"
        int* ip = new int;
    3."operator delete"
        "deallocate the memory space the pointer is pointing to"
        delete ip;
        // now ip is a dangling pointer
        ip = nullptr;   // if a pointer is not pointing to anyone, just set it to null
        "*ip now is an unexpected behaviour"
    4."common errors"
        dangling pointer:
            pointing to a static object which is already out of scope
            (or anything that is deallocated)
        memory leak:
            lose access of some memory address
            a dynamically allocated memory no longer needed is not released
    5."pointer as an array"
    
        a dynamic array
            int *x = new int[1000];
            "to delete a dynamic array"
                delete [] array_name;
                "don't forget the [] for arrays (when creating and deleting)"
    pbr = pbv + pointer

17. linked list

    1."array vs linked list"
        array
            advantage
                efficient, head to tell, works well with loops and recursion
            disadvantage
                size of the array is determined
        linked list
            advantage
                dynamic, it grows and shrinks to any size as you want
            disadvantage
                requires additional memory for the linking "pointers"
                not so "efficient"
    2."typical linked lists"
        head -> value,pointer_to_next -> value,pointer_to_next -> ... -> value,nullptr //tail
        e.g.
            struct ll_node
            {
                int data;          // value
                ll_node* next;  // pointer_to_next
            };
        the "pointer_to_next" for the last node should be nullptr
    3."walking ptr"
        e.g.
            for (ll_node* p = first_p; p != nullptr; p = p->next)
                cout << p->data;
    4."basic operations"
        0.struct
            struct ll_node
            {
                char data;
                int* next = new ll_node;
            };
        1.create
        2.search
            use travelsal
            for (ll_node* p = head; p != nullptr; p = p->next)
            {
                /* code */
            }
            
        3.delete
            "for delete, pass by reference (node*& head) is needed"
            "because you need to set the pointer variable itself to nullptr"
            "duplicate the pointer first"
        4.insert
    5."cautions"
        always think: who remembers the address of the next node?
        always think: whether a sequence of modifying will lose track of the next node
            always copy the next pointer first before you modify the last pointer
            always keep the address of the head node
        "special case"
            1. at first, at last
            2. empty    "when it is empty, be careful with head->next"
            3. only one node
        when using pass pointer by reference, always ask: what does it reference to?

18. array as an pointer

    1."pointer arithmetic"
        pointer_variable + 1;
            "pointer_variable_address + 1 * sizeof(type of the variable)"
        an array name has two role:
            1.name of array
            2.const pointer pointing to the first element
        cout << &array_name;    //grab addr of the array x, x is the name of the array (role 1)
        cout << array_name;     //print the const pointer, which is the address of the first element
        cout << &array_name[0]; //access the first element, print out its address
            "both means the address of the first element"
        When getting access to the last element of an array, remember to use start+length-1
        
        if you write
            const char* s1 = "creative";
                This is okay.
            char* s1 = "creative";
                Not right.
    2."dynamic array"
        "to create a dynamic array"
            int *x = new int[<integer expression>]; // can have a length defined by variable
        "to delete a dynamic array"
            delete [] array_name;
        "don't forget the [] for arrays (when creating and deleting)"
    3."multi-dimensional array"
        To create a 2D array:
            1. Allocate a 1D array of M int*
            2. Allocate a 1D array for each of the element
            e.g.
            // to create
            int** x = new int* [num_rows];
            for (int i = 0; i < num_rows; i++)
            {
                x[i] = new int[num_lines];
            }
            // to get access
            *(*(x + j) + k);
            or
            x[j][k];
            // to delete
            for (int i = 0; i < num_rows; i++)
            {
                delete [] x[i];
            }
            delete [] x;  
        "When an array is dereferenced, the last element is always deleted first"

19. class

    class = data + operations + access control
    member functions
        constructor "create"    // done when defining a class object
                                // either by build-in constructor or user-defined constructor
        accessor    "read"      // by public functions
        mutator     "write"     // by public functions
        destructor  "delete"
    object: the data; //instantiation //?

    e.g.
        class student_record
        {
            private:    // access control
            // internal usage
                char gender;
                unsigned int id;
                char name[30];
            public:     // access control
                // accessor
                char get_gender() const { return gender; }    
                "'const' is reminding the compiler: double check: do not change data number!"
                unsigned int get_id() const { return id; }
                void print() const
                    { cout << name << endl << id << endl << gender << endl; }
                
                // mutator
                void set(const char my_name[], unsigned int my_id, char my_gender)
                    { strcpy(name, my_name); gender = my_gender; id = my_id;}
                void copy(const student_record& r) { set(r.name, r.id, r.gender); } 
                    // the data is accessible by their own member functions
        };
        // calling member function:
        student_record amy;
        amy.set("Amy", 20711102, 'F');
        
    "variables in private can only be accessed through functions in public"
    "this is to protect the data stored in private area"
        "information hiding and protection"
            stop not permitted reading and writing
            protect data from improper modification
    
    "you can just declare functions in class definition"
        "and place definition in other places"
        // when defining member functions outside class:
        student_record::set(const char my_name[], unsigned int my_id, char my_gender)
        {
            ...
        }
        "the :: is scope operator, restricting the scope of the function"
    
    "user-defined constructor"
        class_name::class_name()
            {...}
        // class_name:: not needed if defined in class definition
        "we can use function overload to define default constructor and explicit constructor"
            e.g.
                temperature::temperature() 
                    { degree = 0.0; }
                temperature::temperature(double d, char s) 
                    { set(d, s); }
                // to call explicit constructor:
                temperature y(10, 'K');
    "user-defined destructor"
        class_name::~class_name()
            { delete ...; ...}
        "we can have at most define one destructor"
        "usually used when you use dynamic memory"
    "destructor and constructor both do not need data type"
    
    constructor function and the destructor can only be called automatically;

20. ADT

    1."ADT"
        abstract data type
    2."stack"
        "LIFO" last in first out
        top: getting the value of the top
        push: adding a new item
        pop: removing from top
    3."queue"
        "FIFO" first in first out
        front: getting the value of the front
        enqueue: add to the back
        dequeue: remove from the front