Jumping into C++ Chapter 13 Practice Prob No4 - Pointers - c++

I've having trouble understanding the wording of this question and what it means by returning the second value through a pointer parameter?
The problem is:
Write a function that takes input arguments and provides two seperate results to the caller, one that is the result of multiplying the two argumentsm the other the result of adding them. Since you can directly return only one value from a funciton you'll need the seecond value to be returned through a pointer or references paramter.
This is what I've done so far.
int do_math(int *x, int *y)
{
int i =*x + *y;
int u = *x * *y;
int *p_u = &u;
return i;
}
void caller()
{
int x = 10;
int y = 5;
std::cout << do_math(&x, &y);
//std::cout << *u;
}

I think all they're wanting you to do is to demonstrate your understanding of the difference between passing arguments by value and passing them by reference.
Here is a sample code that shows that although my function is only returning one value "i = X+Y", It is also changing the value of Y to (Y * X).
Of course if you do need Y's value to stay unchanged, you could use a third variable that is equal to Y's value and pass its reference as an extra argument to your function.
You could run the code bellow to see what's happening to X and Y before and after calling the function.
Hope this helps.
#include <iostream>
using namespace std;
int do_math(int value1, int *pointer_to_value2)
{
int i = value1 * *pointer_to_value2;
*pointer_to_value2 = *pointer_to_value2 + value1; // y changes here
return i;
}
int main( int argc, char ** argv ) {
int x = 10;
int y = 5;
cout << "X before function call " << x << endl;
cout << "Y before function call " << y << endl;
int product = do_math(x, &y);
cout << "X after function call " << x << endl;
cout << "Y after function call " << y << endl;
cout << "What the function returns " << product << endl;
return 0;
}

In the assignment there is written
Write a function that takes input arguments ...
So there is no any need to declare these input parameters as pointers.
The function could look like
int do_math( int x, int y, int &sum )
{
sum = x + y;
return x * y;
}
or
int do_math( int x, int y, int *sum )
{
*sum = x + y;
return x * y;
}
In these function definitions the sum and the product can be exchanged as the parameter and return value
As for me the I would write the function either as
void do_math( int x, int y, long long &sum, long long &product )
{
sum = x + y;
product = x * y;
}
or
#include <utility>
//...
std::pair<long long, long long> do_math( int x, int y )
{
return std::pair<long long, long long>( x + y, x * y );
}
void caller()
{
int x = 10;
int y = 5;
std::pair<long long, long long> result = do_math( x, y );
std::cout << "Sum is equal to " << result.first
<< " and product is equal to " << result.second
<< std::endl;
}
Edit: I would like to explain why this statement
std::cout << "sum is " << do_math(x, y, result) << " and result is " << result;
is wrong.
The order of evaluation of subexpressions and function argument is unspecified. So in the statement above some compilers can output value of result before evaluation function call do_math(x, y, result)
So the behaviour of the program will be unpredictable because you can get different results depending on using the compiler.
Edit: As for your code from a comment then it should look like
#include <iostream>
int do_math( int x, int y, int *p_u )
{
int i = x + y;
*p_u = x * y;
return i;
}
int main()
{
int x = 10;
int y = 5;
int u;
int i = do_math( x, y, &u );
std::cout << i << std::endl;
std::cout << u << std::endl;
}
Also take into account that in general case it is better to define variables i and u as having type long long because for example the product of two big integers can not fit in an object of type int.

The wording is kind of contrived but I believe the task asks you to
return the multiplication as the return value of the function, and
since you can't return two types at once (except if you wrap them up somehow), you should use a third parameter as a storage area for the sum:
#include <iostream>
/* Multiplication in here */ int do_math(int x, int y, int& result/* Addition in here */)
{
result = x + y;
return x*y;
}
int main() {
int x = 10;
int y = 5;
int addition = 0;
int multiplication = do_math(x, y, addition);
std::cout << "multiplication is " << multiplication << " and sum is " << addition;
}
Example
It's not specifically asking you to use two parameters for the function.

