1 functions in c++ default arguments overloading inlining call-by-reference scope of variables,...
TRANSCRIPT
1
Functions in C++• Default arguments• Overloading• Inlining• Call-by-reference• Scope of variables, static, extern• namespace• new and delete• assert
2
C++Functions
159.234
In C++ the use of void is optional in a function that has no arguments:
int fct() () { return global*2;}
Default arguments:// k has a default value of 2int power(int n, int k = 2int k = 2) { if (k == 2) {
return n*n;}
return power(n,k-1)*n;}
we can call this function in two different ways:
j = power(5,3); // 5 cubed j = power(5); // 5 squared
only trailing arguments may be only trailing arguments may be defaulteddefaulted
more than one argument can be defaulted:
void fct(int j=4, int k=5, int m=7);
3
C++Overloading
159.234
int maxmax(int m, int nint m, int n) { return (m>n)?m:n;}
What about the max of two floats?
max is already in use –
float fmax(float x, float yfloat x, float y) { return (x>y)?x:y;}
C++ allows functions with arguments of differing types, to have the same name.
We call this function function overloading.overloading.
float maxmax(float x, float y) { //is OK return (x>y)?x:y;}
4
C++Functions
159.234
One function can have more arguments than another, or the types of the arguments can be different.The compiler chooses which function to use by matching the arguments.
1. an exact match2. a match by promoting
float -> double, short -> long, etc.
3. a match by convertingfloat -> int
An overloaded function must have parameters that differ in some way.
Differing only by return type is notnot allowed.
5
C++Inlining:
159.234
int cube(int j) { return j*j*j;}The drawback with this code is its inefficiency. The time required to call the function may be the same as the calculation. If the function is called many times, the program slows down.
The alternative is to ignore functions. Write out the code each time it is used: i = k*k*k;
But this makes for messy code, especially if k is a computed expression.The keyword - inline - asks the compiler to generate inline code – as though we as though we had written out the code had written out the code each time.each time.
inlineinline int cube (int j) { return j*j*j;}inline functions cannot be cannot be recursiverecursive, and are normally very short.
6
C++Call-by-reference
159.234
If a C function wants to alter an argument, then a pointer to the variable must be used
int main() { int j = 4; change_it(&j); ...}
void change_it(int *ipint *ip) { (*ip) = 6;}
This works well for simple types. When pointers themselves are passed as arguments, it can be quite confusing - with pointers to pointers.
**p or even ***p can take some time for a human to unravel.
7
C++In C++, functions can use call-by-reference.
159.234
int main() { int i,j; ... swap(i,j); ...}void swap(int &p, int &qint &p, int &q) { int temp; if (p > q) { temp = p; p = q; q = temp; }}
p and q are called ‘reference parameters’. They refer back to the original variables - so the function function can alter its parameterscan alter its parameters.
We can create ‘reference variables’ similarly:int main() { int m; int &p = m;
p is now just another name for p is now just another name for the variable m. the variable m.
8
C++Scope:
159.234
Our programs so far have been small in size and have fitted into one file.Variables have been declared as eitherglobal - at the top of the file orlocal - at the beginning of a function.
This is not the whole story:Variables:that are declared outsideoutside functions are global.They must be declared beforebefore they are used.
int main() { ...}
int j = 4;int j = 4;void fct() { cout << jj;}
j is a global variable, but main() cannot access it.
9
In C++, local variables can be declared anywhere within a function. (statements and declarations can be mixed up in order, but a variable must be declared before it is used)
When the enclosing {} ends, the variable is destroyed (from the stackstack part of the memory)
if (x > 0){{y = x;
int zint z = x*x + x;w = y + z*z;
}}
ScopeThe portion of the program where an identifier has meaning is known as its scope.
10
ScopeThe scope resolution operator scope resolution operator :::: is used to access a name that has external scope and has been hidden by local scope.
int iint i = 50; //global variableglobal variable
int main() {
int i = 100; // this one is not seen for( int iint i = 0; i < 5; ++i){
cout <<"\nLocal i is "<< i << " ";
cout <<"Global i is "<< ( ::i::i ); }
}
This will print i = 0, 1, 2, etc for local and 50 for the global
11
C++Static Local Variables
159.234
Local variables can be declared anywhere within a function.When the enclosing {} ends, the variable is destroyed.
if (x > 0) { y = x;
int z = x*x + x; w = y + z*z;}
Static variables:Static local variables are not destroyed when the enclosing block ends.
char *fct() { static char static char s[16]; char *p p = &s[0]; ... return p;}ss retains its value from one call of fct() to another.
Static local variables Static local variables are similar to globals – their default value is 0 and they last until the program ends - but they are only accessible within the block that they are declared.
12
C++Local Variables
159.234
They are useful when returning a pointer to an area of memory:
char *fct() { char s[16], *p; p = s;p = s; ... return p; return p; // !}
is a mistakemistake most people make in their lives.
The returned pointer points to an area of memory that no longer contains anything useful!
13
C++Global Variable to be Used in Multiple Files
159.234
With large programs it is normal to split the code over several files.When a global variable is needed by code in more than one file we must:
define the variable in one file e.g. int j;int j;
declare the variable as extern in all other files:extern int j;extern int j;
It is normal to put the extern declarations in a header fileheader file, and include this header file in all code files. The compiler does not complain if it sees:
extern int j;int j;
14
C++STATIC FUNCTIONS
159.234
Static can also be applied to functions.Functions are extern by default - only their function prototype is needed in another file.
The static keyword limits the scope of a function to just the file in which it is written.This feature is important when writing libraries. There should be no name clashes of small private functions.
mylib.c
void fct1(void); //available to othersstatic void printit(void);static void printit(void); //only for me
void fct1() { ... printit(); ...}static void printit() { ...}
15
C++Namespace
159.234
C++ extends the idea of limiting access to particular functions by use of namespace and the scope resolving operator ::
Writers of libraries enclose their code with a namespace identifier
16
C++Namespace
159.234
Writers of libraries enclose their code with a namespace identifier
namespace PKlib namespace PKlib { void fct();}
Users of this library can either use the function by using its full name:int main() { PKlib::fct();PKlib::fct();}
or by making all functions in the library directly accessible :
using namespace PKlib;int main() { fct();}
17
Header files included without the .h prefix conform to the namespace standard.
All the standard functions are in the “std” namespace.
#include <iostream>#include <string>using namespace std;using namespace std;
will enable a program to use all the console and string functions without a std:: prefix
Namespace
18
using namespace std;int main(){ cout<<“Hello”;}
Namespace
or
using std::cout;int main(){ cout<<“Hello”;}
or int main(){ std::cout<<“Hello”;}
Assume: #include <iostream>#include <iostream>
GCC (use to) accept:
int main(){ cout<<“Hello”;}
Any of the following is acceptable:
Non-C++ standard
19
Conditional compilationAvoid multiple inclusions of the same header file. Include an #ifndef directive in the header file. (read as “if-not-defined” )
//The file myheader.hmyheader.h contains:
#ifndef MYHEADER_H#ifndef MYHEADER_H#define MYHEADER_H#define MYHEADER_H
//The declarations of //the header file follow here.
#endif#endif
20
Conditional compilationWhen the preprocessor scans the file for the first time:
•As the symbol MYHEADER_H is not yet defined, •The #ifndef condition succeeds and all declarations are scanned. •The symbol MYHEADER_H is defined.
When the file is scanned for the second time during the same compilation:
•As the symbol MYHEADER_H is defined, •All information between the #ifndef and #endif directives is skipped.
This is important to prevent accidental recursive This is important to prevent accidental recursive inclusion of files by the programmer.inclusion of files by the programmer.
21
#include <iostream>
using namespace std;
int myInt =98; // this is a global
namespace { //unnamed namespace
double d=88.22;
}
namespace Example{
const double PI= 3.14159;
const double E=2.71828const double E=2.71828;
int myInt =25;
void printVal();
namespace Inner{//nested namespace
enum years {past=1900,present=2004,futurefuture};
}
}
int main(){
cout <<"d= "<<d; //output value of unnamed namespace
cout <<"\nglobal variable myInt "<< myInt;
//output values of Example namespace
cout <<"\nPI = "<< Example::PI << "\nE ="
<< Example::EExample::E<<"\nmyInt= "<<Example::myInt
<<"\nFUTURE = "<<Example::Inner::futureExample::Inner::future<<endl;
Example::printVal()Example::printVal(); //invoke printVal function
return 0;
}
void Example::printVal(){
cout <<"\nIn printVal:\n"<<"myInt = "<< myInt
<<"\nPI = "<< PI << "\nE = " << E
<<"\nd = " << d<<"\n(global) myInt ="<<::myInt
<<"\nfuture = "<<Inner::futureInner::future<<endl;
}
• Example output:d= 88.22global variable myInt 98PI = 3.14159E =2.71828myInt= 25FUTURE = 2005
In printVal:myInt = 25PI = 3.14159E = 2.71828d = 88.22(global) myInt =98future = 2005
22
C++assert
159.234
#include <assert.h>void fct(int n) { assert(n<10);assert(n<10); printf("n is less than 10!\n");}
assert has a bool as an argument:If it is true then assert does nothing.
If it is false then assert prints an error and exits.
23
Static variable - a variable that is local to a function and whose lifetime is the life of the program. Namespaces are used to avoid name clashes when programs written by various parties are combined
The unary operands new and delete are available to manipulate heap memory.
Next: Classes (Textbook p.115)
SummarySummary
24
C++new and delete
159.234
new and delete can be used instead of malloc and free.
Use only one form or the other. int main() { int *ip;//allocate space for an int ip = new int; ... delete ip;}
int main() { int *ip;//allocate an array of int ip = new int[50]; ... delete [] ip;}
notice the form of the delete with arrays.
Don’t try to free something that was obtained with new or vice-versa.
25
Two Dimensional arrays• For example: int ** array; // declare an array of arrays - an array of “pointers-to-
ints” array = new int* [10]; // allocate an array of pointers for(int i=0;i<10;i++){ // allocate individual arrays of ints array[i] = new int [7]; } array[9][6] = 42; // use as normal
for(int i=0;i<10;i++){ // free up memory using delete[] operator
delete[] array[i]; } delete[] array; // finally free up the array of arrays using delete []