Title: CS304: Lecture 3
1CS304 Lecture 3
- Functions, Recursion, Arrays and Vectors
- Deitel, Ch. 6 and 7
- http//www.cis.uab.edu/cs304
2Things I Wont Cover That You Should Know!TM
- Recursion! Didnt you do this in CS302?
- Read 6.19-6.21, please!
3A Clarifying Note on Definitions
- Implementations of a function require variable
names in the argument list Prototypes do not!
Why? - class test int method1(int)int
method2(string, int) -
- int testmethod1(int intname)
- int testmethod2(string stringname, int intname)
4More on Prototypes
- Prototype Interface Definition
- Formal parameters in the prototype must conform
to the function signature (i.e. types must
match), but names of parameters are of no
importance
5Divide and Conquer
- Ideal way to construct large programs
- Manageability
- Simplicity
- Accomplished in many ways in C
- Functions
- Classes
- Libraries
- STL
6Prepackaged Functions
- Many common functions are provided for you
- Math
- String Parsing
- Time
- Containers
- Vector
- List
- Queue
- Algorithms
7Math
- include ltcmathgt
- All functions are global
- Most functions take doubles as arguments
- See page 242 for a list of common functions
8ltcmathgt functions
- ceil(x) rounds x to the smallest integer not less
than x - exp(x) exponential function ex
- fabs(x) absolute value of x
- floor(x) rounds x to the largest integer not
greater than x - fmod(x, y) remainder of x/y as a floating-point
number - log(x) natural logarithm of x (base e)
- log10(x) logarithm of x (base 10)
- pow(x, y) x raised to the power of y
- Complex numbers, too!
9We cant do math with floats? Or ints?
- Argument Coercion can adapt the math functions to
our uses. - This happens (largely) behind the scenes and
automatically - Square (4.5) 16
- Data could be lost in the conversion
- E.g., long to int, double to int.
- Promotion rules should be followed
- Hierarchy of data types (pp. 250)
- Explicit override can be given by casting
- Also applies to mixed-type expressions
10Other Header Files
- ltiostreamgt Standard I/O
- ltiomanipgt Functions for stream manipulation
- ltcmathgt Math functions
- ltcstdlibgt Mishmash! String/number conversion,
memory allocation, random numbers, etc. - ltctimegt Time functions
- ltvectorgt, ltlistgt, ltdequegt, ltqueuegt, ltstackgt,
ltmapgt, ltsetgt, ltbitsetgt Standard Template
Library ADTs - ltcctypegt Character functions (upper-lower
conversion, type tests) - ltcstringgt Contains C-style string processing
functions - ltexceptiongt, ltstdexceptgt Exception handling
classes - ltfstreamgt Functions for file I/O
- ltstringgt Contains C string class from STL
- See page 251 for a list of common functions
11Generate a Random Number Using the Standard
Library
- include ltiostreamgt
- include ltcstdlibgt
- include ltctimegt
- using namespace std
- int main()
- unsigned int seed
- cout ltlt "Enter seed, or 0 for time "
- cin gtgt seed
- srand((seed 0)?time(0)seed)
- cout ltlt "Your random number is " ltlt rand() ltlt
endl - return 0
12Want to generate specific numbers?
- Within a range, between at least start and less
than end - int number rand()(end-start)start
Only works for integers!!
Scaling Factor
Shifting Factor
Question given a random float number generator,
how to generate a float within a range?
13The Enum Datatype
- Have you ever done this?
- int first 0, second 1, third 2, nth
n-1 - int Sunday 0, Monday 1, , Saturday 6
- Use this instead!
- enum Numbers FIRST, SECOND, THIRD, , NTH
- enum Days SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY - This creates a datatype called (Numbers or Days)
that can hold one of the values contained (i.e.
FIRST, SECOND, MONDAY, etc. where appropriate).
This is NOT a class. - See Section 6.8 for this applied
14Storage Classes
- Storage classes are modifiers that change how the
memory associated with the variable behaves
within a function - There are five storage classes (auto, register,
extern, mutable, static), but we will discuss
three - auto Allocate the variable when it is declared,
deallocate it when it is no longer in scope.
This applies to local variables. - register Used with an automatic variable to
suggest to the compiler that this variable be
kept in a hardware register - static Used with global variables
(automatically) or local variables (explicit).
This causes a variable to retain its value
throughout the execution of the program.
Please read Section 6.9 for details!
15Scope
- Scope refers to where in a program a variable is
usable. - Alive ! usable e.g., you cannot use a static
variable defined inside of a function outside of
the function scope. - Six types of scopes Function, File, Block,
Function-Prototype, Class, and Namespace - File scope A static variable declared outside
of any class or function (or is a function!) - Function scope Known throughout a function, no
matter where declared (labels!) - Block scope A variable declared within
- Careful about hiding other variables!
- Function-Prototype scope Variables declared
within the parameter list - See Fig. 6.12 for a scope example
16Function Calls in C
- The C runtime environment can be described as a
stack LIFO structure. - Each function call is represented by an
activation record - Each record holds all information needed for that
particular instance of the function - Each time the function gets called, a new
activation record is added
17Activation Records Example On Board
- include ltiostreamgt
- using namespace std
- int square (int)
- int main() int a 10cout ltlt a ltlt squared
ltlt square( a ) ltlt endlreturn 0 -
- int square(int x) return x x
Read 6.11 for details, nice figure!
18Inline functions
- Function calls are slow!
- the call stack
- Function calls are good!
- e.g., reusable
- Inline function calls are fast and good!
- Acts as advice to the compiler to insert the
body of the function directly
19Cube function
- inline double cube (const double side) return
side side side -
- int main() cout ltlt cube(3.0) ltlt endl
- cout ltlt cube(4.0) ltlt endlreturn 0
20Turns to
- int main () cout ltlt 3.0 3.0 3.0 ltlt
endlcout ltlt 4.0 4.0 4.0 ltlt endlreturn 0
21Reference Parameters
- From our discussion of activation records, you
know that copies occur when parameters are passed
(a new local copy is created). - What if we want to make changes to the parameter
within the function call and keep the change
after leaving the function? - What if we dont want to copy whole structures?
- Passing classes?
22Passing an Argument by Reference
- Pass by value int funcall(int arg1)
- Pass by reference int funcall(int arg1)
- reference (or address-of) operator
- This requires no change to the body of the
function! - Use const modifier to prevent changes to the
structure - Why would we want to do this?
- References are first-class datatypes, and can be
used everywhere in a program
23Reference Example
- void makesquared (int num) num num
-
- int main() int num 3makesquarednum(num)cou
t ltlt num // output 3return 0
24Reference Example
- void makesquared (int num) num num
-
- int main() int num 3makesquarednum(num)cou
t ltlt num // output 9return 0
25Remember what Java does?
- Always pass-by-reference for Classes
- Always pass-by-value for primitive types, e.g.,
int - What if we want to pass two int values to a
function and keep the changes after the function
call is finished?
26Default arguments
- Specify a default argument this way
- int myfun(int x 0, int y 1, int z 2)
- Arguments that have a default should be rightmost
- Must have it make sense! (No ambiguity!)
- This is done in one place, typically the prototype
27Overloading Functions
- Specify different arguments (without conflicts,
of course). - int sqrt(int x)
- float sqrt(float x)
- double sqrt(double x)
- string sqrt(string x)
- int sqrt()
- What is different arguments?
- Number of parameters
- Type of each parameter
- Order of the parameters
? How about float sqrt()
28Templates
- Hate overloading every function for every
argument? - Generalize! Templates allow everything that
makes sense (more on this later in the course) - Our square root function written using templates
- templatelt class T gt
- T sqrt(T value)
- // Do some fancy calculations return answer
29- Arrays and Vectors
- Chapter 7
30Introduction
- Data Structures
- Collections of related data items
- Comparison between arrays and linked list
- The Simplest Data Structure The Array
- A consecutive group of memory locations that all
have the same type - Size is static from compile time
- Can be used as another kind of string
- The STLs Take The Vector
- Completely Dynamic (Resizable)
- Has all the advantages of the STL (e.g.,
object-oriented, templated, availability of
pre-programmed algorithms)
31Arrays
- Zero-indexed
- An array with n elements is addressed as a0,
a1, a2, , an-1, using only integers - Why? Memory offset (brief notes on pointers,
much more next week) - A subscripted element is an l-value (can be
assigned to)
32Declaration of Arrays
- Declaring an array allocates a swath of memory
equal to the size of the datatype times the
number requested. No more, no less. - type arrayName arraySize
- The type can be a primitive datatype, struct, or
class - arraySize must be an integer constant greater
than zero - Integer values 1, 2, 3
- variables declared as const int const int a
10 - Const variables read-only, must be initialized
- Javas equivalent to this? static final double PI
3.141592653589793 - Defined constants define x 30
Negative values? Compiler error 0? OK but useless
33The Static Array
- static int array100
- for (int n 0 n lt 100 n)
- cout ltlt arrayn
- //We have 0000000000000000000
- Its entries behave as static variables should
34Array initialization
- Only static arrays are automatically initialized
to zero when you declare it, non-static are not. - Using a loop to initialize an array
- Using initializer list
- int n2 1, 2 // Size of initializers
- int n1 1, 2 // Size lt of initializers
- Compilation error
- int n3 1, 2 // Size gt of initializers
- N2 is set to 0 automatically
- int n2 // no initializer
- All elements are initialized to 0
- Different with int n2 no initialization unless
its a static array - int n 1, 2 // no array size
- size of initializers
- int n // no initializer and no array size
- OK, but nonsense.
35Using an Array
- To take from this Always initialize!
- int main()
- int n10
- for (int i 0 i lt 10 i)
- ni 0
- cout ltlt Array initialized!\n
- return 0
36More Initialization Options
- You can use an initializer list!
- int main()
- int n 0,1,2,3,4,5,6,7,8,9
- // This declared n10 for you
- for (int i 0 i lt 10 i)
- cout ltlt ni ltlt ltlt endl
- //output will be 0 1 2 3 4etc.
- return 0
37Even More!
- Initialize everything to one value
- int main()
- int n10 0
- for (int i 0 i lt 10 i)
- cout ltlt ni ltlt
- //should output 0 0 0 0 0 etc.
- return 0
38Fibonacci Sequence!
- int main()
-
- int array50
- array0 array1 1
- cout ltlt Fibonacci Numbers 1-50\n
- for (int n 0 n lt 50 n)
- arrayn arrayn-1arrayn-2
- cout ltlt n ltlt \t ltlt arrayn ltlt endl
-
- return 0
39Char Arrays as Strings
- Im sure were all familiar with null-terminated
strings, correct? - \0 null character, int(\0) 0 (ASCII code)
- char string1 f,i,r,s,t,\0)
- char string1 first
- cin and cout will use these char arrays as
strings just like a string object - Why? C didnt have string classes (or classes at
all), so they had to do text processing somehow.
See ltcstringgt, or ltstring.hgt
40Print out the ASC II code
- include ltiostreamgt
- using namespace std
- int main()
- char a "first"
- for (int i 0 ilt 6 i) cout ltlt (int)ai
ltlt endl - return 0
-
41Passing Arrays Via Function Calls
- int sum(int array, int size)
- int sum
- for (int n 0 n lt size n)
- sum arrayn
- return num
-
- int main()
- array20
- // Fill the array here
- cout ltlt The sum of the entries ltlt
- sum(array, 20) ltlt endl
- return 0
42Multidimensional Arrays
- int a100200
- Think of this as an array of arrays (Obligatory
bad drawing on board goes here) - An m x n array has m rows, and n columns. It is
declared as arraymn.
43(No Transcript)
44What are the Arrays Limitations?
- We cant meaningfully compare two arrays for
equality - We cant assign one array to another, but must
manually iterate over elements (if they are even
the same size!) - Array names are simply const pointers!
- Statically allocated, so it cant grow with the
data - From the array itself, we dont know its size
It has to be tracked by the programmer
45Vectors let us do nice things
- Dynamic!!
- Two ways to declare a vector
- vector lt type gt nameofvector
- Allocates a zero-element vector
- vector lt type gt nameofvector(size)
- Gives a preallocated number of elements
- Several member functions
- Nameofvector.size() returns the number of
elements - Nameofvector.push_back(data) creates a new
element at the end of the current vector - Nameofvector.pop_back() removes the last element
- These can be indexed like a normal array
- But only if the element being indexed is
pre-allocated or put onto the vector