A typical solution to the intent of the exercise text…
” Write a function that takes input arguments and provides two seperate results to the caller, one that is the result of multiplying the two argumentsm the other the result of adding them. Since you can directly return only one value from a funciton you'll need the seecond value to be returned through a pointer or references paramter
… is
auto product_and_sum( double& sum, double const a, double const b )
-> double
{
sum = a + b;
return a*b;
}
#include <iostream>
using namespace std;
auto main() -> int
{
double product;
double sum;
product = product_and_sum( sum, 2, 3 );
cout << product << ", " << sum << endl;
}
This code is unnatural in that one result is returned while the other is an out-argument.
It's done that way because the exercise text indicates that one should do it that way.
A more natural way to do the same is to return both, as e.g. a std::pair:
#include <utility> // std::pair, std::make_pair
using namespace std;
auto product_and_sum( double const a, double const b )
-> pair<double, double>
{
return make_pair( a*b, a+b );
}
#include <iostream>
#include <tuple> // std::tie
auto main() -> int
{
double product;
double sum;
tie( product, sum ) = product_and_sum( 2, 3 );
cout << product << ", " << sum << endl;
}
As the second program illustrates, the last sentence of the exercise text,
” Since you can directly return only one value from a funciton you'll need the seecond value to be returned through a pointer or references paramter
… is just not true. I suspect the author had meant the word “directly” to clarify that this excluded the case of a non-basic type. But even so the conclusion is incorrect.

What you need to do is provide another parameter to the function - the pointer or the reference to the variable where you want to store your other result:
int do_math(int *x, int *y, int &res) //or int *res
{
...
res = *x * *y;
...
}
Then make a result variable in main and pass it to the function

Related

Pass by reference and type casting problems in c++

I am learning c++ and I come across problems in this program.
What I'm trying to do is to write a function computing max of 2 parameters x and y, each of type “reference to const double”. The function returns type “reference to double”. Return the entire conditional expression, type casting it as (double &) to override the “const" variable.
So I write this function in a file named "fmax.cpp"
double& fmax(const double &x, const double &y)
{
return (x > y) ? x : y; //Need type casting here?
}
I try to call the funciton in another file main.cpp
include <iostream>
using namespace std;
double& fmax(const double &x, const double &y);
int main()
{
const double &x; //should I put &x or x here?
const double &y; //should I put &y or y here?
cout << "enter 2 values" << '\n';
cin >> x >> y; //should I put & or no & here?
//Am I calling the function correctly?
cout << fmax(double &x, double &y) << '\n';
return 0;
}
Please advise how to write the program correctly.
This program should look like this:
#include <iostream>
double fmax(double x, double y) {
return x > y ? x : y;
}
int main()
{
double x;
double y;
std::cout << "enter 2 values" << '\n';
std::cin >> x >> y;
const auto res = fmax(x, y);
std::cout << res << '\n';
return 0;
}
There is no use to pass doubles (ints, floats and other small types) by references, because size of a memory address being passed is the size of the platform pointer (4 bytes on 32bits, 8 bytes on 64bits). Size of int is 4 bytes, for example.
I added const and auto as an example.
There are several defects in the code:
Only a function signature exists, but nowhere defined or linked any header file.
You don't need to use:
fmax(double &x, double &y)
// __^^^^^^_____^^^^^^____ errors
Used const qualifier when taken reference, it's usually used when the variable is guaranteed to not be changed anywhere in the code. You don't need to use a reference here.
Beware of using const when the program is going to alter the value of the variable. Otherwise, errors will be generated.
Code redefined:
fmax.h
double& fmax(const double &x, const double &y);
fmax.cpp
double& fmax(const double &x, const double &y) {
return (x > y) ? x : y;
}
main.cpp
#include <iostream>
#include "fmax.h"
int main(void) {
double x, y;
std::cout << "Enter 2 values: ";
std::cin >> x >> y;
std::cout << fmax(x, y) << '\n';
return 0;
}

if-else vs Ternary function call performance [duplicate]

