Why can't Max be used as a function in this case? - c++

I just started C++ and I don't understand why Max cannot be used as a function in this case.
What I'm trying to do in this code is find the maximum number between the first one and the forth one, on any random number that only has 4 digits.
I've tried inserting Max to int, also to cin but it still does not work. any ideas on how to do it?
Thank you!
#include <iostream>
using namespace std;
int main()
{
int Max, a, b, c, d;
cin>>Max>>a>>b>>c>>d;
Max(a,b) = (a+b+abs(a-b))/2;
Max(b,c) = (b+c+abs(b-c))/2;
Max(c,d) = (c+d+abs(c-d))/2;
Max = (Max(a,b)+Max(b,c)+Max(c,d)+abs(Max(a,b)-Max(b,c)-Max(c,d)))/2;
}

There is some confusion, you'll need to study function syntaxes.
A variable declaration:
int Max;
The above declares a variable called Max.
A function declaration:
int Max(int a, int b);
The above declares a function, Max, which takes 2 int parameters: a and b.
A function definition could be:
int Max(int a, int b)
{
if (a > b)
{
return a;
}
return b;
}
For extra points, find the calculus formula for return the maximum value of 2 integers. :-)
Notes:
1. The above function can't be on the Left-Hand Side (LHS) of an assignment operation (it doesn't make sense, how would the function be assigned a value?).
2. The function returns a value. You should assign the value to a variable or print it:
int maximum = Max(3,15);
std::cout << "Maximum of 4, 24 is: " << Max(24,4) << "\n";

Related

Difference in the function return value and direct operation in cpp

I am not able to understand why the function (log_a_to_base_b) is returning a different value in comparison to the same operation if given with the input values in single line (Please refer below and code for much clearer explanation of problem)
-Basicaly why the function value and the variable x returned values are different
as function return type is INT and the x is also storing the answer in INT shouldn't both answer be same
If given the same value
The function value in the below code is coming as 3 while the x value in the below code is coming as 2
For refrence the log of 445943744 with base of 764 is 3
// C++ program to find log(a) on any base b
#include <bits/stdc++.h>
using namespace std;
int log_a_to_base_b(int a, int b)
{
return log2(a) / log2(b);
}
// Driver code
int main()
{
int a = 445943744;
int b = 764;
cout << log_a_to_base_b(a, b) << endl;
int x=log2(445943744)/log2(764);
cout<<x<<endl;
return 0;
}
// This code is contributed by shubhamsingh10, yousefonweb

Confirm Understanding about Pointers to Functions

As a C++ learner, I came across the following piece of code from C++ Language Tutorial and got two questions, could any expert provide some guidance on those?
#include <iostream>
using namespace std;
int addition (int a, int b)
{ return (a+b); }
int subtraction (int a, int b)
{ return (a-b); }
int operation (int x, int y, int
(*functocall)(int,int))
{
int g;
g = (*functocall)(x,y);
return (g);
}
int main () {
int m,n;
int (*minus)(int,int) = subtraction;
m = operation (7, 5, addition);
n = operation (20, m, minus);
cout <<n;
return 0;
}
In function "operation" definition:
Question 1: for "g = (*functocall)(x,y)", does it deference the pointer that points to a function (ex.subtraction) and assign it to g?
Question 2: for "return(g)", I'm wondering why we put parenthesis for g?
And for "int (*minus)(int,int) = subtraction;" in the main function, is that okay if we write the following instead?
int (*minus)(int,int)
minus = subtraction
Question 1: for g = (*functocall)(x,y), does it deference the
pointer that points to a function (ex.subtraction) and assign it to g?
Answer: No.
(*functocall)(x,y);
is simply one allowable syntax for invoking the function from the pointer passed as a parameter. It is entirely equivalent to:
functocall(x,y);
Which simply eliminates the (*...) syntax which is allowable but unnecessary.
Question 2: for return(g), I'm wondering why we put parenthesis for
g?
The parenthesis too are discretionary and are superfluous to the return. Simply providing:
return g;
is all that is needed as there is no expression requiring evaluation priority provided by the enclosing (..).
Before I start, your code uses way more parenthesis than it needs.
Here is the same code, better formatted and reduced:
#include <iostream>
using namespace std;
int addition (int a, int b)
{ return a+b; }
int subtraction (int a, int b)
{ return a-b; }
int operation (int x, int y, int (*functocall)(int,int))
{
int g;
g = functocall(x,y);
return g;
}
int main () {
int m,n;
int (*minus)(int,int) = subtraction;
m = operation (7, 5, addition);
n = operation (20, m, minus);
cout <<n<<"\n";
return 0;
}
for "g = (*functocall)(x,y)", does it deference the pointer that points to a function (ex.subtraction) and assign it to g?
In a nutshell - yes. When calling a function through it's pointer, it is not necessary to explicitly dereference it. I know, it's surprising and counter to the way pointers are typically used.
Think of it this way. Whenever you are just writing the name of a function, you are essentially getting the function's pointer. This is why you wrote as you did, rather than write:
m = operation (7, 5, &addition);
You do not need to explicitly dereference when using a function pointer for the same reason you do not need to explicitly use the address of operator when taking its address in the first place.
Question 2: for "return(g)", I'm wondering why we put parenthesis for g?
There is positively no good reason to. In fact, there is no reason to do it for any of your return statements.
And for "int (*minus)(int,int) = subtraction;" in the main function,
is that okay if we write the following instead?
int (*minus)(int,int);
minus = subtraction;
Personally, I recommend you use:
int (*minus)(int,int) = nullptr;
minus = subtraction;
so as not to leave uninitialized variables, but otherwise, yes, absolutely. A pointer to function variable is just like any other variable.

