CS 192 - PowerPoint PPT Presentation

1 / 32
About This Presentation
Title:

CS 192

Description:

bunnies = 50, rats = 50, rodents = 50. bunnies address = 9AF4, rodents' address = 5FF ... Subsequently altering pi to point to bunnies does not alter the fact that ... – PowerPoint PPT presentation

Number of Views:43
Avg rating:3.0/5.0
Slides: 33
Provided by: Sham4
Category:
Tags: bunnies

less

Transcript and Presenter's Notes

Title: CS 192


1
CS 192
  • Lecture 15
  • Winter 2003
  • January 16, 2004
  • Dr. Shafay Shamail

2
Passing Values
  • Ways to pass an argument to a function
  • By Value
  • By Address
  • By Reference
  • ___________________________________
  • By Value
  • include ltiostream.hgt
  • int sqr_it(int x)
  • int main()
  • int t10
  • cout ltlt sqr_it(t) ltlt ' ' ltlt t //output?
  • int sqr_it(int x)
  • x xx
  • return x
  • A copy of the value of argument t is passed to
    the formal parameter x. t remains unaltered.

3
Passing Pointers
  • By Address
  • We can use pointers to pass the address of the
    actual variable
  • include ltiostream.hgt
  • void sqr_it (int x)
  • int main()
  • int t 10
  • sqr_it(t)
  • cout ltlt t
  • return 0
  • void sqr_it (int x)
  • x (x)(x) // var pointed to by x is
    assigned 100
  • Original variable whose address is passed, i, is
    modified

i
100
10
5FF
j
5FF
4
Passing References
  • By Reference
  • Eliminates the need to manipulate pointers or to
    remember to pass address of argument. Not there
    in C
  • include ltiostream.hgt
  • void sqr_it(int x)
  • int main()
  • int t 10
  • cout ltlt "Old value for t " ltlt t ltlt '\n'
  • sqr_it(t) // pass address of t to sqr_it()
  • cout ltlt "New value for t " ltlt t ltlt '\n'
  • return 0
  • void sqr_it(int x)
  • x x // this modifies calling argument t
  • Output 1 10

5
References
  • A reference is an alias for the variable.
  • Simply follow the parameters type by an
    ampersand in prototype e.g. int x, pronounced x
    is a reference to an int
  • We passed the address of t to sqr_it() by
    assigning another name to t, which was x.
  • Now the compiler automatically knows that
    whenever x is encountered, we mean t, because
    they are the same memory location
  • To pass by reference, simply call the function
    with the variable name i.e. sqr_it(t)
  • Now mentioning the variable by its parameter name
    (new alias) in the function body accesses the
    original variable in the calling function

one variable, two names
10
100
5FF
t, x
6
Independent References
  • In addition to passing arguments by reference,
    can declare a stand-alone reference variable,
    called an independent reference
  • include ltiostream.hgt
  • int main()
  • int j, k
  • int i j // independent reference
  • j 10
  • cout ltlt j ltlt " " ltlt i // outputs 10 10
  • k 121
  • i k // copies k's value into j
  • cout ltlt "\n" ltlt j // outputs 121
  • return 0
  • An independent reference must be initialized when
    declared. How were we initializing reference
    parameters?

7
Independent References
  • Output of following programme?
  • include ltiostream.hgt
  • int main()
  • int x 3, y
  • cout ltlt "x " ltlt x ltlt endl ltlt "y " ltlt y ltlt
    endl
  • y 7
  • cout ltlt "x " ltlt x ltlt endl ltlt "y " ltlt y ltlt
    endl
  • return 0
  • error C2530 'y' references must be initialized
  • Output if we do int y x ?
  • Not a good idea to use independent references as
    not necessary and inherently confusing to have
    two names for same variable

8
References
  • Output?
  • include ltiostream.hgt
  • int main()
  • int rats 101
  • int rodents rats
  • cout ltlt "rats " ltlt rats
  • cout ltlt ", rodents " ltlt rodents ltlt endl
  • rodents
  • cout ltlt "rats " ltlt rats
  • cout ltlt ", rodents " ltlt rodents ltlt endl
  • cout ltlt "rats' address " ltlt rats
  • cout ltlt ", rodents' address " ltlt rodents ltlt
    endl
  • return 0
  • Output rats 101, rodents 101
  • rats 102, rodents 102
  • rats address 006FD, rodents address
    0068FD

