#include // In this exercise, we will compare two functions // that accomplish exactly the same task: // // 1. One takes a reference to an integer. // 2. The other takes a pointer to an integer. // // Both functions: // // - Save the original value of an integer. // - Set that integer to zero. // - Return its original value. // // Before running this program, predict the // four values that will be printed. // // Recall the following notation: // // IN A DECLARATION // // int &a{ m }; // // The variable a is a reference to m. It is // another name, or alias, for the same integer. // // int *p_a{ &m }; // // The variable p_a is a pointer to an integer. // It stores the address of m. // // IN AN EXPRESSION // // &m // // This is the address of m. // // *p_a // // This is the integer stored at the address // held by p_a. This operation is called // dereferencing the pointer. // // In particular: // // *p_a = 0; // // changes the integer that p_a points to. // // Exercise: // // Write one sentence describing what each // of the two functions does. Explain how // the functions differ in their parameters // and in the arguments passed to them. // // Solutions appear below. // Function declarations int reset( int &a ); int reset_p( int *p_a ); int main(); // Function definitions int main() { int m{ 42 }; int n{ 91 }; // Predict the output before running // the program. std::cout << reset( m ) << std::endl; std::cout << m << std::endl; std::cout << reset_p( &n ) << std::endl; std::cout << n << std::endl; return 0; } int reset( int &a ) { int const tmp{ a }; a = 0; return tmp; } int reset_p( int *p_a ) { int const tmp{ *p_a }; *p_a = 0; return tmp; } // Hint: // // In the call // // reset( m ); // // the parameter a becomes another name for m. // // Therefore, assigning // // a = 0; // // also changes m. // // In the call // // reset_p( &n ); // // the parameter p_a receives the address of n. // // Therefore, assigning // // *p_a = 0; // // changes n. // // Notice that neither function changes its // parameter to refer or point to a different // integer. Both change the original integer. // The output is: // // 42 // 0 // 91 // 0 // // The first function returns the original // value of m and then m is printed after // it has been reset. // // The second function does the same for n. // Explanation of the two functions: // // // 1. Resetting through a reference // // int reset( int &a ) { // int const tmp{ a }; // a = 0; // return tmp; // } // // The parameter a is a reference to the integer // passed as an argument. // // In the call reset(m), a is another name for m. // // The local variable tmp is initialized with // the original value of m. // // Assigning zero to a also assigns zero to m, // because a and m refer to the same integer. // // Finally, the function returns the original // value saved in tmp. // // // 2. Resetting through a pointer // // int reset_p( int *p_a ) { // int const tmp{ *p_a }; // *p_a = 0; // return tmp; // } // // The parameter p_a is a pointer to an integer. // // In the call reset_p(&n), the argument &n // supplies the address of n. // // The expression *p_a accesses the integer // stored at that address. // // The local variable tmp saves its original // value. Assigning zero to *p_a then changes // the integer at that address. // // Finally, the function returns the original // value saved in tmp. // // The pointer must point to a valid integer. // In particular, passing nullptr to reset_p // would result in undefined behavior when // the function attempts to dereference it. // Additional experiment: // // Consider the following function: // // void reset_pointer( int *p_a ) { // p_a = nullptr; // } // // If you call // // int m{ 42 }; // int *p_m{ &m }; // // reset_pointer( p_m ); // // what happens to p_m and m? // // Answer: // // Neither changes. // // The pointer parameter p_a receives a copy // of the address stored in p_m. // // Assigning nullptr to p_a changes only that // local copy. It does not change p_m, and it // does not change m. // // This is different from // // *p_a = 0; // // which changes the integer at the address // stored in p_a.