This question already has answers here:
Ternary operator ?: vs if...else
(14 answers)
Closed 3 years ago.
In my C++ code, I have to select between two functions that take the same arguments based on a given condition. I could write:
if (condition)
return foo(a, b, c);
else
return bar(a, b, c);
Or:
return (condition? foo : bar)(a, b, c);
But which of these two ways is faster?
EDIT:
I tried to test using this code:
#include <cmath>
#include <chrono>
#include <iostream>
using namespace std;
void foo(float x, float y, int param)
{
pow(x+y, param);
}
void bar(float x, float y, int param)
{
pow(x+y, param);
}
int main() {
const int loops = 1000;
auto t1 = chrono::high_resolution_clock::now();
for(int i = 0; i < loops; i++)
for(int j = 0; j < loops; j++)
(i==j? foo : bar)(i, j, 2);
auto t2 = chrono::high_resolution_clock::now();
for(int i = 0; i < loops; i++)
for(int j = 0; j < loops; j++)
if(i==j)
foo(i, j, 2);
else
bar(i, j, 2);
auto t3 = chrono::high_resolution_clock::now();
cout << "ternary: " << (chrono::duration_cast<chrono::microseconds>(t2-t1).count()) << "us" << endl;
cout << "if-else: " << (chrono::duration_cast<chrono::microseconds>(t3-t2).count()) << "us" << endl;
return 0;
}
With the updated test code I got:
ternary: 70951us
if-else: 67962us
Migrated from comments:
Any decent compiler will output the same assembly for both. This is next-level premature optimization and something you shouldn't care about. Pick the one that is most readable and fits into your project style. —Sombrero Chicken
There is no problem with the performance. The compiler can generate the same object code for the both cases.
However there is a difference in applying these constructions.
For the conditional operator there must be deduced the common type of its second and third operands.
For example if you have the following functions
void foo( int, int, int ) {}
int bar( int, int, int ) { return 10; }
then you can use the if-statement as it is shown in the demonstrative program
#include <iostream>
void foo( int, int, int ) {}
int bar( int, int, int ) { return 10; }
int main()
{
int x;
std::cin >> x;
if ( x < 10 )
{
foo( x, x, x );
}
else
{
bar( x, x, x );
}
}
However you may not write as it seems an equivalent code
#include <iostream>
void foo( int, int, int ) {}
int bar( int, int, int ) { return 10; }
int main()
{
int x;
std::cin >> x;
x < 10 ? foo( x, x, x ) : bar( x, x, x );
}
because the compiler is unable to deduce the common type of the calls foo( x, x, x ) and bar( x, x, x ). The first one has the type void and the second one has the type int.
Of course you could write instead
x < 10 ? foo( x, x, x ) : ( void )bar( x, x, x );
but sometimes this makes code less readable when compound expressions are used. And moreover sometimes it is even impossible to deduce the common type because there is no explicit or implicit conversion between expressions especially for user-defined types.
Another example. You can write a function to allow the compiler to deduce its return type.
#include <iostream>
constexpr auto factorial( unsigned long long int n )
{
if ( n < 2 )
{
return n;
}
else
{
return n * factorial( n - 1 );
}
}
int main()
{
int a[factorial( 5 )];
std::cout << "The array has " << sizeof( a ) / sizeof( *a ) << " elements\n";
}
The program output is
The array has 120 elements
On the other hand, you may not write
#include <iostream>
constexpr auto factorial( unsigned long long int n )
{
return n < 2 ? n : n * factorial( n - 1 );
}
int main()
{
int a[factorial( 5 )];
std::cout << "The array has " << sizeof( a ) / sizeof( *a ) << " elements\n";
}
The compiler is unable to deduce the return type of the function.
So sometimes there is even no choice between whether to use the if-statement or the conditional expression:)

candidate function not viable: expects an l-value for 3rd argument

Calculate nth power of P (both p and n are positive integer) using a recursive function myPowerFunction(int p, int n, int &currentCallNumber). currentCallNumber is a reference parameter and stores the number of function calls made so far. myPowerFunction returns the nth power of p.
int myPowerFunction(int p, int n, int &z)
{
z++;
if(n==1)return p;
else if(n==0)return 1;
else if(n%2==0)return myPowerFunction(p,n/2,z)*myPowerFunction(p,n/2,z);
else return myPowerFunction(p,n/2,z)*myPowerFunction(p,n/2,z)*p;
}
int main()
{
cout << myPowerFunction(3,4,1);
}
You need a variable to pass as the third argument in main_program. You can't pass a constant as a non-const reference.
int count = 0;
std::cout << myPowerFunction(3, 4, count) << 'n';
std::cout << count << '\n';
Third parameter expects a lvalue, so you cannot pass numeric constant there, so possible solution can be:
int z = 1;
cout<< myPowerFunction(3,4,z);
or better to create a function that calls recursive one:
int myPowerFunction(int p, int n)
{
int z = 1;
return myPowerFunction(p,n,z);
}
In myPowerFunction(3,4,1) the literal 1 cannot be passed to a non const reference as it is a prvalue [basic.lval]. You need to store the value into a variable and then use that variable when calling the function.
int z = 0;
std::cout << myPowerFunction(3, 4, z);
You don't have to give a reference as parameter as many here state.
But yes, your input for z cannot be modified as it comes from read-only memory. Treat the input for z as const, copy z internally and give the copy as reference. Then your desired usage works:
int myPowerFunction(int p, int n, const int &z) // z is now const !
{
int _z = z + 1; // copy !
if (n == 1) return p;
else if (n == 0) return 1;
else if (n % 2 == 0) return myPowerFunction(p, n /2 , _z) * myPowerFunction(p, n / 2, _z);
else return myPowerFunction(p, n / 2, _z) * myPowerFunction(p, n / 2, _z) * p;
}
int main()
{
std::cout << myPowerFunction(3, 4, 1);
}

Returning and outputting 2 integers from 1 function

