Functions - sheerazwalid/COMP-I GitHub Wiki
Functions that return void
A function is a named block of code that can be executed by calling the function. When you call a function, you pass in zero or more arguments.
The following illustrates the syntax of a function definition with a simple example.
// Define the print function.
void print(int x) {
cout << "The number is: ";
cout << x;
cout << endl;
}
int main() {
// Call the print function.
print(3);
cout << "Done." << endl;
return 0;
}
In the example above, the statement print(3)
calls the print function with the value 3. This causes the parameter x
to be assigned the value 3 and then execution goes to the first statement in the function. After all the statements in the function complete, execution returns to the calling code. The result for the above example is the following output.
The number is: 3
Done.
Functions that return values
The above example illustrates a void function, which is a function whose invocation does not result in a value, and therefore can not be used within an expression. To use a function in an expression, you need to return a value when exiting the function. The following illustrates this.
// Define the squareIt function.
double squareIt(double x) {
double xSquared = x * x:
return xSquared;
}
// Use the squareIt function in an expression.
int main() {
double radius = 4.0;
double area = pi * squareIt(radius);
return 0;
}
In the above example, the function squareIt is first defined, then it is used within the main function. In the main function, squareIt is used by "calling" it with squareIt(radius)
. The expression squareIt(radius)
evaluates 16, which is then used to evaluate the expression in which it appears, which would become pi * 16
.
Note that in the function definition, the function name is preceded by the datatype that is returned.
Default parameter values
void greet(string name = "friend") {
cout << "Hello " << name << endl;
}
int main() {
greet("Alice"); // Prints "Hello Alice"
greet(); // Prints "Hello friend"
return 0;
}
Pass by value versus pass by reference
Pass by value means copies of the function arguments are provided to the statements in the function. The following code illustrates this.
void doubleIt(int x) {
x = 2 * x;
}
int main() {
int x = 4;
doubleIt(x);
cout << x; // bad: prints 4
return 0;
}
In the above code, the statement inside doubleIt has no effect on the variable x in the calling code because it operates on a copy of that variable. Contrast this with the following.
Pass by reference means the function arguments name the same memory as the variables passed in. To pass by reference, precede the function parameter with an ampersand. The following code illustrates the syntax and the result.
void doubleIt(int & x) {
x = 2 * x;
}
int main() {
int x = 4;
doubleIt(x);
cout << x; // good: prints 8
return 0;
}
In the above code, the statement inside doubleIt operates on the same memory as the variable x used in the calling code.
const references
It's good programming practice to narrow the scope of things as much as possible. When we intend for a function to only use an argument without modifying it, we can declare that argument as const to convey this intention. This is illustrated in the following.
void greet(const string & name) {
cout << "Hi " << name;
}
int main() {
greet("Bob");
return 0;
}
The above greet function gets a reference to the string being passed to it, which is good practice because it conserves resources by avoiding making a copy of the string that would result from call by value. However, pass by reference opens up the potential for functions to modify the data unexpectedly. To avoid this possibility, we declare the argument as const. If someone accidentally introduces code that tries to modify name in the above code, the compiler will refuse to compile. For example, the following code will not compile.
void greet(const string & name) {
name = "Fred"; // ERROR: assignment to name not allowed.
cout << "Hi " << name;
}
Forward declarations
It's possible to define a function after you use it by using a forward declaration. The following illustrates this.
// Declare the print function.
void print(int x);
int main() {
// Call the print function.
print(3);
return 0;
}
// Define the print function.
void print(int x) {
cout << x;
}
Forward declarations are sometimes necessary and they also increase the options for organization of source code.
Reading
Optional Videos
- C++ functions for beginners, May 10, 2016
- 2016-07-11
- 2016-07-13 stop at 12m47s, this video covers reference parameters
- 2016-07-18 part A