These are the requirements for my program. Code a program that will find the minimum, maximum, and sum of two integers and of three integers. Use 1 overloaded function for each of min, max, & sum. I have gotten most of it done, but dont know how to add an overload function. here is my code
#include <iostream>
using namespace std;
int main(){
int num1, num2;
cout<<"Enter first number: ";
cin>>num1;
cout<<"Enter second number: ";
cin>>num2;
cout<<"Sum of " << num1<< " and " <<num2<<" is: "<<(num1+num2)<<endl;
if (num1>num2)
{
cout << "The max is " << num1<< " and the min is " << num2<< endl;
}
else
{
cout<< num2 << " is the max, and " <<num1 <<" is the min"<<endl;
}
return 0;
}
The idea here is to separate the code into functions, and more specifically, to two different functions, with the same name, but with a different parameters (this means that this function has a different signature, and this is how the compiler distinguish one function to another!).
The code should look like that:
int add(int a, int b)
{
return a + b;
}
int add(int a, int b, int c)
{
return a + b + c;
}
int max(int a, int b)
{
return (a > b) ? a : b;
}
int max(int a, int b, int c)
{
return max(a, max(b, c));
}
Notice the little "trick" (which is recommended), that I have used the 2-argument max in the 3-argument max, instead of re-implement the same logic twice. In this way, if you have a bug, you will have a bug in both, but if you fix it, it will be fixed in both at the same time. This is true for many other type of functions!
Also, denote the (expression) ? (value_1) : (value_2) which is a short version for if assignment, which can be used when assigning variables or when returning a value, and are in common use.
P.S you can make in such a way an overload for any number of arguments, and for any type that has the operator< (although it does contain a problem, if the arguments are not from the same type!), using:
template <typename T>
T max(T a, T b)
{
return (a > b) ? a : b;
}
template <typename T, typename... Ts>
T max(T a, Ts... others)
{
const T max_of_others = max(others...);
return (a > max_of_others) ? a : max_of_others;
}
int main()
{
std::cout << "max of 1-6 is: " << max(1, 6, 3, 4, 5, 2) << std::endl;
}
But it is an overkill here! (just good to know for the future!)
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I'm writing a program that finds the roots of a quadratic equation using exception handling and i'm wondering if there's a way I can simplify the program, I have a bunch of empty classes for the catch cases
// Program to solve quadratic equation
#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;
class all_zero{
};
class negative{
};
class zero_division{
};
void roots(double a, double b, double c) throw (all_zero,negative,zero_division);
int main(){
double a, b, c; // coefficient of ax“2 + bx + c= 0
cout << "Enter the three coefficients \n";
cin >> a >> b >> c;
try
{
roots(a, b, c);
}
catch(all_zero) {cout << "All values are zero \n";}
catch(negative) {cout << "Square root of negative values is not defined \n";}
catch(zero_division) {cout << "Division by zero, not defined \n";}
return 0;
}
void roots(double a, double b, double c) throw (all_zero,negative,zero_division){
double x1, x2; // The two roots
double temp;
if(!(a== 0 && b== 0 && c==0)){
if(a != 0){
temp = b*b - 4*a*c;
if(temp >= 0){
x1 =(-b + sqrt(temp))/2*a;
x2 = (-b - sqrt(temp))/2*a;
cout << "The two roots are: "<< x1 <<" and " << x2 << endl;
}else{throw negative();}
}else{throw zero_division();}
}else{throw all_zero();}
}
Is there a way I can make it so i dont have just empty classes or a way to put them into maybe a struct?
Note that the dynamic excpetion specification you are using is deprecated in C++11 and removed in C++17:
void roots(double a, double b, double c) throw (all_zero,negative,zero_division)
// ^^
You can just remove it.
using namespace std; is considered bad practice.
Do not use std::endl to add a newline. std::endl adds a new line and flushes the stream. Most of the time this is unnecessary. Use '\n' to add a newline.
Is there a way I can make it so i dont have just empty classes or a way to put them into maybe a struct?
Actually, I don't see the bad about having seperate classes for the different types of exceptions. The downside of your approach is that the "what" is in the catch, not part of the exception or coming from where the exception occured. I'll show you the first (message is part of the type) and hope you will see how to realize the latter (message is from where the exception is thrown).
You can inherit from std::runtime_error which offers a what() method that returns a string passed to the constructor. This also makes it easier for others to catch your exceptions, because std::runtime_error in turn inherits from std::excpetion which is the base class of all standard exceptions:
// Program to solve quadratic equation
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <stdexcept>
struct all_zero : std::runtime_error {
all_zero() : std::runtime_error("All values are zero") {}
};
struct negative : std::runtime_error {
negative() : std::runtime_error("Square root of negative values is not defined") {}
};
struct zero_division : std::runtime_error {
zero_division() : std::runtime_error("Division by zero, not defined") {}
};
void roots(double a, double b, double c);
int main(){
double a, b, c; // coefficient of ax“2 + bx + c= 0
std::cout << "Enter the three coefficients \n";
std::cin >> a >> b >> c;
try
{
roots(a, b, c);
}
catch(std::runtime_error& ex) {std::cout << ex.what() << '\n';}
return 0;
}
void roots(double a, double b, double c) {
double x1, x2; // The two roots
double temp;
if(!(a== 0 && b== 0 && c==0)){
if(a != 0){
temp = b*b - 4*a*c;
if(temp >= 0){
x1 =(-b + sqrt(temp))/2*a;
x2 = (-b - sqrt(temp))/2*a;
std::cout << "The two roots are: "<< x1 <<" and " << x2 << "\n";
}else{throw negative();}
}else{throw zero_division();}
}else{throw all_zero();}
}
Live Demo
Note that exceptions should be catched as reference, otherwise there will be object slicing when the exception is derived. And as in general you don't know what type of exception you will catch, you need to be careful to avoid that.
Alternatively you could use a more general exception type (roots_exception?) and instead of hardcoding the "what" pass it to the constructor when you throw it.
There is probably more you can improve, for which I suggest you https://codereview.stackexchange.com/.
PS: I tried to keep style aside, though one more thing you should change is to return the result from the function, instead of just printing it to the screen. If you want to use the result for other calcualtions you currently cannot. Perhaps you were puzzled how to return two values. std::pair makes that simple:
std::pair<double,double> roots(...) {
// ...
return {x1,x2};
}
and then:
try {
auto result = roots(a,b,c);
std::cout << "The two roots are: "<< result.first <<" and " << result.second << "\n";
}
My input:
Make sure the formula is correct. The /2*a part should be /(2*a).
Define an error category for your solver's errors and inherit more specific errors from that.
Remove unnessary tests (a== 0 && b== 0 && c==0). You already check if a == 0, so if a != 0 but b and c are, the solution will be 0, which should be valid.
Reverse the tests to not have to throw in an else. Throw early to not have deep nested if's.
Return the result, don't print it. I've added tweaks to make it possible to solve linear and complex equations too (in comments), but you can skip that if you want. This shows how you can return multiple values though.
Don't do forward declaration unless you really have to.
Read Why is using namespace std; considered bad practice?
More details in comments in the code
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <stdexcept>
#include <tuple> // std::tuple - used for returning multiple values here
struct solver_error : std::runtime_error { // your solver's error category
using std::runtime_error::runtime_error;
};
struct unknown_error : solver_error {
unknown_error() : solver_error("x is unknown") {}
};
struct linear_error : solver_error {
linear_error() : solver_error("cant solve linear equation") {}
};
struct complex_error : solver_error {
complex_error() : solver_error("cant solve complex equation") {}
};
// add more exceptions to the solver_error exception category if needed
// now returns two values and a bool to indicate if the solution is complex
std::tuple<double, double, bool> solve_for_x(double a, double b, double c) {
if(a == 0) throw linear_error(); // throw early
/* ... or solve it as a linear equation:
if(a == 0) {
if(b == 0) throw unknown_error(); // both a and b == 0, x is unknown
double res = -c / b;
return {res, res, false}; // only one x and not complex
}
*/
double div = 2 * a;
double temp = b * b - 4 * a * c;
if(temp < 0) throw complex_error();
/* ... or solve it as a complex equation
if(temp < 0) {
double sqr = sqrt(-temp); // sqrt of the positive temp instead
return {-b / div, sqr / div, true}; // real, imaginary and complex==true
}
*/
// real quadratic
double sqr = sqrt(temp);
double x1 = (-b + sqr) / div; // corrected formula (div = 2*a)
double x2 = (-b - sqr) / div; // corrected formula
return {x1, x2, false}; // return the two values and complex==false
}
int main() {
// make the user aware of what the coefficients are for
std::cout << "Enter the three coefficients a, b and c in the equation\n"
"ax^2 + bx + c = 0\n";
double a, b, c;
try {
// check that extracting the numbers succeeds
if(not(std::cin >> a >> b >> c)) throw std::runtime_error("input error");
// get the three return values via structured bindings
auto [first, second, complex] = solve_for_x(a, b, c);
std::cout << "x = ";
if(complex) // complex quadratic
std::cout << first << " ± " << second << 'i';
else if(first == second) // linear
std::cout << first;
else // real quadratic
std::cout << '{' << first << ',' << second << '}';
std::cout << '\n';
} catch(const solver_error& ex) {
// catching the generic error category by "const&"
std::cerr << "Solver error: " << ex.what() << '\n';
return 1;
} catch(const std::runtime_error& ex) {
std::cerr << ex.what() << '\n';
return 1;
}
}
I'm writing a rather simple program following Euclidean algorithm (we have to write it using recursion). It works really well when executed in C++ Tutor but when I compile the program in the terminal, it already gives me:
warning: control may reach end of non-void function [-Wreturn-type]
When I try to execute it in the terminal, it throws:
runtime error: execution reached the end of a value-returning function without returning a value
(But I am returning a value?)
Why does it work with c++ tutor but not in the Linux terminal (using clang compiler)?
I tried to use a bunch of extra variables in the function to make the process clearer to me, but I still don't get why it thinks that there would be a case where I would not return a value.
#include <iostream>
using namespace std;
int ggt(int a, int b){
int rest{0};
int zaehler{0};
int divisor{0};
if(a>=b){
zaehler=a;
divisor=b;
if(a%b==0){
return b;
}
else{
rest=a%b;
divisor=rest;
zaehler=b;
ggt(zaehler, divisor);
}
}
else{
zaehler=b;
divisor=a;
if(b%a==0){
return a;
}
else{
rest=b%a;
divisor=rest;
zaehler=a;
::durchlaeufe--;
ggt(zaehler, divisor);
}
}
}
int main(){
int a{40}, b{12};
cout << "Bitte Zaehler eingeben: ";
cin >> a;
cout << "\n";
cout << "Bitte Nenner eingeben: ";
cin >> b;
cout << "\n";
if(ggt(a, b)==0){
cout << "ERROR\n";
}
else {
cout << "Der groesste gemeinsame Teiler ist: " << ggt(a, b) << "\n";
}
return 0;
}
In this example, with a=40 and b=12, the result should be 4. And that's exactly what C++ tutor says...
the actual answer (missing return at recursion call) was already given.
i'd like to add a simpler version for you to compare and maybe learn something :)
int ggt(int a, int b)
{
if (a < b)
{
std::swap(a, b);
}
if (a%b == 0)
{
return b;
}
return ggt(b, a%b);
}
short explanation:
the "swap" when a < b ensures b contains the smaller value.
the "rest" (a%b) is calculated directly when calling the recursion (this avoids storing intermediate values)
as you see the control flow is simpler, so it is easier to reason about each step of the execution.
For a class I have to this simple problem in which I need to check the size of multiple types of variables while using pointers and display it all.
I want my code to look as clean as posible. So I wanted to know if there is something that does it cleaner. I have this code as of now.
void size (float *p1, int *p2, int*p3, int *p4, double *p5,bool *pc){
for(int i=1; i <=5; i++){
cout << "Size of pointer " << i << " is:" << sizeof(p::i)<< endl;
}
cout << "Size of control pointer is:" << sizeof(pc)<< endl;
}
Is there a way to do it somehow like this, or do I have to explicitely write line by line?
You can use template parameter packs to do this, but it's not clear this is the best choice for whatever problem you're facing.
#include <iostream>
template<typename T>
void print_size(const T* t) {
std::cout << sizeof(*t) << '\n';
}
template<typename T, typename... Args>
void print_size(const T* t, Args... args) {
std::cout << sizeof(*t) << '\n';
print_size(args...);
}
struct MyStruct {
const char my_char[10];
};
int main() {
int* int_ptr;
double* double_ptr;
MyStruct* my_struct;
print_size(int_ptr, double_ptr, my_struct);
}
Results in the output (on my machine):
4
8
10
if your goal is to automatically print the sizes of some function parameters, you may write something like
template< typename T, typename... V >
void print_size_of_args( T(*f)(V...) )
{(( std::cout << "size of arg[" << typeid(V).name() << "] is " << sizeof(V) << std::endl ), ... );}
void fun(float *p1, int *p2, int*p3, int *p4, double *p5,bool *pc)
{
print_size_of_args(fun);
// ...
}
this is c++17 and, as it is, works for non overloaded, non member functions; can be made more general if necessary ...
I was having a discussion with a coworker about how to transform the following iterative function into a strictly recursive function. We know that all iterative functions can be transformed into recursive functions; however, my coworker remembered that this particular implementation used only three parameters. We can't re-solve this problem. Are we remembering incorrectly? Or are we missing something simple?
void iterative_function (char a, char b, int width) {
int i = width;
while (i > 0) {
cout << string(i, a) << string(width-i, b) << endl;
i -= 2;
}
i = width % 2;
while (i <= width) {
cout << string(i, a) << string(width-i, b) << endl;
i += 2;
}
}
Where the output looks something like below when called like iterative_function('X', '-', 5).
XXXXX
XXX--
X----
XXX--
XXXXX
EDIT: Here is a small skeleton of what the recursive version might look like:
void recursive_function (char a, char b, int width) {
if (width > -1) {
cout << string(width, a) << endl;
recursive(a, b, width - 2);
cout << string(width, a) << endl;
}
}
Except the problem here is filling the right side out with, say, hyphens.
Here is the recursive function, I just add another len to your function you can see in here, that its output is exactly like the output of your code here.
#include <iostream>
using namespace std;
void i_f(char a, char b, int width,int len) {
if(len <0 || width < 0)
return;
cout <<string(width, a) << string(len, b) << endl;
i_f(a,b,width-2,len+2);
cout <<string(width, a) << string(len, b) << endl;
}
int main() {
i_f('X', '-', 5,0);
return 0;
}
your code output:
XXXXX
XXX--
X----
X----
XXX--
XXXXX
my code output:
XXXXX
XXX--
X----
X----
XXX--
XXXXX
P.S After I posted my answer I saw your edit, although you edited your question 10 minutes before my answer, and I can see that you choose a path like my answer yourself.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
#include<iostream.h>
#include<conio.h>
#include<stdlib.h>
int * add(int *, int *);
int add(int, int);
void main() {
int a, b, sum, *z;
cout << "enter the value of a & b";
cin >> a >> b;
z = add(&a, &b);
sum = add(a, b);
cout << "\nthe sum is: " << sum << endl;
cout << "the sum is :" << *z << endl; getch();
}
//.....calling with value.....
int add(int a, int b) {
int s;
s = a + b;
return s;
}
//......calling with address.......
int *add(int *a, int*b) {
int r;
r = *a + *b;
return &r;
}
Why does it give the wrong answer:
output........ a=70 b=80 the sum with value is: 150 the sum with address is :1208
...but when I give the program as:
#include<iostream.h>
#include<conio.h>
#include<stdlib.h>
int * add(int *, int *);
int add(int, int);
void main() {
int a, b, sum, *z;
cout << "enter the value of a & b";
cin >> a >> b;
sum = add(a, b);
cout << "\nthe sum is: " << sum << endl;
z = add(&a, &b);
cout << "the sum is :" << *z << endl;
getch();
}
//.....calling with value.....
int add(int a, int b) {
int s;
s = a + b;
return s;
}
//......calling with address.......
int *add(int *a, int*b) {
int r;
r = *a + *b;
return &r;
}
It gives right answer.
output..... a=70 b=80 the sum with value is:150 the sum with address is:150.
Why?
int *add(int *a,int *b)
{
int r; // r resides on stack
r=*a+*b;
return &r;
} // life time of r ends here.
You are returning the address of a local variable causing undefined behavior. Compiler should have warned about it.
When you return the address of r, in main, you have the address of a variable that is on the stack, in an area of stack that is currently "free". Using memory after it has been freed, whether it's "stale stack" or "stale heap" is "undefined behaviour"
In this case, any use of the location of r on the stack in the future will overwrite the value in r with some other "random" value. In this case, it looks like it may be the address of the function add (with int parameters).
I would also suggest that you use a more modern compiler (one that isn't old enough to legally apply for a driving license in most countries) and enable warnings. For example GCC (which is free software, so no cost) - it will give warnings for "returning address of local variable".