i have to write a code that has a function that takes two integers and returns x as (a + b) and y as (a * b) and when i run it, it only outputs y. Why doesnt it output (or return) x?
#include <iostream>
using namespace std;
int math (int a, int b) {
int x, y;
x = a + b;
y = a * b;
return x, y;
}
int main() {
cout << math (5,3);
getchar();
getchar();
return 0;
}
The return type of math is int, so this is what it returns (a single integer).
The expression x, y uses the comma operator. The comma operator evaluates x, discards its value, and then evaluates and returns y. In other words, return x, y is equivalent to return y.
You could use std::pair<int,int> to return a pair of integers.
The line
return x, y;
does not do what you expect. The comma operator returns only the value after the last comma - in this case, y. To return multiple values, you should use a struct or class containing both.
You can only return one thing. You can put those in a struct, and return it. Simpler example.
struct xy {
int x;
int y;
};
xy math(int a, int b) {
xy pair;
int x, y;
pair.x = a + b;
pair.y = a * b;
return pair;
}
There are two ways to make a function return more than one value. The
first is to use out parameters, either references or pointers:
void
math( int a, int b, int& sum, int& product )
{
sum = a + b;
product = a * b;
}
int
main()
{
int s;
int p;
math(5, 3, s, p);
std::cout << s << ' ' << p << std::endl;
return 0;
}
The other is to define a class to contain the two values:
struct MathResults
{
int sum;
int product;
};
MathResults
math( int a, int b )
{
return MathResults{ a + b, a * b };
}
std::ostream&
operator<<( std::ostream& dest, MathResults const& value )
{
dest << value.sum << ' ' << value.product;
}
int
main()
{
std::cout << math( 5, 3 ) << std::endl;
return 0;
}
In most cases, the second solution is to be preferred.

How do I properly pass these function values in C++

I am trying to write a program using functions that calculates county tax, sales tax, adds them together, and outputs them in main. I have also made a printData function so I could output everything at once but i'm confused on how to use it, because of an initialization error in run time. I am not very good with function and was hoping I could get some help.
Here is my written code: (updated)
#include <iostream>
using namespace std;
void calcCounty(double &TotalSales, double &CountySalesTax);
void calcState(double &TotalSales, double &StateSalesTax);
void calcTotal(double &TotalSales, double &CountySalesTax, double &StateSalesTax);
void printData(double &TotalSales, double &CountySalesTax, double &StateSalesTax);
double TotalSales;
double CountySalesTax;
double StateSalesTax;
int main()
{
cout << "Tax Calculation program" << endl;
cin >> TotalSales;
printData(TotalSales, CountySalesTax, StateSalesTax);
cout << TotalSales << CountySalesTax << StateSalesTax;
return 0;
}
void calcCounty(double &TotalSales, double &CountySalesTax)
{
CountySalesTax = TotalSales * 0.4;
}
void calcState(double &TotalSales, double &StateSalesTax)
{
StateSalesTax = TotalSales * 0.2;
}
void calcTotal(double &TotalSales, double &CountySalesTax, double &StateSalesTax)
{
TotalSales = CountySalesTax + StateSalesTax;
}
void printData(double &TotalSales, double &CountySalesTax, double &StateSalesTax)
{
cout << TotalSales, CountySalesTax, StateSalesTax;
}
Why don't you rather return a value from your functions?
double calcCounty(double& totalSales) {
return totalSales * 0.4;
}
Then in your main do:
countySalesTax = calcCounty(totalSales);
You need to initialize your variables first (the ones you need).
For example, this function:
void calcCounty(double &TotalSales, double &CountySalesTax)
{
CountySalesTax = TotalSales * 0.4;
}
should have TotalSales initialized before been called.
As suggested by the comments, you also need to call the functions at some point.
Moreover, the printing should be done like this in your case:
cout << TotalSales << ", " << CountySalesTax << ", " << StateSalesTax;
First, I would suggest you to read this example:
#include <iostream>
using namespace std;
/*
* Write a program, which will declare two variables, 'a' and 'b'.
* They will be initialized with the values 10 and 100, respectively.
* Write a function 'int find_min(int a, int b)`, which will find
* which of the given parameters is less and will return it.
*
* Then, write `void find_min_no_return(int a, int b, int& min)`,
* which will do the same job as `find_min()`, but with no return
* statement.
*/
int find_min(int a, int b) {
if(a < b) {
return a;
}
else {
return b;
}
}
/*
* 'min' is passed by reference because it is
* going to be modified. 'a' and 'b' are passed
* by value.
*/
void find_min_no_return(int a, int b, int& min) {
if(a < b) {
min = a;
}
else {
min = b;
}
}
int main() {
int a = 10;
int b = 100;
int min;
min = find_min(a, b);
cout << "min of first function called = " << min << endl;
find_min_no_return(a, b, min);
cout << "min of second function called = " << min << endl;
return 0;
}
and then solve your problem.