Title: EECS498-006 Lecture 23
1EECS498-006 Lecture 23
2Something New (Sort Of)
- Consider the following line of code from a
program I wrote - Any ideas as to what this odd syntax does?
- Consider, instead this line of code
- Now, we see that the above line is a function
call - retval is the return value of the function call
- addEmUp is the name of the function we are
calling - mainary is the the first parameter to the
function - arySize is the second parameter to the functions
- Notice the second example is the same as the
first, with "opListwhichOp" replaced with
"addEmUp"
retVal opListwhichOp (mainary, arySize)
retVal addEmUp(mainary, arySize)
3Intro To Function Pointers
- In C function names in your program actually
represent the address where the executable code
for that function starts - This means that we can set a pointer variable to
the address of a function, and call it via the
pointer - These are called "function pointers"
- There are many potential uses for function
pointers - Function pointers can be placed in an indexed
array, thus allowing you to call a specific
function depending on value used as index - Function pointers can be passed as parameters to
functions, allowing one function to call
different functions in different circumstances - Function pointer can be updated in a loop to
perform several operations (function calls) on
the same data, with only one LOC
4Use Of Function Pointers
- Any variable in C must be declared.
- Function pointer variables are no exception
- What type is a function pointer?
- Type must describe the return value and params of
the function - Now, variables we declare to be of type "operFn"
are function pointers, with the described
signature
typedef int (operFn) (int, int)
\__________/
This is the param list
for the func ptr This is the name
of the type we are creating return type
of function being pointed to Says that we are
defining a new type (for our function ptr)
5Use Of Function Pointers, Cot'd
- Let's assume we have the following functions
defined - All of the above functions have the same
parameter types and return type - We can define a type for pointers to such
functions - Now, declare a function pointer variable
- The variable "fptr" can be assigned to the above
functions
int addEmUp (const int ary, int size) int
multEmUp (const int ary, int size) int findMin
(const int ary, int size) int findMax (const
int ary, int size)
typedef int (operFn) (int, int)
operFn fptr
fptr addEmUp // or fptr multEmUp etc...
6Interesting (and useful) C Stuff
- There are many elements of the C language not
discussed - This lecture is just a collection of C
information - These items are NOT necessarily related in any
way - More importantly, you should not assume that
everything covered should be used often - Remember, just because you are a good programmer,
using good style, does not mean everyone else is - You should know many features even if you don't
plan on using them all, in case you come across
them in code - Every feature has a place where it is a good
feature, and most have a place where it is a bad
feature
7The Ternary Operator
- There is an operator in C called the ternary
operator - It is somewhat widely used in certain
circumstances - Can make your code more compact
- Avoid using it too much, though, as it could get
hard to trace - The ternary operator can replace the
"if-then-else" structure in some situations - The operator is "?"
- Place an expression before the question mark
- Place a value to be used is the expression is
true between the question mark and colon - Place a value to be used otherwise after the
colon - Often used when assigning different values
depending on a condition
8The Ternary Operator, Example
int main(void) int i 7, j 10, k 4, s
0 //Assign s to i if i is less than j.
//Otherwise, assign s to j //Method 1 if (i
lt j) s i else s j cout ltlt
"First - s " ltlt s ltlt endl //Method 2 s
(i lt j)?ij cout ltlt "Second - s " ltlt s ltlt
endl cout ltlt "Max(" ltlt i ltlt "," ltlt j ltlt ")
" ltlt ((i gt j)?ij) ltlt endl cout ltlt "Max(" ltlt i
ltlt "," ltlt k ltlt ") " ltlt ((i gt k)?ik) ltlt endl
return (0)
First - s 7 Second - s 7 Max(7,10)
10 Max(7,4) 7
9The Comma Operator
- The comma is another operator allowed in C
- A comma expression is a series of expressions
separated by commas - Since a comma expression is, in fact, an
expression, it has a value - the value of the
rightmost expression - Each expression in a comma expression is
evaluated in order from left to right - Use of the comma can lead to major headaches in
trying to interpret a program in some cases - Use of the comma in a for loop is quite common
though
10The Comma Operator, Example
int i, j, k 0, l 0, m 0 for (i 0, j
5 i lt 5 i, j--) cout ltlt "i " ltlt i ltlt " j
" ltlt j ltlt endl if (k 3) //FALSE m k
1 l 2 cout ltlt "k " ltlt k ltlt " l " ltlt l ltlt "
m " ltlt m ltlt endl if (k 0) //TRUE m k
3 l 4 cout ltlt "k " ltlt k ltlt " l " ltlt l ltlt "
m " ltlt m ltlt endl if (k 17) //FALSE m (k
5, l 6) cout ltlt "k " ltlt k ltlt " l " ltlt l ltlt
" m " ltlt m ltlt endl if (k 3) //TRUE m (k
7, l 8) cout ltlt "k " ltlt k ltlt " l " ltlt l ltlt
" m " ltlt m ltlt endl
i 0 j 5 i 1 j 4 i 2 j 3 i 3 j 2 i 4 j
1 k 0 l 2 m 0 k 3 l 4 m 3 k 3 l 4 m 3 k
7 l 8 m 8
11Function Objects
- You've used the ( ) operator many times when you
make a function call - Normally, it would be a bad idea to overload this
operator - However, there are cases where it might make
sense to overload the function call operator - When a class overloads ( ), an object of that
class is called a "function object" - I stress again - this is usually a bad idea
- Still, it is pretty interesting
- When using an overloaded ( ) operator, it appears
you are calling a function - Since the function call is actually a method of
the class, it acts different, depending on the
values of data members of the object
12Function Object, Example
class compareClass public int cmpWith
char cmpOp bool operator() (int check)
bool res if (cmpOp 'lt')
res (cmpWith lt check) else if (cmpOp
'gt') res (cmpWith gt check)
return res
int main(void) bool a compareClass
compare compare.cmpWith 9 compare.cmpOp
'gt' a compare(5) cout ltlt "1 " ltlt
(a?"true""false") ltlt endl a compare(12)
cout ltlt "2 " ltlt (a?"true""false") ltlt endl
compare.cmpOp 'lt' a compare(5) cout ltlt
"3 " ltlt (a?"true""false") ltlt endl a
compare(12) cout ltlt "4 " ltlt
(a?"true""false") ltlt endl return (0)
1 true 2 false 3 false 4 true
13Labels
- Labels are exactly that - a way to identify
(label) an area of your code - If unreferenced, they are ignored during
execution - A label is just an identifier with a colon after
it - see below
int main(void) cout ltlt "Welcome to a label
program" ltlt endl label1 cout ltlt "Labels can
appear in programs" ltlt endl blah cout ltlt
"They do not interfere with" ltlt endl cout ltlt
"the flow or execution!" ltlt endl blip cout ltlt
"The End!" ltlt endl exit(0) blop cout ltlt
"See ya" ltlt endl return (0)
Welcome to a label program Labels can appear in
programs They do not interfere with the flow or
execution! The End!
14Goto (gasp!)
- Labels by themselves are pretty boring, as they
serve no purpose - C does provide a goto statement although it is
rarely used and always results in a nasty sneer
by most programmers - Still, there are situations, where you might see
a goto in someone else's code (of course, you
would never use one) - "goto" is a C keyword
- The keyword is followed by a label, making a
"goto statement" - When a goto statement is reached, the flow of
your program immediately jumps to the next
statement after the label - Using goto results in jumpy code that is
difficult to trace and follow. Avoid the use of
goto!!
15Goto (gasp!), Example (double gasp!)
int main(void) int fact 1 int value
5 goto mult printRes cout ltlt "result is
" ltlt fact ltlt endl goto alldone mult fact
value value-- goto whatnext cout ltlt
"Current Val " ltlt fact ltlt endl alldone cout
ltlt "Hope you had fun! Bye" ltlt endl return
(0) whatnext if (value gt 1) goto mult
else goto printRes return (5)
result is 120 Hope you had fun! Bye
(Yes, it actually works, but it is far from
clear. This is a horrible use of goto - many
uses are not so blatant and difficult)
16Bitwise Operators
- You all know that a byte is a collection of 8
bits - Bits are just values that are either 0 or 1
- Since an integer is a 4 byte value (usually) it
contains 32 bits - Each of those 32 bits can store a 0/1 value
- C provides bitwise operators, often used for
storing flags, or attributes, of an object - Bitwise not - negates each bit in an
expression - Bitwise and - "multiplies" each bit in one
expression with the corresponding bit in another
expression - Bitwise or - "adds" each bit in one with
corresponding bit in other - gtgt Bitwise shift right - Shifts each bit to the
right - ltlt Bitwise shift left - Shifts each bit to the
left
17Bitwise Operators, Example
const unsigned int ATR1 0x0001 //20 gt
0001 const unsigned int ATR2 0x0002 //21 gt
0010 const unsigned int ATR3 0x0004 //22 gt
0100 const unsigned int ATR4 0x0008 //23 gt
1000 printEnv(int env) //here, the is used
as a MASK cout ltlt "ATR1 " ltlt ((env
ATR1)?"on""off") ltlt endl cout ltlt "ATR2 " ltlt
((env ATR2)?"on""off") ltlt endl cout ltlt
"ATR3 " ltlt ((env ATR3)?"on""off") ltlt endl
cout ltlt "ATR4 " ltlt ((env ATR4)?"on""off") ltlt
endl int main(void) int e 0
//Initially empty environment e e ATR1
//Set attribute 1 e e ATR3 //Set
attribute 3 printEnv(e) e e
//Invert all attributes printEnv(e) e e
ATR2 //Clear attribute 2 printEnv(e)
return (0)
ATR1 on ATR2 off ATR3 on ATR4 off ATR1
off ATR2 on ATR3 off ATR4 on ATR1 off ATR2
off ATR3 off ATR4 on
18More Interesting Stuff
- Did you ever wonder why you could check for a
file being in fail state with just the name of
the object? - What is the "value" of an object (i.e. myfile, or
an object of a user-defined class)?
int main() ifstream myfile("in.txt") int
i int j myfile gtgt i gtgt j if
(!myfile) cout ltlt "myfile is in fail
state!" ltlt endl return (0)
19Conversion Operator
- An object doesn't not result in any value unless
you, the programmer, tell it what to evaluate to - You can do so via the special member functions
called "conversion operators" - Conversion operators have NO return type
- The name of the function is "operator lttypegt()
- To have your object evaluate to a boolean value,
implement the following member function - operator bool() //No return type!
- Even though there is no return type, this
function should return a value of type bool - Other conversion operators must return the
appropriate type - The fstream class has a boolean conversion
operator. - When the file is in fail state, the conversion
operator returns false, otherwise it returns true
20Conversion Operator, Cot'd
int main() IntClass ic1(13) IntClass
ic2(0) int x x 4 ic1 cout ltlt "x "
ltlt x ltlt endl cout ltlt "IC1 WAS " ltlt
(ic1?"TRUE""FALSE") ltlt endl cout ltlt "IC2 WAS
" ltlt (ic2?"TRUE""FALSE") ltlt endl
return (0)
class IntClass public IntClass(int
inVal)val(inVal) operator int()
return (val) operator
bool() return (val
0?falsetrue) private int val
x 17 IC1 WAS TRUE IC2 WAS FALSE