cs 192 lecture 14 winter 2003 january 14-15, 2004 dr. shafay shamail

33
CS 192 Lecture 14 Winter 2003 January 14-15, 2004 Dr. Shafay Shamail

Post on 21-Dec-2015

217 views

Category:

Documents


1 download

TRANSCRIPT

CS 192

Lecture 14

Winter 2003

January 14-15, 2004

Dr. Shafay Shamail

Functions

• Building blocks of a C++ program

• Each function has a name, which is used to call the function; functions call each other

• You will write your own functions, e.g. main(), and also use pre-written functions from standard library

/* This program contains two functions: main() and myfunc().*/#include <iostream.h>

void myfunc(); // myfunc's Protoype

int main(){ cout << "In main()"; myfunc(); // call myfunc() cout << "Back in main()";

return 0;}

void myfunc() // myfunc’s Definition{ cout << " Inside myfunc() ";}

Function Prototypevoid myfunc(); // myfunc's Protoype

• Like variable declaration; tells the compiler about the return type of the function and the number and type of parameters it needs from the calling function:

return_type functionName (parameter list);

• So, place prototypes before main()• main() is predefined in C++ and does not need a

prototype• Can’t the compiler look ahead and get definitions?• Prototype can be omitted if whole function placed

before it is called; is that a good practice?

Returning a Value// Returning a value.

#include <iostream.h>

int mul(int x, int y); // mul()'s prototype

int main(){ int answer; answer = mul(10, 11); // assign return value cout << "The answer is " << answer; return 0;}

// This function returns a value. int mul(int x, int y){ return x * y; // return product of x and y}

Library Functions• Pre-written functions in libraries that you can use• Just include the proper header file• Compiler gets prototype from the header file and

searches appropriate libraries itself to get function definition

• e.g. math library has mathematical functions in it

#include <iostream.h>#include <math.h> //or <cmath>

int main(){ cout << sqrt(9.0); return 0;}

Scope Rules• Scope rules tell that a variable is visible to which parts of your

program; also define variable’s lifetime• 3 types of variables: local, global, formal parameters

Scope Rules - Local Variables

• A variable can be declared inside any block and is then local to that block

• Block: {} int main() { {int x = 4;} cout << x; return 0; }

• error C2065: 'x' : undeclared identifier• Memory storage for a local variable created when entering

its block and destroyed when its block exited

Scope Rules-Local Variables• Most common block is a function

#include <iostream.h>void func();int main(){ int x; // local to main() x = 10; func(); cout << x; // displays ? return 0;}void func(){ int x; // local to func() x = -199; cout << x; // displays ?}

• -199 10. Each variable x has a separate location in memory• Identically-named variables in inner block ‘hide’ or override

those in the outer block; Avoid this practice

Scope Rules-Local Variables #include <iostream.h> int main() { int i, j; i = 10; j = 100; if(j > 0) { // start of block int i; // this i is separate from outer i i = j / 2; // outer j is known here cout << “first inner i: " << i << '\n'; } if(i < 50) { i += 10; cout << “2nd inner i: “ << i << endl;

} cout << "outer i: " << i << '\n'; return 0; }50 20 20• Declaring within a conditional block also saves memory; see next slide

Scope Rules-Local Variables

