Calling a function in main - c++

I'm just learning C++ and I have a little code here:
using namespace std;
int main()
{
cout<<"This program will calculate the weight of any mass on the moon\n";
double moon_g();
}
double moon_g (double a, double b)
{
cout<<"Enter the mass in kilograms. Use decimal point for any number entered";
cin>>a;
b=(17*9.8)/100;
double mg=a*b;
return mg;
}
It compiles, but when I run it it only prints out:
This program will calculate the weight of any mass on the moon
but doesn't execute the moon_g function.

This line:
double moon_g();
doesn't actually do anything, it just states that a function double moon_g() exists. What you want is something like this:
double weight = moon_g();
cout << "Weight is " << weight << endl;
This won't work yet, because you don't have a function double moon_g(), what you have is a function double moon_g(double a, double b). But those arguments aren't really used for anything (well, they are, but there's no reason to have them passed in as arguments). So eliminate them from your function like so:
double moon_g()
{
cout<<"Enter the mass in kilograms. Use decimal point for any number entered";
double a;
cin>>a;
double b=(17*9.8)/100;
double mg=a*b;
return mg;
}
(And declare the function before you call it.) More refinements are possible, but that'll be enough for now.

This is a function declaration:
double moon_g();
this won't call a function, and if you did have it correct, which means adding two parameters since that is how you define it below:
moon_g( a, b ) ;
it would not work because you either need to move the definition of moon_g before main or add a forward declaration before main like this:
double moon_g (double a, double b) ;
Although it seems like a and b are not inputs but values you want to return back to main then you would need to use references and it would need to be declared and defined like this:
double moon_g (double &a, double &b) ;
^ ^
A useful thread to read especially if you are starting out would be What is the difference between a definition and a declaration?.
Which compiler you use makes a difference here clang provides the following warning:
warning: empty parentheses interpreted as a function declaration [-Wvexing-parse]
double moon_g();
^~
while I can not get gcc nor Visual Studio to warn me about this. It is useful in the long run to try code in different C++ compilers when you can, it can be a very educational experience and you don't have to install them either since there are plenty of online C++ compilers available online.

There is huge difference between calling a function and declaring it just as there is difference between local variables and function arguments.
I suggest reading basic tutorials first.
Anyway, thats how code should look like:
#include <iostream>
using namespace std;
double moon_g ()
{
double a,b;
cout<<"Enter the mass in kilograms. Use decimal point for any number entered\n";
cin>>a;
b=(17*9.8)/100;
double mg=a*b;
return mg;
}
int main()
{
cout<<"This program will calculate the weight of any mass on the moon\n";
cout<<"Result is: "<<moon_g();
}

There are two problems in your code.
Firstly, if you want to call your function
double moon_g (double a, double b) // this means if you want to call moon_g() you must provide arguments a and b, otherwise, the you will encounter an compile error.
{
cout<<"Enter the mass in kilograms. Use decimal point for any number entered";
cin>>a;
b=(17*9.8)/100;
double mg=a*b;
return mg;
}
you should provide the two parameters a and b.
But a and b are calculated in the body of function definition, it is unnecessary to declare the two parameters. You can write like this.
double moon_g () //this means function moon_g() does not accept any arguments
{
double a, b; // declare a and b in the definition body instead of in the arguments list
cout<<"Enter the mass in kilograms. Use decimal point for any number entered";
cin>>a;
b=(17*9.8)/100;
double mg=a*b;
return mg;
}
Then, in the main function, your calling function statement is wrong. You may want to receive the return value. So, you should write the code like this.
int main()
{
cout<<"This program will calculate the weight of any mass on the moon\n";
double ret = moon_g();
}
Finally, it is mostly recommended that the function which will be called by another function should be declared or defined previously.

Related

Problems with accessor and mutator functions of class

