-2

For a homework problem I have to define a struct that can be used in a program to represent a fraction, together with a set function that can be used to set up the value of a fraction, and a print function that will print the fraction nicely. We are given the main function and according to the problem the output should be

(2/3) (1/5) (3/5)

Here's what I've written:

#include "library.h"
struct fraction
{
    int numerator;
    int denominator;
};

void set (fraction st, int n, int d)
{
    if (d>0)
    {
        n = st.numerator;
        d = st.denominator;
    }
}

void print(fraction st)
{
    int x = st.numerator;
    int y = st.denominator;
    print("(x/y)");
    print(" ");
}

void main()
{
    fraction a, b, c;
    set(a, 2, 3);
    set(b, 1, 5);
    set(c, 3, 5);
    print(a);
    print(b);
    print(c);
}

If you're wondering "library.h" is what my university uses as a shortcut for most of the standard includes.

I keep getting the error that the variable 'a' is being used without being initialized. Any help would be greatly appreciated.

WhozCraig
  • 65,258
  • 11
  • 75
  • 141
AWright
  • 3
  • 3
  • 3
    If you think it *is* initialized, care to state where? (Hint, the compiler is correct to complain, and not just about `a`). – WhozCraig Apr 10 '16 at 19:02
  • 1
    Doesn't the compiler tell you exactly what line(s) the problem is? – juanchopanza Apr 10 '16 at 19:05
  • Fwiw, the assignment statements in `set()` appear to be backward. Further, even if those were fixed, you're still passing `a`, `b`, and `c` by *value* to `set()`, so nothing back in `main()` will be changed regardless. – WhozCraig Apr 10 '16 at 19:06
  • `void main()` ?? main must return `int` in c++ – Andreas DM Apr 10 '16 at 20:03

2 Answers2

2

You pass a, b, c to set() by value. Of course, they are uninitialized in main() (and in print()). Try this:

void set (fraction &st, int n, int d)
{
    if (d>0)
    {
        //n = st.numerator;
        //d = st.denominator;
        // I suppose this part should be:
        st.numerator = n;
        st.denominator = d;
    }

    /* Edit, thanks to @Tyler S comments:
       Not sure what author needs, but something like this
       should be here to really avoid uninitialized values. 

       Other options:
       Use unsigned int if you use only positive integers ( d>0 ).
       Use exceptions to handle negative inputs, zero denominator..
    */
    else
    {
        st.numerator = 1;
        st.denominator = 1;
    }
 }

in main():

set(a, 2, 3);
set(b, 1, 5);
set(c, 3, 5);

I'd also change print(..) to void print(const fraction &st). There's no need to pass by value. Imagine larger data struct - copying just to print it is waste of time.

I recommend to check pass by value/reference and const correctness.

Enkelli
  • 305
  • 5
  • 18
  • 1
    This is still dangerous because it is possible that the members of the struct will not be initialized, in the event that d <= 0. If you try and call print after calling `set()` with parameters outside the accepted range, you could be dealing with some bizzare values. If OP was using pointers, this type of practice could very likely lead to a segmentation fault. – MS-DDOS Apr 10 '16 at 19:30
  • True, but I quite do not understand the condition - why checking just d - avoid negative denominator? what about negative numerator? I just wrote solution to question, but thanks for remark. – Enkelli Apr 10 '16 at 19:35
  • If the goal was to simply avoid negative values, OP should be using unsigned ints. However I believe the goal is to avoid `DIV/0`, so an exception should be throw as an `else` condition in the `set()` method. [This stack overflow article](http://stackoverflow.com/questions/8480640/how-to-throw-a-c-exception) covers the subject in sufficient detail. – MS-DDOS Apr 10 '16 at 19:53
  • I agree, but I do not think that author knows the `exceptions` when struggling with function calls. As author wrote - it is homework. – Enkelli Apr 10 '16 at 20:00
  • 1
    I agree. I'm just presenting additional information that may be useful to OP or any other potential reader of this question going forward. – MS-DDOS Apr 10 '16 at 20:11
1

If the set function is expected to define a fraction then you should be assigning the st.numerator and st.denominator member variables with the values of n and d like so:

void set (fraction st, int n, int d)
{
    if (d>0)
    {
        st.numerator = n;
        st.denominator = d;
    }
}

You should also pass the fraction variables into the set function by reference i.e: void set(fraction& st, ...) or pointer void set(fraction* st, ...) in order to get any results back.

Jonathon Ogden
  • 1,562
  • 13
  • 19