int main() { int choice; cout << "(1) add numbers or "; cout << "(2) concatenate strings?: "; cin >> choice;

if(choice == 1) { int a, b; /* activate two integer vars */ cout << "Enter two numbers: "; cin >> a >> b; cout << "Sum is " << a+b << '\n'; } else { char s1[80], s2[80]; /* activate two strings */ cout << "Enter two strings: "; cin >> s1; cin >> s2; strcat(s1, s2); cout << "Concatenation is " << s1 << '\n'; } a = 10; // *** Error *** -- a not known here! return 0; }

Scope Rules-Local Variables

• Variables declared in for loops are local according to current spec for C++

for(int i = 0; i<10; i++)

cout << i << " ";

i = 100; // *** Error *** -- i not known here!

• Does not work on Visual C++ 6.0 (i.e. no error)• Can declare a variable within any conditional

expressionif(int x = 20)

{

cout << "This is x: ";

cout << x;

}

x = 2; //*** Error *** -- x not known here!

• Not a good practice

Scope Rules-Formal Parameters

• Formal parameters: variables that receive values passed to a function

• Scope local to the function #include <iostream.h>

int mult(int, int);

int main()

{

int a = 10, b = 20;

cout << mult(a, b);

//cout << x << y; // *** Error *** --unknown identifiers x, y

return 0;

}

int mult(int x, int y)// can have different names here

{

return x*y;

}

Scope Rules-Global Variables

• Usually declared outside any function; have life as long as the program runs

• Can be used by all following functions• Usually placed at the beginning of program• Initialized only at the start of the program;

uninitialized default to zero• An identically named local variable masks global

one

Scope Rules-Global Variables #include <iostream.h> void func();

int i = 2; // global int main() { cout << i << endl; func(); cout << i << endl; int i = 5; // local. What if i=5; cout << i << endl; func(); return 0; } void func() { cout << i << endl; int i = 3; // local cout << i << endl; }• 2 2 3 2 5 2 3• 2 2 3 2 5 5 3 if i = 5 at the indicated place

Scope Rules-global variables

#include <iostream.h> #include <cstdlib> void drill(); int count; //count and num_right are global int num_right; int main() { cout << "How many practice problems: "; cin >> count; num_right = 0; do { drill(); count--; } while(count); cout << "You got " << num_right << “ right.\n"; return 0; }

void drill() { int count; /* This count is local. */ int a, b, ans; // Generate two numbers between 0 and 99. a = rand() % 100; b = rand() % 100; // The user gets three tries to get it right. for(count=0; count<3; count++) { cout << "What is " << a << " + " << b << "? "; cin >> ans; if(ans==a+b) { cout << "Right\n"; num_right++; return; } } cout << "You've used up all your tries.\n"; cout << "The answer is " << a+b << '\n'; }

Passing Pointers to Functions

• No big deal. Just declare parameter as type _______ ?

#include <iostream.h> void f(int *j);//or void f(int *); int main() { int i; int *p; p = &i; // p now points to i f(p); cout << i; // i is now 100 return 0; } void f(int *j) { *j = 100; // var pointed to by j is assigned 100 }

i26

p j

100

100 100

Passing Pointers to Functions• The pointer variable not necessary. Can generate and pass the

address of i as such to f()

#include <iostream.h> void f(int *j); int main() { int i; f(&i); cout << i; return 0; } void f(int *j) { *j = 100; // var pointed to by j is assigned 100 }

i26

j

100

100

Passing Pointers to Functions #include <iostream.h> int sqr_it(int x); int main() { int t=10; cout << sqr_it(t) << ' ' << t; //output? } int sqr_it(int x) { x = x*x; return x;}

• IMPORTANT: What’s the difference between the above function, and the ones on previous two slides?

• Here, a copy of the value of t is passed. t remains unaltered. x is a local variable, which could have been named t

• Called “Call by Value”• Previous called “Call by Reference” where the original

variable (not a copy) is accessed by the called function

(copy)t5 5

5x

Passing Arrays to Functions• What is an array name without index? • Address of first element passed to function. So actual

array accessed, not a copy. Saves memory• 3 ways to pass this addressI. Declare parameter as an array of same type and size #include <iostream.h> void display(int num[10]); //or display(int [10]); int main() { int t[10],i; for(i=0; i<10; ++i) t[i]=i; display(t); // pass array t to a function cout <<endl; for(i=0; i<10; i++) cout << t[i] << ' '; //output? } // Print some numbers. void display(int num[10]) { int i; for(i=0; i<10; i++) cout << num[i] << ' '; //output? for(i=0; i<10; i++) (num[i] = num[i] + 1); }

Passing Arrays to FunctionsII. Can also declare as display(int num[]) i.e. unsized. Same thing • Internally, compiler converts int num[10] or int num[] to int *III. So, why not declare parameter as a pointer to int void display(int *num) { int i; for(i=0; i<10; i++) cout << num[i] << ' '; //or *(num+i) }• How is a single element passed? As an ordinary variable #include <iostream.h> void display(int num); //each element is of type int int main() { int t[10],i; for(i=0; i<10; ++i) t[i]=i; for(i=0; i<10; i++) display(t[i]); //only one element passed } void display(int num) { cout << num << ' ';}

Passing Arrays to Functions #include <iostream.h> void cube(int *n, int num); int main() { int i, nums[10]; for(i=0; i<10; i++) nums[i] = i+1; cout << "Original contents: "; for(i=0; i<10; i++) cout << nums[i] << ' '; cout << '\n'; cube(nums, 10); // compute cubes cout << "Altered contents: "; for(i=0; i<10; i++) cout << nums[i] << ' '; return 0; } void cube(int *n, int num) {

while(num) { *n = *n * *n * *n; num--; n++; } }• Original contents: 1 2 3 4 5 6 7 8 9 10• Altered contents: 1 8 27 64 125 216 343 512 729 1000

Passing Strings to Functions• What is a string stored as? So what should we pass?

#include <iostream.h> #include <cstring> #include <cctype> void stringupper(char *str); int main() { char str[80]; strcpy(str, "this is a test"); stringupper(str); cout << str; // display uppercase string return 0; } void stringupper(char *str) { while(*str) { *str = toupper(*str); // uppercase one char str++; // move on to next char } }

• Can also declare as an array of char stringupper(char[])

The return Statement• return statement can be used without a value for void

functions. Must return a value for non-void functions• Control passed back to calling function when return

encountered or closing curly brace of function #include <iostream.h> void power(int base, int exp); int main() { power(2, 10); return 0; } void power(int base, int exp) { int i; if(exp<0) return; i = 1; for( ; exp; exp--) i = base * i; cout << "The answer is: " << i << endl; }

The return Statement• Can have multiple return statements. Function returns

as soon as the first one encountered void f()

{

// ...

switch(c) {

case 'a': return;

case 'b': // ...

case 'c': return;

}

if(count<100) return;

// ...

}

The return Statement• non-void functions return values to the calling function.

Therefore, can call a non-void function and use that call as an operand in an expression (as it has a value) in the calling function

• x = power(y);• if(max(x, y)) > 100) cout << "greater";• switch(abs(x)) {...

• Don’t necessarily have to store the returned value in a variable #include <iostream.h> #include <cstdlib> int main() { int i; i = abs(-10); // stored cout << abs(-23); // just used abs(100); // returned value discarded return 0; }

Multiple return Statements #include <iostream.h> int find_substr(char *sub, char *str); int main() { int index; index = find_substr("three", "one two three"); cout << "Index of three is " << index; // index is 8 return 0; }

int find_substr(char *sub, char *str){ int t; char *p, *p2;

for(t=0; str[t]; t++) { p = &str[t]; // reset pointers p2 = sub; while(*p2 && *p2==*p) { // check for substring p++; p2++; } /* If at end of p2 (i.e., substring), then

a match has been found. */ if(!*p2)

return t; // return index //of match

} return -1; // no match found }

Returning Pointers

#include <iostream.h> char *get_substr(char *sub, char *str); int main() { char *substr; substr = get_substr("three", "one two three four"); cout << "substring found: " << substr; return 0; }

char *get_substr(char *sub, char *str) {

int t;char *p, *p2, *start;

for(t=0; str[t]; t++) { p = &str[t]; // reset pointers start = p; p2 = sub;

while(*p2 && *p2==*p) { //check for substring

p++; p2++;

} /* If at end of p2 (i.e., substring),

then a match has been found. */ if(!*p2) return start; /* return pointer to

beginning of substring */} return 0; // no match found

}

Command Line Arguments

• To pass info to main() from the command line• e.g. cl hellouser

• Here, cl and hellouser are command line arguments • main() receives infor about these arguments in two parameters:

int main( int argc, char *argv[])

• argc (argument count) parameter is an integer that holds the number of arguments on the command line. Always at least 1, as program name also counted

• argv (argument variable) parameter is a null-terminated array of pointers to strings

• argv[0] points to program name on command line, argv[1] points to the first argument, and so on. argv[argc]==0

Command Line Arguments #include <iostream.h> int main(int argc, char *argv[]) { if(argc!=2) { cout << "You forgot to type your name.\n"; return 1; } cout << "Hello " << argv[1] << '\n'; return 0; }

• If we name this program as greeting, then after making an exe file we can type greeting Shamail at the command prompt and the program will execute and output: Hello Shamail

• Spaces and tabs usually separate strings; for a longer string, use quotes e.g. greeting “Shafay Shamail” outputs Hello Shafay Shamail

Command Line Arguments• Can access individual characters in the command line strings by using a

double subscript. See the program echo below #include <iostream.h> int main(int argc, char *argv[]) { int t, i; for(t=0; t<argc; ++t) {// t denotes the tth string i = 0; while(argv[t][i]) {// t[i] accesses the ith character of t cout << argv[t][i]; ++i;

cout << ' '; }

cout << ' '; } return 0; }

• e.g. echo hi there results in e c h o h i t h e r e

Passing Numeric Command Line Arguments

• Want to pass numbers to main( ), but it takes strings• Use atof(), atoi(), atol() #include <iostream.h>

#include <cstdlib>

int main(int argc, char *argv[])

{

double a, b;

a = atof(argv[1]);

b = atof(argv[2]);

cout << a + b;

return 0;

}

• atoi(“2”) gives 2; atof(“-11.11”) gives -11.11

Command Line

Arguments

#include <iostream.h>

#include <cstdlib>

int main(int argc, char *argv[])

{

double a, b;

a = atof(argv[1]);

b = atof(argv[2]);

cout << a + b;

return 0;

}

#include <iostream.h> int main(int argc, char *argv[]) { while(--argc > 0)

cout << *++argv << endl; return 0; }

#include <iostream.h> int main(int argc, char *argv[]) { for(int j=0; j<argc; j++)

cout << argv[j] << endl; return 0; }

#include <iostream.h> #include <cstdlib> int main(int argc, char *argv[]) { char **argvector = argv; double a, b; a = atof(*++argvector); b = atof(*++argvector); cout << a + b; return 0; }