1

I want to make a program that does fraction calculations, and i've made a fraction struct with 2 properties: numerator and denominator. I want to be able to initialize those properties using a function i've overloaded twice called init(fraction x). The overloads are as follows:

init(fraction x) //Initializes a fraction struct with numerator and denominator equal to 0
init(fraction x, int a) //initializes fraction struct to a/1
init(fraction x, int a, int b) //initializes fraction struct to a/b

Then I try to test it and output a fraction like so

int main() {

fraction a;
init(a,1);

cout << "The fraction is: ";
print(a); 
cout << endl;

return 0;
}

but I just get 0/0 every time no matter what. I think it's a pass by value/reference problem but i'm not sure how to go about fixing this. Here's all my code:

Header.h

#include <iostream>
using namespace std;

struct fraction {
    int numerator = NULL, denominator = NULL;
};

void init(fraction x);                          // set fraction to 0
void init(fraction x, int n);                // set fraction to n/1
void init(fraction x, int a, int b);       // set fraction to a/b
fraction add(fraction a, fraction b);                        // adds a and b and returns the sum (a and b unchanged)
fraction sub(fraction a, fraction b);                        // subtracts a and b and returns difference
fraction mul(fraction a, fraction b);                        // multiplies a and b and returns the product
fraction div(fraction a, fraction b);             // divides a and b and returns the quotient
void print(fraction x);                                    // prints the fraction (no improper fractions)
void read(fraction x);                                    // reads fraction 3 / 5 into x
void reduce(fraction x);                               // simplifies x to lowest common terms
int gcd(int a, int b);                                       // finds greatest common divisor of a and b

Source.cpp

#include "Header.h"

void init(fraction x) {
    x.numerator = 0;
    x.denominator = 0;
}

void init(fraction x, int n) {
    x.numerator = n;
    x.denominator = 1;
}

void init(fraction x, int a, int b) {
    x.numerator = a;
    x.denominator = b;
}


fraction add(fraction a, fraction b) {
    return a;
}


fraction sub(fraction a, fraction b) {
    return a;
}

fraction mul(fraction a, fraction b) {
    return a;
}

fraction div(fraction a, fraction b) {
    return a;
}

void print(fraction x) {
    cout << x.numerator << '/' << x.denominator;
}

void read(fraction x) {

}

void reduce(fraction x) {

}

int gcd(int a, int b) {
    return a;
}

Main.cpp

#include "Header.h"

int main() {

fraction a;
a.numerator = a.denominator = 1;
init(a,1, 2);

cout << "The fraction is: ";
print(a); 
cout << endl;

return 0;
}
3
  • 1
    struct fraction {int numerator = NULL, denominator = NULL;}; Unrelated, but don't use the NULL constant as 0, use 0 if that is what you want. It isn't guaranteed to be 0L Commented Sep 21, 2016 at 20:16
  • void init(fraction& x) { ...} Commented Sep 21, 2016 at 20:22
  • void init(fraction x) { x.numerator = 0; x.denominator = 0; } don't work, because of passing by value, do like David by refference, and is bad style in C++ (should be a method) Commented Sep 21, 2016 at 20:23

2 Answers 2

4

but I just get 0/0 every time no matter what. I think it's a pass by value/reference problem but i'm not sure how to go about fixing this.

That's the correct diagnosis. You are passing the fraction by value. The changes are made to the copy, not the original object. Change the functions to:

void init(fraction& x);
void init(fraction& x, int a);
void init(fraction& x, int a, int b);

You have the same problem with read and reduce. Change them to:

void read(fraction& x);
void reduce(fraction& x);
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! I always get confused on what to make a pointer or where to put address operators...
& here is not the address operator, but the thing that makes a reference declarator.
2

Since you're doing this in C++, the best way is to have a constructor for your struct:

struct fraction
{
    int a_, b_;
    fraction(int a = 0, int b = 1): a_(a), b_(b){}
}

Then you won't need any other function to initialize your structure, you'll simply do

fraction frac{1,2}; // 1/2

In fact, in C++11 you don't even need a constructor, you can just use in-class initialization and if you want to change the values you rely on the fact that the struct is an aggregate and you can use aggregate initialization:

struct fraction
{
    int a_ = 0, b_ = 1;
};

fraction frac1; // default
fraction frac2{1,2}; // 1/2, aggregate initialization

Also think about overloading operators, like operator+ etc for your fraction, so you can write proper C++ code (not C in C++). In fact writing a fraction class is a typical exercise when learning C++.

Side note: your

int numerator = NULL, denominator = NULL;

happens to compile, because NULL is a compile-time constant equal to zero. But it's VERY BAD practice. NULL was reserved for null pointers in C++03 and not for initializing variables with zero. C++11 deprecated it and now one uses nullptr, which is not an int anymore, so un-wanted conversions won't happen.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.