Hochiminh University of Technology Computer Science and Engineering - [CO1011] Fundamentals of Function and Pointer C++ Programming Lecturer: Duc Dung Nguyen Credits: 4 Outcomes ❖ Solving problems with functions ❖ Understand recursive algorithms ❖ Declare and implement recursive functions ❖ Declare and using pointers 2 Outline ❖ Function: definition, declaration, parameters, returned value ❖ Scope of variables ❖ Storage ❖ Pointer ❖ Recursion 3 Function Function ❖ You should never write monolithic code ❖ Difficult to write correctly. ❖ Difficult to debug. ❖ Difficult to extend. ❖ Hard to maintenance ❖ Non-reusable ❖ Nonsense! 5 Function ❖ Math vs.
Computer Software ❖ A function can return no value ❖ A function can take many different types of parameters ❖ A function can set as many output as it needs Input Function Output 6 Function ❖ Definition: a group of statements that is given a name, and which can be called from some point of the program. ❖ Syntax: ❖ <type> <name>(<parameters>); ❖ <type> <name>(<parameters>) { <statements> } ❖ <type>: the value returned by the function ❖ <name>: name of function ❖ <parameters>: each parameter consists of a type followed by an identifier 7 Function ❖ <type> ❖ The function can return any type ❖ At some point, it must return a value ❖ return x; ❖ The function can return nothing (sometimes it is called procedure) ❖ No need for the return statement. ❖ return statement can be used to end the function. 8 Function ❖ Example #include <iostream> #include <math.h> int generateArrayValue(int range) { return rand() % range; } int main() { int img[12][16]; for (int i = 0; i < 12; i++) { for (int j = 0; j < 16; j++) { img[i][j] = generateArrayValue(256); } } return 0; } 9 Function ❖ Example #include <iostream> #include <math.01); } } return 0; } float add(float a, float b) { return a + b; } 10 Function ❖ Example #include <iostream> #include <math.01); } } printArray(img[2], 16);// print the third line of two dimensions array return 0; } 11 Function ❖ Name ❖ Many functions can have the same name: overloaded functions.
❖ Functions with the same name must not share the same prototype ❖ Function signature: name + parameter list ❖ Provide convenience for programmer 12 Function ❖ Example #include <iostream> #include <math.h> float add(float a, float b) { return a + b; } int add(int a, int b) { return a + b; } double add(int a, double b) { return (double)a + b; } int main() { double k = 3.2) << endl; cout << add(3, -8) << endl; cout << add(1, k) << endl; return 0; } 13 Function ❖ Parameters: there are two ways to pass parameters to a function ❖ Value: the value will be copied to local variable (parameter) of the function ❖ Reference (only in C++): the parameter is associated with passed variable ❖ User can only pass variables through a reference parameter ❖ Any change in the parameter affects the variable 14 Function ❖ Example #include <iostream> #include <math.h> float add(float a, float b) { b += 1; return a + b - 1; } float foo(int a, float &b) { b *= a; return b; } int main() { float x = 2.08) << endl; x = foo(2, y); cout << x << endl; cout << y << endl; return 0; } 15 Function ❖ main: ❖ Default return value of main: 0 - the program executed successfully ❖ stdlib.h/cstdlib: ❖ EXIT_SUCCESS: same as default return value ❖ EXIT_FAILURE: the program failed 16 Function ❖ Parameter passing: ❖ C++ allows user pass parameters by value or by reference ❖ If user pass a parameter using reference, it will be translated to pointer ❖ Unlike C++, everything in Java is pass-by-value. ❖ Think about what happens in the background. ❖ C++ allows user pass default values to parameters 17 Function ❖ Example #include <iostream> #include <math.h> float add(float a, float b = 1.0f) { return a + b; } int main() { float x = 2.08) << endl; cout << “increase x: x + 1 = ” << add(x) << endl; return 0; } 18 Function ❖ Reuse functions ❖ Define prototype in header file (.h): <type> <name>(<parameters>); ❖ Must export the function if it was build in a library. ❖ Use export/import instructions: depend on platform and language ❖ Static linked libraries vs.
Dynamic linked libraries 19 Function ❖ Why do you need function prototype? ❖ To reuse a function written in another module ❖ To solve tricky situations 20 Function ❖ inline functions ❖ Similar to function, except that the compiled code will be inserted where we call inline functions. ❖ Purpose: improve performance ❖ inline <return type> <function name>(<parameters>) { <function body> } 21 Scope of Variables Scope of Variables ❖ In C/C++, the variable is effective in the scope of declaration statement ❖ In C: all variables must be declared at the beginning of the function. No initialization in declaration. ❖ In C++: variables can be declared anywhere and take effect in the declared scope ❖ void test() { for (int i = 0; i < 5;) { i += 2; } i = 10;// error } 23 Scope of Variables ❖ Global vs.
Local variables ❖ Global variables can be accessed everywhere in the function without declaration ❖ Local variables can only be accessed inside the scope where it is declared 24 Scope of Variables ❖ Global vs. Local variables #include <iostream> #include <math.h> float defaultFactor; float mul(float a, float b, bool useGlobal = false) { return useGlobal? a * defaultFactor: a * b; } int main() { defaultFactor = 2.0f; cout << “Use default factor: ” << mul(3.14159, 0, true) << endl; cout << “Multiply pi by 5: ” << mul(3.0f) << endl; return 0; } 25 Scope of Variables ❖ Global vs. Local variables ❖ Why don’t we declared everything at global scope? ❖ Benefit of local variable? ❖ When should we use global variables? ❖ When should we use local variables? 26 Scope of Variables ❖ Global vs. Local variables ❖ Local variables take precedence over global variables ❖ The :: operator is called the scope resolution operator 27 Scope of Variables ❖ Global vs.
Local variables #include <iostream> #include <math.h> float accSum; float acc(float a, float accSum) { ::accSum += a; return accSum + a; } int main() { accSum = 0.14159, 0) << endl; cout << “acc(3.14159, 1) << endl; cout << “accSum: ” << accSum << endl; return 0; } 28 Storage Storage ❖ How your program is organized? ❖ What are common errors? ❖ Memory overflow ❖ Memory corruption 30 Storage high address command line arguments //// and environment variables stack heap uninitialized data (bss) initialised to zero by exec initialized data read from program file text (code segment) low address 31 Storage ❖ Code segment: contains executable code (binary code) ❖ Data segment: ❖ Initialized data: global, static, constants ❖ Uninitialized data ❖ Heap: contains allocated memory at runtime ❖ Stack: stores local variables, passed arguments, and return address 32 Storage ❖ Common errors: ❖ Use variables without initialization ❖ Memory fault ❖ Access restricted areas ❖ Overwrite meta information on memory ❖ Stack overflow 33 Storage ❖ Uninitialized variables #include <iostream> #include <math.h> float __gVal; float foo(float a, float b) { __gVal += b; return a * b + __gVal; } int main() { float x, y; x = 0.5f; cout << foo(x, y) << endl; return 0; } 34 Storage ❖ Memory fault (access freed memory) #include <iostream> #include <math.h> float* foo(float a, float b) { a += b; return &a; } int main() { float x, y; x = 0.9f; float *pRet = foo(x, y); cout << *pRet << endl; return 0; } 35 Storage ❖ Memory fault (access restricted area) #include <iostream> #include <math.h> char* getConstString() { return “This is a string”; } int main() { char* pStr = getConstString(); cout << pStr << endl; for (int i = 0; i < 10; i++) { pStr[i] = ‘-’; } cout << pStr << endl; return 0; } 36 Storage ❖ Overwrite meta information in memory (memory corruption) #include <iostream> #include <math.h> void foo(char *pStr) { char buf[10]; strcpy(buf, pStr); } int main() { char* pStr = “This string will overwrite the local buffer”; foo(pStr); return 0; } 37 Storage ❖ Blow away your stack (stack overflow) #include <iostream> #include <math.h> int foo(int n) { return n + foo(n + 1); } int main() { cout << “This code will blow away your stack\n”; foo(0); return 0; } 38 Storage ❖ How to avoid memory errors? Heap vs. Stack errors ❖ Invalid memory access ❖ Memory leaks ❖ Mismatched allocation/deallocation ❖ Missing allocation ❖ Uninitialized memory access ❖ Cross stack access 39 Pointer Pointer ❖ What is pointer? ❖ How do we access memory so far? ❖ Through variables: use identifiers ❖ What if you need something more dynamic? ❖ Allocate on demand ❖ Vary in size ❖ Flexible access mechanism 42 Pointer ❖ C++ program does not decide exact memory address of variables, the OS does. ❖ Obtain memory address of a variable ❖ Use operator & ❖ E.534f; cout << &a << endl; 43 Pointer ❖ Declare a pointer variable ❖ <type> * <identifier>; ❖ E.: int * pInt, a; ❖ Define a pointer type ❖ typedef <type>* <alias_type>; ❖ E.: typedef int* intPointer; 44 Pointer ❖ Special values ❖ Specific areas managed by OS ❖ Stack ❖ Code address ❖ Data addresses ❖ NULL == 0 (== nullptr) 45 Pointer 3.14159 unknown #include <iostream> x pX #include <math.14159 &x int main() { float x = 3.14159; float* pX; x pX pX = &x; cout << “Value of x: ” << x << endl; cout << “Address of x: ” << pX << endl; 7.5; cout << “Value of x: ” << x << endl; pX = NULL; x pX return 0; } 7.853975 0 x pX 46 Pointer ❖ Dereference operator * ❖ Used to access the memory pointed to by the pointer variable ❖ Usage: *<pointer variable> ❖ Example: ❖ int *pX = &a; *pX = 5; a = *pX - 2; 47 Pointer ❖ Casting pointer value ❖ int *p; p = 0xff63;// error, illegal statement ❖ int *p; p = reinterpret_cast<int *>(0xff63); ❖ Use pointer wisely! 48 Pointer ❖ Pointer vs. array (static) #include <iostream> #include <math.h> ❖ Pointer can be changed! int main() { int a[10]; for (int i = 0; i < 10; i++) { ❖ Access memory in the same way a[i] = 0; cout << a[i] << " "; } ❖ A static array can be considered as a cout << endl; int *pA = a; constant pointer for (int i = 0; i < 10; i++) { pA[i] = i + 1; cout << pA[i] << " "; *a = i; } cout << endl; return 0; } 49 Pointer #include <iostream> ❖ Passing array as function parameter #include <math.h> typedef struct { ❖ Passing values: define a new int data[10]; } myStruct; structure to hold array int foo(myStruct a) { int sum = 0; ❖ int foo(int a[10]) { for (int i = 0; i < 10; i++) sum += a.data[i] = i; … } cout << “Sum = ” << foo(mA) << endl; } return 0; } 50