* Comments * Functions A function takes any number of arguments, does something, then, optionally returns a value. * There are a number of predefined functions in C++ that you can use. #include #include int main() { float n, sqn; cout << "What num do you want to take the square root of? "; cin >> n; sqn = sqrt(n); cout << "sqrt(" << n << ") = " << sqn << endl; return 0; } * sqrt is a function that accepts one double argument and returns the square root of that argument as a double. * You can represent the function using the following syntax: double sqrt(double); * This is called a function prototype. * other predefined math functions in cmath: double pow(double, double); int abs(int); double fabs(double); double ceil(double); double floor(double); void exit(int); // void means the function doesn't return anything int rand(); // no arguments void srand(unsigned int); // unsigned means always positive, more range int x = -3; x = abs(x); // x = 3 srand(42); x = rand(); // x is some pseudo-random integer exit(0); // quits the program and returns 0. * How do we write our own functions? int abs(int x) { return x < 0 ? -x : x; } Must name parameters. Must return if function is not void. Use return command to return an expression of the type of the return type of the function. int max(int x, int y) { return x < y ? y : x; } void printXtoYincrZ(int x, int y, int z) { int i; for(i = x; i <= y; i +=z) { cout << i << endl; } } bool range(int a, int x, int y) { return (a >= x) && (a <= y); } x = max(5,6); printXtoYincrZ(1, 10, 2); if(range(5,1,10)) { } * You can still put a return statement in a void function, but you don't put an expression after it. It just quits the function. void printXtoYincrZ(int x, int y, int z) { int i; for(i = x; i <= y; i +=z) { if(i == 42) return; cout << i << endl; } } * Arguments are can only be seen in the function they are arguments for. * Variables declared in a function can only be seen in that function. * If you declare a variable outside of any function, it is called global. Any function can see and modify it. #include int x; void foo() { x = 5; } int main() { x = 3; foo(); cout << x << endl; return 0; } * Prints out 5. int bar(int y) { y = 2; } int main() { int x = 3; bar(x); cout << x << endl; return 0; } * prints 3 * functions normally copy the value of the argument to a new variable, so when you assign to it in the function, it assigns to the new variable. * Here is how you can write a function so that you can modify an argument: #include void foo(int& y) { y = 2; } int main() { int x = 3; foo(x); cout << x << endl; return 0; } * Prints out 2 now. void swap(int& x, int& y) { int t = x; x = y; y = t; } * Notice I've been putting main last. If call a function that is defined further down in the file, you'll get an error. In order to get that to work, you need to write out it's prototype first. #include void swap(int&, int&); int main() { int x = 2; int y = 3; swap(x, y); cout << x << " " << y << endl; return 0; } void swap(int& x, int& y) { ... } * function overloading - same function name, different parameters: double average(double x1, double x2) { return (x1 + x2) / 2.0; } double average(double x1, double x2, double x3) { return (x1 + x2 + x3) / 3.0; } * functions that have the same name must have the same return type. ILLEGAL: double average(double x1, double x2) int average(int x1, int x2) * they must differ by the number of parameters or the types of parameters. void add2(double& x) { x += 2.0; } void add2(int& x) { x += 2; } * ambiguous overloads will cause an error: void foo(int x, double y); void foo(double x, int y); if you call foo(2, 2), the compiler won't know which int to convert to double. * Default arguments, allow the caller to omit some arguments, but the arguments get a default value in that case: double calcVolume(int length, int width = 1.0, int height = 1.0) { return length * width * height; } int main { int x; x = calcVolume(2); // x = 2 x = calcVolume(3, 2); // x = 6 x = calcVolume(4,2,3); //x = 24 } * Functions can call themselves, this is called recursion. void foo() { foo(); } Infinite loop! fact(n) = n * fact(n - 1) fact(0) = 1 int fact(int n) { if(n == 0) return 1; else return n * fact(n - 1); } same with sum sum(n) = n * sum(n-1) sum(0) = 0 int sum(int n) { if(n == 0) return 0; return n * sum(n - 1); } fib(n) = fib(n-1) + fib(n-2); int fib(int n) { if(n == 0) return 1; if(n == 1) return 1; return fib(n-1)+fib(n-2); } Beware, this is much slower than using a loop. Why? every fib, is calculated many many times fib(9) fib(8)+fib(7) (fib(7)+fib(6))+(fib(6)+fib(5)) .... Recursive functions are often much more elegant than loops. Every loop can be written as a recursive function, and vice versa. void forloop(int init, int cond, int step) { if(init < cond) { .... forloop(init + step, cond, step); } return; }