9
References
  • include ltiostream.hgt
  • int main()
  • int rats 101
  • int rodents rats
  • cout ltlt "rats " ltlt rats
  • cout ltlt ", rodents " ltlt rodents ltlt endl
  • cout ltlt "rats' address " ltlt rats
  • cout ltlt ", rodents' address " ltlt rodents ltlt
    endl
  • int bunnies 50
  • rodents bunnies //can we change the
    reference?
  • cout ltlt "bunnies " ltlt bunnies
  • cout ltlt ", rats " ltlt rats
  • cout ltlt ", rodents " ltlt rodents ltlt endl
  • cout ltlt "bunnies address " ltlt bunnies
  • cout ltlt ", rodents' address " ltlt rodents ltlt
    endl
  • return 0
  • Output

10
References
  • A reference keeps referring to the same variable
    to which it was initialized. You cannot change it
    by assignment later on
  • int rats 101
  • int pi rats
  • int rodents pi
  • int bunnies 50
  • pi bunnies
  • cout ltlt pi ltlt endl ltlt rodents ltlt endl ltlt rats
    ltlt endl
  • Output 50 101 101
  • Initializing rodents to pi makes it refer to
    rats. Subsequently altering pi to point to
    bunnies does not alter the fact that rodents
    refers to rats

11
Returning References from Functions
  • The return type of function determines that a
    reference is passed
  • Can use such function on LHS of assignments!
    Cant do so with ordinary functions that have the
    usual return types
  • include ltiostream.hgt
  • double f()
  • double val 100.0
  • int main()
  • double newval
  • cout ltlt f() ltlt '\n' // display val's value
  • newval f() // assign value of val to newval
  • cout ltlt newval ltlt '\n' // display newval's
    value
  • f() 99.1 // change val's value
  • cout ltlt f() ltlt '\n' // display val's new
    value
  • return 0
  • double f()
  • return val // return reference to val

12
Returning References from Functions
  • include ltiostream.hgt
  • double change_it(int i) // return a reference
  • double vals 1.1, 2.2, 3.3, 4.4, 5.5
  • int main()
  • int i
  • cout ltlt "Here are the original values "
  • for(i0 ilt5 i)
  • cout ltlt valsi ltlt ' '
  • cout ltlt '\n'
  • change_it(1) 5298.23 // change 2nd element
  • change_it(3) -98.8 // change 4th element
  • cout ltlt "Here are the changed values "
  • for(i0 ilt5 i)
  • cout ltlt valsi ltlt ' '
  • cout ltlt '\n'
  • return 0
  • double change_it(int i)

13
Returning References from Functions
  • If a function returns a reference to a variable
    local to itself, what happens?
  • int f()
  • int i10
  • return i
  • i goes out of scope when f() returns. The
    behaviour of compilers is unpredictable in such
    cases. Some might give warning, some might give
    error. So be careful!
  • One way to avoid is to return reference to a
    global, or to a variable that was passed to the
    function from the calling function

14
When to Use Reference Arguments
  • We use them for two reasons
  • To alter a data object in the calling function
  • To speed up a programme by not passing entire
    data object
  • Second reason important for large data objects,
    such as structures and class objects
  • When to pass by value, by pointer, by reference?
    Some guidelines
  • If the data object is small, such as a built-in
    data type or a small structure, pass it by value
  • If the data object is an array, no choice but to
    use a pointer
  • If large data object is a structure, use a
    reference or pointer
  • If large data object is a class object, use a
    reference

15
Creating a Bounded Array
  • To prevent array overrun
  • include ltiostream.hgt
  • int put(int i) // put value into the
    // array
  • int get(int i) // obtain a value from the
    // array
  • int vals10
  • int error -1
  • int main()
  • int i
  • put(0) 10 // put values into the array
  • put(1) 20
  • put(9) 30
  • cout ltlt get(0) ltlt ' '
  • cout ltlt get(1) ltlt ' '
  • cout ltlt get(9) ltlt ' '
  • // now, intentionally generate an error
  • put(12) 1 // Out of Bounds
  • return 0
  • // Put a value into the array.
  • int put(int i)
  • if(igt0 ilt10)
  • return valsi // return a reference to
    // the ith element
  • else
  • cout ltlt "Bounds Error!\n"
  • return error // return a reference to
    // error
  • //________________________________
  • // Get a value from the array.
  • int get(int i)
  • if(igt0 ilt10)
  • return valsi // return the value of
    // the ith element
  • else
  • cout ltlt "Bounds Error!\n"
  • return error // return an error

