350 likes | 362 Views
Learn about formal vs. actual parameters, call by value/reference, static/dynamic arrays, and object composition in C++.
E N D
Short C++ Review CS 302 – Data Structures
Formal Parameters • The argument names in the function header are referred to as formal parameters. int FindMax(int x, int y) { int maximum; if(x>=y) maximum = x; else maximum = y; return maximum; } x,yare called “formal parameters”
Actual Parameters • The argument names in the function call are referred to as actual parameters int FindMax(int, int); // function prototype int main() { int firstnum, secnum, max; cout << "\nEnter two numbers: "; cin >> firstnum >> secnum; max=FindMax( firstnum, secnum); // the function is called here cout << "The maximum is " << max << endl; return 0; } firstnum,secnumare called “actual parameters”
Calling a function by value void newval(float, float); // function prototype int main() { float firstnum, secnum; cout << "Enter two numbers: "; cin >> firstnum >> secnum; newval(firstnum, secnum); cout << firstnum << secnum << endl; return 0; } void newval(float xnum, float ynum) { xnum = 89.5; ynum = 99.5; } Formal parameters receive a “copy” of the actual parameters!
Calling a function by reference void newval(float&, float&); // function prototype int main() { float firstnum, secnum; cout << "Enter two numbers: "; cin >> firstnum >> secnum; newval(firstnum, secnum); cout << firstnum << secnum << endl; return 0; } void newval(float& xnum, float& ynum) { xnum = 89.5; ynum = 99.5; } Formal parameters become an “alias” of the actual parameters!
1D Static Array Allocation short arr[6]; • &arr[i] := &arr[0] + (i * sizeof(short)) offset
Static 1D arrays as function arguments float find_average(int [], int); void main() { const numElems = 5; int arr[numElems] = {2, 18, 1, 27, 16}; cout << "The average is " << find_average(arr, numElems) << endl; }
Static 1D arrays as function arguments float find_average(int vals[], int n) { int i; float avg; avg=0.0; for(i=0; i<n; i++) avg += vals[i]; avg = avg/n; return avg; }
2D Static Array Allocation • Static 2D arrays are always stored in memory as 1D arrays in contiguous memory. short arr2D[3][4];
Static 2D arrays as function arguments float find_average(int [][2], int, int); void main() { const numRows = 2; const numCols = 2; int arr2D[numRows][numCols] = {2, 18, 1, 27}; float average; average = find_average(arr2D, numRows, numCols); cout << "The average is " << average << endl; }
Static 2D arrays as function arguments float find_average(int vals[][2], int n, int m) { int i,j; float avg; avg=0.0; for(i=0; i<n; i++) for(j=0; j<m; j++) avg += vals[i][j]; avg = avg/(n*m); return avg; }
Dynamic 1D Array Allocation/ Deallocation int *arr; arr = newint[N]; delete [] arr;
Dynamic 1D arrays as function arguments float find_average(int *, int); void main() { int *arr, numElems; float average; cin << numElems; arr = new int[numElems]; // initialize array average = find_average(arr, numElems); cout << "The average is " << average << endl; }
Dynamic 1D arrays as function arguments float find_average(int *vals, int n) { int i; float avg; avg=0.0; for(i=0; i<n; i++) avg += vals[i]; avg = avg/n; return avg; }
Dynamic 2D Array Allocation arr[2][6] 480 482 484 486 488 490
Dynamic 2D Array Allocation/Deallocation int **arr2D; arr2D = new int* [numRows]; // allocation for(i=0; i<numRows; i++) arr2D[i] = new int[numCols]; for(i=0; i<numRows; i++) // deallocation delete [] arr2D[i]; delete [] arr2D;
Dynamic 2D arrays as function arguments float find_average(int **, int, int); void main() { int **arr2D; float average; arr2D = new int*[numRows]; for(i=0; i<numRows; i++) arr2D[i] = new int[numCols]; // initialize array average = find_average(arr2D, numRows, numCols); cout << "The average is " << average << endl; }
2D Dynamic arrays as function arguments float find_average(int **vals, int n, int m) { int i, j; float avg; avg=0.0; for(i=0; i<n; i++) for(j=0; j<m; j++) avg += vals[i][j]; avg = avg/(n*m); return avg; }
class rectangle { private: float height; float width; int xpos; int ypos; public: rectangle(float, float); // constructor void draw(); void posn(int, int); void move(int, int); }; rectangle::rectangle(float h, float w) { height = h; width = w; xpos = 0; ypos = 0; }
Object Composition: objects as members of classes class rectangle { private: float height; float width; int xpos; int ypos; properties pr; public: rectangle(float, float, int, int ); // constructor void draw(); void posn(int, int); void move(int, int); }; A class may have objects of other classes as members.
Object Composition (cont.) class properties { private: int color; int line; public: properties(int, int); // constructor }; properties::properties(int c, int l) { color = c; line = l; }
Object Composition (cont.) rectangle::rectangle(float h, float w, int c, int l):pr(c, l) { height = h; width = w; xpos = 0; ypos = 0; }; void main() { rectangle rc(3.0, 2.0, 1, 3); ……… }
#include <iostream.h> #include <string.h> class string { private: char *s; int size; public: string(char *); ~string(); void print(); void copy(char *); }; void string::print() { cout << s << endl; } Note: no user defined copy constructor provided! void string::copy(char *c) { strcpy(s, c); }
Constructor/Destructor string::string(char *c) // constructor { size = strlen(c); s = new char[size+1]; strcpy(s,c); } string::~string() // destructor { delete []s; }
void main() { string str1("George"); string str2(str1); // shallow copy! str1.print(); // what is the output ? str2.print(); str2.copy("Mary"); str1.print(); // what is the output now ? str2.print(); }
Copy-Constructor string::string(const string& old_str) { size = old_str.size; s = new char[size+1]; strcpy(s,old_str.s); }
Overloading Assignment • Default overloading is not enough for classes with pointer members (i.e., shallow copy) class string { private: char *s; int size; public: string(char *); ~string(); void operator=(string&); void print(); void copy(char *); };
Overloading Assignment void string::operator=(string& old_str) { delete [] s; //release previously assigned memory size = old_str.size; s = new char[size+1]; //assign new memory strcpy(s, old_str.s); }
Handling multiple assignments(e.g., x=y=z;) string& string::operator=(const string& old_str) { if (this != &old_str) { delete [] s; size = old_str.size; s = new char[size+1]; strcpy(s, old_str.s); } return *this; // return ref for multiple assignment }
Difference between copy constructor and assignment • The copy constructor creates a new object. • The assignment operator works on an already valid object.