I'm trying to write a simple program that takes in a Kelvin temperature input from the user, and output the Farneheit and Celsius conversions of it. However, for a Kelvin input of 273.15, my program keeps outputting strange numbers like "6.95274e-310" for Farenheit and "4.6519e-310" for Celsius. I believe there is a problem with the accessor and mutator functions within the class, but I'm not quite sure what the issue is.
#include <iostream>
using namespace std;
class Temperature{
private:
double Kelvin;
double Celsius;
double Farenheit;
public:
void setKelvin(double);
void setCelsius();
void setFarenheit();
double getKelvin();
double getCelsius();
double getFarenheit();
};
void Temperature::setKelvin(double x){
Kelvin = x;
}
void Temperature::setCelsius(){
Celsius = Kelvin-273.15;
}
void Temperature::setFarenheit(){
Farenheit = (Celsius/(5.0/9))+32;
}
double Temperature::getKelvin(){
return Kelvin;
}
double Temperature::getCelsius(){
return Celsius;
}
double Temperature::getFarenheit(){
return Farenheit;
}
int main(){
cout<<"Enter a temperature in degrees Kelvin: ";
double y;
cin>>y;
Temperature K;
K.setKelvin(y);
cout<<"Temperature after converting to Celsius: ";
cout<<K.getCelsius();
cout<<"Temperature after converting to Farenehti: ";
cout<<K.getFarenheit();
}
Whenever you see weird values like this, it's very likely that these are uninitialized memory (aka garbage). It is data that was written by another application before and not been changed (initialized) by yours. That is why it's very important to always initialize variables.
Built-in types (int, char, double, etc) aren't initialized automatically: that is why you often see statements like int x(0);. Other objects, on the other hand, are initialized via the default constructor. This is why std::string str; doesn't create garbage: an empty std::string is created by std::string::string().
This behavior is clearly demonstrated in your program: Temperature::Celsius and Temperature::Farenheit are never initialized. An easy fix is to add the following lines after K.setKelvin(y):
K.setCelsius();
K.setFarenheit();
Alternative solutions may involve recalculating the Celsius and Farenheit values in their respective getters or systematically "synchronizing" them in the setKelvin method.

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.

Working of program in Function Overloading

I want to ask why this program does not generate a compile time error?
int Add(int x, int y){
return (x+y);
}
double Add(double x, double y, double z){
return (x+y);
}
int main()
{
cout<<Add(5,6);
cout<<Add(5.5,6.6);
return 0;
}
Add(5,6); calls int Add(int x, int y). That is clear enough.
Now Add(5.5,6.6) looks for a proper matching function. It finds one with two arguments and one with three. Now it checks if it can use the function with two arguments. And indeed it can convert double to int. So it again uses int Add(int x, int y).
If you would provide an double Add(double x, double y), it would find two functions with two arguments and checks which one "matches best". This would then be double Add(double x, double y).
Because C++ defines an implicit conversion from double to int, which gets applied in the second call.
See C++11[conv.fpint]ยง1:
A prvalue of a floating point type can be converted to a prvalue of an integer type. The conversion truncates; that is, the fractional part is discarded. The behavior is undefined if the truncated value cannot be represented in the destination type.
When you call
Add(5.5,6.6);
it gets mapped to function signature
int Add(int x, int y);
so, 5.5 -> 5 and 6.8 -> 6 conversion takes place
and you get the answer as 11 (5 + 6).
The solution comes down to the number of arguments:
For doubles you have
double Add(double x, double y, double z){
return (x+y);
}
this function requires only/exactly 3 variables before it will be utilised, so when you specify only 2 arguments, there is only one choice available:
int Add(int x, int y){
return (x+y);
}
Should you want to make it multi-purpose you would have to change it to
double Add(double x, double y, double z = 0.0){
return (x+y+z);
}
This will allow you to add 2 or 3 doubles together as needed, as 2 double added is the same as 2 doubles added to 0.0.
The argument for z (double z = 0.0) is simply a default value declaration: most compilers work on the basis that, working right to left on the parameter list you can omit parameters which have defaults, therefore I could do the following:
double Add(double x= 0.0, double y=0.0, double z = 0.0)
and each of the following would be valid calls:
Add();
Add(1.0);
Add(1.1,2.2);
Add(1.1,2.2,3.3);
Add(1);
Add(1,2);
Add(1,2,3);
And the values which we do not specify will be in place by utilising the default values we defined earlier (0.0).
Example usage of modified function
#include <iostream>
using namespace std;
double Add(double x, double y, double z = 0.0){
return (x+y+z);
}
int main() {
cout << Add(1.1,2.1,3.1) << endl;
cout << Add(2,3) << endl;
cout << Add(1.0, 2.12345) << endl;
return 0;
}
Hope this helps, but let me know if you need more information or detail :)
Guys this will generate a compile error 'Add' : no overloaded function takes 2 arguments You need three arguments for the ADD functions- both for int and double- to be utilized.
While I appreciate your answers on this, you must understand that function overload in C++ done like this requires exact number of parameters to be specified in the calling.
Visual Studio won't allow u to compile the above source code. Pass three arguments to the calling of functions in main function.
.
.
.
cout << Add(5,6,7) << endl;
cout << Add(5.5,6.6,2) << endl;
.
.
.

