Insight 12.5.1.
Functions should take input via parameters. They should return results via return values. All โcommunicationโ with the rest of the program should happen through these mechanisms.
calculateTriangleArea(side1, side2, side3), it is pretty clear that the function is going to calculate the area of a triangle with those three sides. We could write a version of that function that instead uses global variables to store the data needed:
// global variables - BAD, BAD, BAD!!!!
double side1, side2, side3;
double area;
void calculateTriangleArea() {
// I hope someone set these...
double s = (side1 + side2 + side3) / 2;
// We'll just put the answer in area and hope the caller knows to look for it
area = sqrt(s * (s - side1) * (s - side2) * (s - side3));
}
int main() {
cout << "Enter the length of the first side of the triangle: ";
cin >> side1;
cout << side1 << endl; // echo the input
cout << "Enter the length of the second side of the triangle: ";
cin >> side2;
cout << side2 << endl; // echo the input
cout << "Enter the length of the third side of the triangle: ";
cin >> side3;
cout << side3 << endl; // echo the input
calculateTriangleArea();
cout << format("The area of the triangle to one decimal is: {:.1f}", area) << endl;
}
calculateTriangleArea() on line 24, it is completely unclear what data is going to be worked on. This function communicates with the rest of this program via the secret back channel of global variables. The caller has to know that they need to set the special variables side1, side2, and side3 before calling the function. And they need to know that the result will be stored in the global variable area.
double area = getTriangleArea(side1, side2, side3);
getTriangleArea(3, 4, 5) is pure because it always produce the same answer: 6.0. Furthermore, calling the function will not change the behavior of anything else in the program.
getTriangleArea() that relies on global variables again. We canโt predict the answer without knowing what value global variables have. Its behavior thus relies on the overall state of the program (whether or not other code set the global variables). Furthermore, the function changes a global variable, which may cause non-obvious changes to the behavior of code that comes after it.
double calculateTriangleArea(double side1, double side2, double side3) are inherently more modular than functions that rely on global state or side effects. Changes to other code canโt affect the behavior of this version of calculateTriangleArea unless they change the parameter values passed into a call. And calling the function canโt change the behavior of other code.
// Take a constant reference
string capitalize(const string& s) {
string copy = s; //copy the original string
for(char& c : copy) {
c = toupper(c);
}
return copy;
}
string copy = capitalize(original);
void capitalize(string& s) {
// loop through the original string and modify it
for(char& c : s) {
c = toupper(c);
}
}
capitalize(original);
capitalize(original);, a reader canโt necessarily tell that the original string is being modified.