I'm trying to create a program which reads a number as type fraction using procedures. That's my code (the compiler gives me an error in readFraction() line 9):
#include <stdio.h>
typedef struct {
int num,den;
} fraction;
void readFraction(fraction * f) {
printf("Insert a fraction: ");
scanf("%d/%d", &*f.num, &*f.den);
}
void writeFraction(fraction f) {
printf("Fraction inserted: %d/%d\n", f.num, f.den);
}
void main() {
fraction a;
readFraction(&a);
writeFraction(a);
}
This is the error message:
$ gcc fraction.c
fraction.c: In function ‘readFraction’:
fraction.c:9:21: error: ‘f’ is a pointer; did you mean to use ‘->’?
9 | scanf("%d/%d", &*f.num, &*f.den);
| ^
| ->
fraction.c:9:30: error: ‘f’ is a pointer; did you mean to use ‘->’?
9 | scanf("%d/%d", &*f.num, &*f.den);
| ^
|
I know I could solve this using something like readFraction(&a.num,&a.den);
or a=readFraction();
and the function returns the fraction but I'd like to know if I could just pass the fraction as a parameter.
The problem with your code is in the relative precedence of C operators. Structure-member selection has higher precedence than the dereferencing operator, so the sub-expression *f.num
means "the object to which f.num
points", not "member num
of the object to which f
points." The former is erroneous because f
is a pointer, not a structure or union.
You could override the default precedence by adding parentheses:
scanf("%d/%d", &(*f).num, &(*f).den);
, but it would be more idiomatic to use the indirect member selection operator:
scanf("%d/%d", &f->num, &f->den);
Since we're talking about precedence here, it is worth noting that the ->
operator has higher precedence than &
, so no parentheses are required in that case.