Compile Error: Function does not take 1 arguments

void displayCost();
double computeArea();
double roundCost();
int main()
{
return 0;
}
void displayCost(string name, int size)
{
double area = computeArea(size);
cout << "Since a " << size << "-inch pizza covers" << area << "square inches, "
<< name << ", then a 12 cents per square inch, the cost will be" << 12*area
<< " - which rounds to" << roundCost();
}
double computeArea(int size)
{
double radius = size/2;
double area = pi*radius*radius;
return area;
}
double roundCost(double price)
{
double roundedCost = ceil(price*100)/100;
return roundedCost;
}
It happens on the line at double area = computeArea(size);. I don't understand why it says I'm not passing an argument in when I clearly am.
double computeArea();
double area = computeArea(size);
double computeArea(int size) {
One of these things is not like the others, ...
You need to fix your prototype (the first one) to match the actual function:
double computeArea(int);
And, of course, ditto for the other prototypes as well.
You are messing up your forward declarations, they also have to reflect the type of parameters of your function.
void displayCost(string, int);
double computeArea(int);
double roundCost(double);
C++ differs from C in that a forward declaration of a function must specify the number and types of arguments. Whereas in C
double computeArea();
means that there is some function called computeArea that returns double, in C++ it is the same as
double computeArea(void);
That is, it specifies that computeArea takes no arguments.
Presumably the difference is because C++ allows functions to be overloaded, whereas C doesn't.
You've declared computeArea to take exactly zero arguments in the prototype (above main). The fact that you've then defined it to take a double down below is beside the point. Inside main, you're calling it with an argument, which, according to the prototype, is wrong.

Calling a function and taking one return out of multiple ones

I'm having a function which computes some averages of some values as inputs and the outputs are two ways of computing average: normal average and logarithmic mean.
void average_function(double nb1, double nb2, double &avr1, double &avr2)
{
....
}
in the main program: I just want to call just the first return, I mean, avr1, and I don't want to have the output avr2. I think if it's a pointer, you shall put to avr2=NULL but not in that case.
double avr1;
average_function(nb1, nb2, avr1, avr2)
Is there a way to output just avr1 in that situation? Or, I shall seperate the different average functions to two ones: one to return avr1 and the other to return avr2 (something that I really don't want to do).
You should separate these into 2 functions. And you should return results to the caller with (shockingly?) a return value...
double Average(double nb1, double nb2);
double LogarithmicMean(double nb1, double nb2);
I would definitely break it up in two functions, and have the average as the return parameter of those functions, such as:
double normalAverage(double nb1, double nb2);
double logarithmicMean(double nb1, double nb2);
...
double normalAvg = normalAverage(15.25, 99.12);
double logMean = logarithmicMean(15.25, 99.12);
There are solutions, none of which is particularly beatuiful (in fact I find both questionable). But for educational purposes:
You can make a functionally overloaded function that discards the 2nd parameter
void average_function(double nb1, double nb2, double &avr1, double &avr2)
{
....
}
void average_function(double nb1, double nb2, double &avr1)
{
double dummy;
average_function(nb1, nb2, avr1, dummy);
}
Further, if you define a global double value somewhere, you could use it as a default parameter:
static double dummy;
void average_function(double nb1, double nb2, double &avr1, double &avr2= dummy)
{
....
}
Passing the argument as pointer, and not computing the corresponding mean if it is nullptr is quite common and absolutely ok.
Design-wise, you should probably split the functionality into two functions, though. My response is based on your saying that you don't want to do this. The only reason you could have for keeping it in one function is if the amount of data to be processed is so large that it blows away the CPU caches, and it therefore would be desirable to only traverse once.
The & operator, when used in a function declaration, is the reference operator. It means that any parameters passed into your function are passed by reference, which means any changes made by the function to the value are kept after the function is concluded. (parameters passed into your function the normal way, by value, are effectively copied into the function; any changes the function makes will not apply to the outside value). A reference is not quite a pointer, which is why you can't pass it NULL.
The best choice is to separate the functions. It's best to make each function be supposed to do one "thing", and if there is a distinct thing to do, do it differently.
If you'd still like to use only one function, you can pass an invalid value to &avr2 (such as 0, if that is in fact invalid), and within the function whether it is 0 or not; if it is, perform the function operation that does not involve using &avr2. If it isn't 0, use &avr2.
void average_function(double nb1, double nb2, double &avr1, double &avr2)
{
if(avr2==0)
{
//non-avr2 option
} else {
//avr2 option
}
}