16
Function Overloading
  • C allows you to give two or more functions the
    same name. The function is said to be overloaded
  • You can have a function average() that computes
    average of integers, another average() that
    calculates average of doubles
  • How can we do that without ambiguity?
  • Signature of a function is its list of parameters
  • Overloaded functions must have different
    signatures
  • Must differ in either the number, type, or order
    of arguments i.e. different signatures
  • Compiler can differentiate then and calls the
    correct version of the function

17
Function Overloading
  • Have you encountered overloading of some sort
    until now in C (not necessarily function
    overloading)?
  • The arithmetic operators. 2 3 and 2.2 3.6
  • The operator is overloaded
  • So, when to use overloaded functions?
  • When same sort of operation is to be performed on
    different data sets
  • Advantage Overloading functions that perform
    closely related tasks can make programs more
    readable and understandable
  • Also called function polymorphism

18
Function Overloading
  • include ltiostream.hgt
  • void f(int i) // integer parameter
  • void f(int i, int j) // two integer parameters
  • void f(double k) // one double parameter
  • int main()
  • f(10) // call f(int)
  • f(10, 20) // call f(int, int)
  • f(12.23) // call f(double)
  • return 0
  • void f(int i)
  • cout ltlt "In f(int), i is " ltlt i ltlt '\n'
  • void f(int i, int j)
  • cout ltlt "In f(int, int), i is " ltlt i
  • cout ltlt ", j is " ltlt j ltlt '\n'

19
Function Overloading
  • Write overloaded functions, one of which averages
    three double numbers, and the other two doubles
  • double ave(double n1, double n2)
  • return((n1 n2)/2.0)
  • double ave(double n1, double n2, double n3)
  • return (n1 n2 n3)/3.0)
  • How about int ave(double n1, double n2)...?
  • Syntax error. Return type not considered by
    compiler while differentiating between functions

20
ExerciseWrite three overloaded functions that
take integer, double and long respectively, and
return their absolute values
  • include ltiostream.hgt
  • int abs(int i)
  • double abs(double d)
  • long abs(long l)
  • int main()
  • cout ltlt abs(-10) ltlt "\n"
  • cout ltlt abs(-11.0) ltlt "\n"
  • cout ltlt abs(-9L) ltlt "\n"
  • return 0
  • int abs(int i)
  • cout ltlt "using integer abs()\n"
  • if(ilt0) return -i
  • else return i
  • double abs(double d)
  • cout ltlt "using double abs()\n"
  • if(dlt0.0) return -d
  • else return d
  • long abs(long l)
  • cout ltlt "using long abs()\n"
  • if(llt0) return -l
  • else return l

21
Default Function Arguments
  • A default value is a value that, although not
    universally applicable, is judged by the
    programmer to be appropriate in a majority of
    cases
  • A default value frees the individual from having
    to attend to every small detail
  • For example, in Unix each text file created by
    the author has read and write permissions for the
    author but only read permissions for all others
  • In C, we can give a parameter a default value
    in the function prototype. This value
    automatically used when no argument corresponding
    to that parameter is specified in a call to that
    function