returning 2 values within a function

I am trying to return values (namely rows and columns) upon a file read, and since I will be reading in multiple files and getting the same variables from each file, I thought it will be better for me to write a function rather than copying and pasting duplicate codes.
Anyway, I am trying to return 2 values and to use them too, please see my code below:
#include <iostream>
#include <fstream>
using namespace std;
int r(string fn);
int main()
{
int a, b = r("input_a.txt");
cout << "a --- " << a << endl;
cout << "b --- " << b << endl;
}
int r(string fn)
{
ifstream fin01;
string file = fn;
fin01.open(file.c_str());
...
...
...
// Suppose I should be getting 2 for 'rows' and 3 for 'cols'
return rows, cols;
}
I got 0x7fff670778ec and 0x7fff670778e8 for my output instead...
Any pointers?
You cannot return two values from a function that is declared to have a single int as return type:
int r(string fn){
/*...*/
return rows,cols; // <-- this is not correct
}
Also the way you call this function is not behaving as you might expect:
int a, b = r("input_a.txt");
this declares two integers and initializes the second one with the return value of the function, but the first one stays uninitialized (see TerraPass answer for more explanation on the comma operator).
You basically have two options. First option is to pass references to the function and the function assigns the results to those references:
void r(string fn, int& rows,int& cols) {
/*...*/
rows = x;
cols = y;
}
and you call it like this:
int a,b;
r("someString",a,b);
However, in this way the caller has to "prepare" those return values. Imho it is more convenient to use the return value to return results from a function (sounds logical, no?). To do this you just have to define a type that encapsulates the two integers:
struct RowAndCol { int row;int col; };
RowAndCol r(string fn) {
/*...*/
RowAndCol result;
result.row = x;
result.col = y;
return result;
}
and call it like this:
RowAndCol rc = r("someString");
Note that you could also use a std::pair<int,int> instead of defining your custom struct (see e.g. molbdnilos answer). However, IMHO whenever you know exactly what is contained in the pair, it is better to give it a reasonable name (e.g. RowAndCol) instead of using a naked std::pair<int,int>. This will also help you in case you need to add more methods to the struct later (e.g you might want to overload the std::ostream& operator<< for your struct to print it on the screen).
PS: Actually your output does not look like it was produced by the code you are showing. Theses are some memory addresses, but in your code there is neither a pointer nor an address-of operator.
I guess you're used to Python (I peeked at your profile), but the comma does not create a pair in C++.
(You may not have thought about it that way, but you can only return one value from a Python function, too. If you "return two values", you're returning one pair.)
Fortunately, there are tuples in the standard library.
#include <iostream>
#include <fstream>
#include <utility>
std::pair<int,int> r(std::string fn);
int main()
{
std::pair<int, int> result = r("input_a.txt");
cout << "a --- " << result.first << endl;
cout << "b --- " << result.second << endl;
// Or,
int a = 0;
int b = 0;
std::tie(a, b) = r("input_a.txt");
cout << "a --- " << a << endl;
cout << "b --- " << b << endl;
}
std::pair<int, int> r(std::string fn)
{
std::ifstream fin01(fn);
// ...
return std::make_pair(rows, cols);
}
Functions in C++ cannot return multiple values of their return type via a return statement.
int a, b = r("input_a.txt");
...
return rows, cols;
These 2 lines don't do what you think they do.
The line int a, b = r("input_a.txt"); is equivalent to:
int a;
int b = r("input_a.txt");
That is, you declare variables a and b and initialize b to the return value of r("input_a.txt"), while a remains uninitialized.
The line return rows, cols; is equivalent to:
rows;
return cols;
...and is an example of comma operator, which evaluates its left operand (in your case, rows), discards the result, then evaluates its right operand (in your case, cols) and returns the result of this evaluation. So, in effect, your function r(), as it is now, always returns a single value, cols.
If you need to return more than one value from a function, you should consider accepting additional arguments as non-const references for you to store resulting values to, or changing the return type of your function to some struct, which would contain all of the values you want to return. You can find an example of both these approaches in #tobi303's answer.

xcode is not showing the output

I tried several time to find where is the problem, but I can not find any thing.So, could anyone help me to find the problem and why I can not see a result?
It might seem stupid question, but I new to programming world :)
This is my code :
#include <iostream>
using namespace std;
// There is the declraction of all functions
float max();
float min();
// This is the main program
int main ( int argc, char ** argv )
{
// Here you can find max
max(504.50,70.33);
// Here you can find min
min(55.77, 80.12);
return 0;
}
// This is the max function
int max(float a, float b){
float theMax;
if (a>b) {
theMax = a;
cout <<theMax ;
}
else{
theMax = b;
cout << b;
}
return theMax;
}
// This is the min function
int min( float c, float d){
float theMin;
if (c >d ) {
theMin =c;
cout << theMin;
}
else {
theMin =d;
cout << theMin;
}
return theMin;
}
You're calling std::max and std::min. That's because you wrote using namespace std, and did not declare your own min and max prior to using them. (You did declare two other min and max functions, but those take zero arguments, not two). So, when the compiler sees max(504.50,70.33); the only candidate is std::max.
You declare these overloads:
float max();
float min();
which are functions that take no arguments and return float.
You're calling
max(504.50,70.33);
and
min(55.77, 80.12);
which are functions that takes two doubles and may or may not return anything.
These match std::max and std::min, not the prototypes you declared.
You then define
int min( float c, float d){
which also doesn't match the prototypes you declared.
In other words, these functions are unknown in main, and the functions that are actually called are std::min and std::max.
Don't use using namespace std; - what you save in typing is lost in clarity and debugging.
You should also rename the functions - it's not a good idea to reuse standard library names.

C++ Defining Global Variable

Very simple question:
I was fiddling with basic C++ (being very new to programming) and I got into trouble while declaring a global variable to do some addition
#include <iostream>
int x,y;
int sum(int, int)
{
return x + y;
}
int main()
{
using namespace std;
cout << "The sum of 10 and 4 is: " << sum(10,4) << endl;
return 0;
}
Changing "int x,y;" to "int x,y = 0" has the same result: The sum equates to 0.
Could someone explain this odd behavior? Thanks!
Your function always returns the sum of global variables x and y, which are always 0. x and y are implicitly set to zero at the program startup. You never change their values, so they remain zero forever. The sum of two zeros is zero, no surprise here.
You pass 10 and 4 to your function, but the function itself completely ignores what is passed to it, i.e. it ignores its parameters (they are not even named). It always sums global x and y, which are always 0.
If you want your function to sum its arguments, you have to name the function parameters and use them
int sum(int a, int b)
{
return a + b;
}
And now you don't need any global variables at all. (main remains as is.)
Alternatively, if you so desire, you can get rid of the parameters completely and sum the global variables instead
int x,y;
int sum()
{
return x + y;
}
but in this case you will have to pass the values to sum through those global variables, not as function arguments
int main()
{
using namespace std;
x = 10;
y = 4;
cout << "The sum of 10 and 4 is: " << sum() << endl;
return 0;
}
This latter approach is here just for illustrative purposes. It is definitely not a good programming practice.
What you have in your code is a weird disconnected hybrid of these two approaches, which can't possibly work.
In order to fix the issue, the thing requires changing is the sum function.
int sum(int a, int b){
return a+b; //a,b here are referring to the inputs, while what you did was referring to the global variable..
}
Besides, try not to use global variables, usually you would end up with lots of troubles.
Another thing, I don't think your way of defining a function is correct. The inputs have to look like this instead:
int sum(int a, int b)
Unless you wanna declare the function first and provide the actual implementation later, you are not suppose to miss the name of the inputs!
when you are just globally declare the variables x,y ,they implicitly set to zero value.in your function definition,you are just giving the datantype of args, not the args names.so when you returning the sum of x,y ,it returns zero.and the value passed by the main function goes nowhere.
your program must look like this
#include<iostream>
int x,y;
int sum(x,y)
{
return x+y;
}
int main()
{
int v,a,b;
cout<<"values of a and b";
cin>>a>>b;
v=sum(a,b)
cout<<"their sum is"<<v;
}
when you explicitly define the value in second case
i.e int x,y=0;
you are just explicitly giving the value of value y to 0 while the x implicitly remains 0 and since you are not giving the args name,the ultimately result return biy the function is zero,
Seems that you only need x and y inside your add function, so make them local to the function. There is no reason to make them global. Follow the "least accessibility" idiom to prevent other parts of your program from mistakenedly modifying variables.
You might need a global variable supposed you want to define a well known parameter that every function needs to know and yet modifiable during run time. If you want it fixed, then a global constant would be more proper.
Hope that helps.