22
Default Function Arguments
  • Default arguments must be specified with the
    first occurrence of the function name, typically
    in the prototype (and where else?)
  • void myfunc(double num 0.0, char ch 'X')
  • ...
  • myfunc(198.234, 'A') // pass explicit values
  • myfunc(10.1) // pass num a value, let ch default
  • myfunc() // let both num and ch default
  • Omitted argument must be the rightmost. If not,
    also have to omit all those to its right.
    Similarly for signature.
  • Call myfunc('A) is not correct. Also, the
    signature
  • void myfunc(double num 0.0, char ch) is not
    correct

23
Default Function Arguments
  • include ltiostream.hgt
  • // Calculate the volume of a box
  • int boxVolume(int length 1, int width 1, int
    height 1)
  • int main()
  • cout ltlt "The default box volume is "
  • ltlt boxVolume() ltlt endl ltlt endl
  • ltlt "The volume of a box with length 10,"
    ltlt endl
  • ltlt "width 1 and height 1 is "
  • ltlt boxVolume(10) ltlt endl ltlt endl
  • ltlt "The volume of a box with length 10,"
    ltlt endl
  • ltlt "width 5 and height 1 is "
  • ltlt boxVolume(10, 5) ltlt endl ltlt endl
  • ltlt "The volume of a box with length 10,"
    ltlt endl
  • ltlt "width 5 and height 2 is "
  • ltlt boxVolume(10, 5, 2)
  • ltlt endl
  • return 0

24
Function Overloading Ambiguity
  • Can have situations where compiler can not choose
    which function to run. Error
  • Main cause is Cs automatic type conversions
    attempts to convert type of argument to the type
    of parameter
  • double mpg(double miles, double gallons)
  • return (miles/gallons)
  • cout ltlt mpg(45, 3) ltlt miles per gallon
  • No error, as C converts 45 to 45.0 and 3 to 3.0
  • int myfunc(double d)
  • cout ltlt myfunc('c')//no error, conversion
    applied

25
Function Overloading Ambiguity
  • ff(char, int)
  • ff(int, int)
  • ff(0, a) //matches ff(int, int) as 0 is an
    exact //match of int
  • min(long, long)
  • min(double, double)
  • int i, j
  • min(i, j) //error ambiguous, no best match
  • foo(int, int)
  • foo(double, double)
  • foo(a, 3.14F) / error ambiguous two
    bestmatches thru promotion, and no promotion
    is preferred over the other /

26
Function Overloading Ambiguity
  • include ltiostream.hgt
  • float myfunc(float i)
  • double myfunc(double i)
  • int main()
  • // unambiguous, calls myfunc(double)
  • cout ltlt myfunc(10.1) ltlt " "
  • // ambiguous
  • cout ltlt myfunc(10)
  • return 0
  • ...
  • In C, all decimal valued constants are of type
    double, unless specified to be float i.e. double
    by default

27
Default Arguments Ambiguity
  • include ltiostream.hgt
  • void ff(int i)
  • void ff(long, int 0)
  • int main()
  • ff(2L) //matches ff(long, 0)
  • ff(0, 0) //matches ff(long, int)
  • ff(0) //matches ff(int)as 0 of exact type int
  • ff(3.14) /error ambiguous. Can match both
    functions/
  • ...
  • If void ff(double i) instead of ff(int i)?
  • Then ff(0) is ambiguous and ff(3.14) is ok

28
const Access Modifier
  • Keyword const before a variable declaration makes
    the value of the variable unalterable
  • const int change 5
  • change 1 //error
  • const double PI 3.14159/if pi oft-used in
    programme/
  • circ_area PI r r
  • Have to initialize and declare a const variable
    in the same line
  • const int students //error
  • A common use of const is when we dont want
    locations pointed to by pointers modified by
    mistake

29
Constant Pointers
  • include ltiostream.hgt
  • void code(const char str)//location pointed to
    by str unalterable
  • int main()
  • code("this is a test")
  • return 0
  • void code(const char str)
  • while(str)
  • cout ltlt (char) (str1) //print a as b and
    so on
  • str
  • The following wont work
  • void code(const char str)
  • while(str)

30
Constant Array Passing
  • include ltiostream.hgt
  • void display(const int num10)
  • // or display(const int num)
  • int main()
  • int t10,i
  • for(i0 ilt10 i) tii
  • display(t) // pass array t to a function
  • cout ltltendl
  • for(i0 ilt10 i) cout ltlt ti ltlt ' '
    //output?
  • // Print some numbers.
  • void display( const int num10)
  • int i
  • for(i0 ilt10 i) (numi numi
    1)//ERROR

31
Constant References
  • // const references cannot be modified.
  • include ltiostreamgt
  • using namespace std
  • void f(const int i)
  • int main()
  • int k 10
  • f(k)
  • return 0
  • void f(const int i)
  • i 100 // Error, can't modify a const
    reference.
  • cout ltlt i

32
(No Transcript)
Write a Comment
User Comments (0)
About PowerShow.com