trouble compiling fibonacci program

I

Ian Collins

Santosh said:
hello all,

I fiddled with BASIC in the early 90s but left it at
that. Now I am trying to learn C. I tried to solve an
exercise in my book, but it failes to compile. Can
anyone tell me what the error messages mean & what I
should do?

# gcc fib00.c
fib00.c: In function 'main':
fib00.c:6: warning: return type of 'main' is not 'int'

int main(void)
fib00.c: At top level:
fib00.c:17: error: conflicting types for 'calc_fib'
fib00.c:11: error: previous implicit declaration
of 'calc_fib' was here

There isn't a prototype for calc_fib before main, so the compiler
assumes the function returns int. Either provide a prototype, or swap
main and calc_fib.
 
S

santosh

Santosh said:
hello all,

I fiddled with BASIC in the early 90s but left it at
that. Now I am trying to learn C. I tried to solve an
exercise in my book, but it failes to compile. Can
anyone tell me what the error messages mean & what I
should do?

thanks.

#include <stdio.h>
long counter;

Use a static local variable instead of a global. It reduces inadvertant
modifications by other parts of the program, (not necessary for such a
trivial example, but it'll become useful when your programs get
bigger).
void main(void)

Standard C defines main() as either int main(void) or int main(int
argc, char **argv). Any other signature is not portable. Of course you
can use your own names instead of argc and argv, but they're canonical.
Also **argv can be written as *argv[].
{
long fibn;
double fibn_value;
printf("Enter fibonacci number: ");

Unless output is terminated by a newline it's not guaranteed to appear
on stdout, (typically the screen), immediatly. Alternatively call
fflush(stdout).
scanf("%ld", &fibn);
fibn_value = calc_fib(fibn);
printf("\nThe %ld fibonacci number is %lf\n", fibn,
fibn_value);

Don't use %lf for doubles. It's non-standard. Use %f.

And return an int here.
}

double calc_fib(long fibn)
{
double fibn_value = 1;
double previous1 = 1;
double previous2 = 0;
if(fibn == 1) return (double) 0;
else if(fibn == 2) return (double)1;
for(counter = 3; counter <= fibn; counter++) {
fibn_value = previous1 + previous2;
previous2 = previous1;
previous1 = fibn_value;
}
return fibn_value;
}

# gcc fib00.c
fib00.c: In function 'main':
fib00.c:6: warning: return type of 'main' is not 'int'
fib00.c: At top level:
fib00.c:17: error: conflicting types for 'calc_fib'
fib00.c:11: error: previous implicit declaration
of 'calc_fib' was here
#

The compiler needs to find the prototype of a function if it's called
before it's definition. Here you call calc_fib() in main() but it's
defined only later, hence the compiler assumes a default return of int,
which conflicts with it's definition.

Place the prototype before any function definitions, right after the
header includes.
 
R

Richard Heathfield

santosh said:
Santosh Krisnan wrote:

Use a static local variable instead of a global.

Look again. It doesn't need to be static.

Unless output is terminated by a newline it's not guaranteed to appear
on stdout, (typically the screen), immediatly. Alternatively call
fflush(stdout).
Right.

To the OP: check the return value. scanf can fail.
Don't use %lf for doubles. It's non-standard. Use %f.

To be strictly accurate, it *is* now standard, since C99 codifies it. It is,
however, non-portable to C90, which is what the world and his dog actually
uses.

<snip>
 
S

SM Ryan

# hello all,
#
# I fiddled with BASIC in the early 90s but left it at
# that. Now I am trying to learn C. I tried to solve an
# exercise in my book, but it failes to compile. Can
# anyone tell me what the error messages mean & what I
# should do?

I would remember my combinatorial math and look up the formula
for a noniterative computation of Fn.

F(n) = ( ((1+sqrt(5))/2)^n - ((1-sqrt(5))/2)^n ) / sqrt(5)
 
S

santosh

Richard said:
santosh said:


Look again. It doesn't need to be static.
<snip>

Yes, sorry.

To the OP: 'counter' can be made into a local variable. Just put it
inside calc_fib() itself. You might also consider using an unsigned
type for 'fibn'.
 
M

Martin Ambuhl

Santosh said:
hello all,

I fiddled with BASIC in the early 90s but left it at
that. Now I am trying to learn C. I tried to solve an
exercise in my book, but it failes to compile. Can
anyone tell me what the error messages mean & what I
should do?

thanks.

#include <stdio.h>
long counter;

void main(void)
^^^^
main returns an int. If your book is using void as a return type for
main, its author knows nothing about even the most trivial aspects of C.
Burn the book. Do *not* give to some other unsuspecting person.
{
long fibn;
double fibn_value;
printf("Enter fibonacci number: ");
scanf("%ld", &fibn);
fibn_value = calc_fib(fibn);
^^^^^^^^^^^^^^
This is your first mention of the function calc_fib(). In all
versions of C before 2001, this involves an implicit declaration of
calc_fib() as having a return type of int. From 2001 on, this "implicit
int" has disappeared and calc_fib is incorrectly used without a prior
declaration. Before use, you should have a declaration, preferably a
full prototype. A good place for it is before main, and it might look like
double calc_fib(long);
printf("\nThe %ld fibonacci number is %lf\n", fibn,
fibn_value);
return;
}

double calc_fib(long fibn)
^^^^^^
The earlier implicit declaration of calc_fib was that it returned an
int. This redeclaration is obviously in conflict with that and is an
error.
{
double fibn_value = 1;
double previous1 = 1;
double previous2 = 0;
if(fibn == 1) return (double) 0;
else if(fibn == 2) return (double)1;
for(counter = 3; counter <= fibn; counter++) {
fibn_value = previous1 + previous2;
previous2 = previous1;
previous1 = fibn_value;
}
return fibn_value;
}

If you had bothered to read these diagnostics, you would not have had to
ask your question. For goodness sake, what do you think diagnostic
messages are for? Read them!
 
S

Santosh Krisnan

hello all,

I fiddled with BASIC in the early 90s but left it at
that. Now I am trying to learn C. I tried to solve an
exercise in my book, but it failes to compile. Can
anyone tell me what the error messages mean & what I
should do?

thanks.

#include <stdio.h>
long counter;

void main(void)
{
long fibn;
double fibn_value;
printf("Enter fibonacci number: ");
scanf("%ld", &fibn);
fibn_value = calc_fib(fibn);
printf("\nThe %ld fibonacci number is %lf\n", fibn,
fibn_value);
return;
}

double calc_fib(long fibn)
{
double fibn_value = 1;
double previous1 = 1;
double previous2 = 0;
if(fibn == 1) return (double) 0;
else if(fibn == 2) return (double)1;
for(counter = 3; counter <= fibn; counter++) {
fibn_value = previous1 + previous2;
previous2 = previous1;
previous1 = fibn_value;
}
return fibn_value;
}

# gcc fib00.c
fib00.c: In function 'main':
fib00.c:6: warning: return type of 'main' is not 'int'
fib00.c: At top level:
fib00.c:17: error: conflicting types for 'calc_fib'
fib00.c:11: error: previous implicit declaration
of 'calc_fib' was here
#
 
K

Keith Thompson

Martin Ambuhl said:
Santosh Krisnan wrote: [...]
fibn_value = calc_fib(fibn);
^^^^^^^^^^^^^^
This is your first mention of the function calc_fib(). In all
versions of C before 2001, this involves an implicit declaration of
calc_fib() as having a return type of int. From 2001 on, this
"implicit int" has disappeared and calc_fib is incorrectly used
without a prior declaration.
[...]

I think you mean 1999.
 
S

SM Ryan

# On Wednesday 06 December 2006 06:49 am SM Ryan
# <[email protected]>
# wrote:
# > Santosh Krisnan <[email protected]>
# > wrote:
# > # hello all,
# > #
# > # I fiddled with BASIC in the early 90s but left it
# > # at that. Now I am trying to learn C. I tried to
# > # solve an exercise in my book, but it failes to
# > # compile. Can anyone tell me what the error messages
# > # mean & what I should do?
# >
# > I would remember my combinatorial math and look up
# > the formula for a noniterative computation of Fn.
# >
# > F(n) = ( ((1+sqrt(5))/2)^n - ((1-sqrt(5))/2)^n ) /
# > sqrt(5)
#
# Thanks. to be frank I'm not very tht strong in math,
# but I implementad your formula and it's giving

Actually it's not my formula but a well known formula
http://en.wikipedia.org/wiki/Fibonacci_number
 
D

Dik T. Winter

> # > F(n) = ( ((1+sqrt(5))/2)^n - ((1-sqrt(5))/2)^n ) /
> # > sqrt(5)
> #
> # Thanks. to be frank I'm not very tht strong in math,
> # but I implementad your formula and it's giving
>
> Actually it's not my formula but a well known formula
> http://en.wikipedia.org/wiki/Fibonacci_number

When using that formula you should round the final result, not truncate.
Moreover, the last part can be ignored when you do rounding. So:
f(n) = floor(pow((sqrt(5) + 1)/2, n) / sqrt(5) + 0.5);
This starts with f(1) = 1 and f(2) = 1.
 
S

Santosh Krisnan

hello all,

I fiddled with BASIC in the early 90s but left it at
that. Now I am trying to learn C. I tried to solve an
exercise in my book, but it failes to compile. Can
anyone tell me what the error messages mean & what I
should do?

big thanks to everyone who respondad. I followed all
your suggestions and the prog. is now working
properly.
 
S

Santosh Krisnan

Santosh Krisnan <[email protected]>
wrote:
# hello all,
#
# I fiddled with BASIC in the early 90s but left it
# at that. Now I am trying to learn C. I tried to
# solve an exercise in my book, but it failes to
# compile. Can anyone tell me what the error messages
# mean & what I should do?

I would remember my combinatorial math and look up
the formula for a noniterative computation of Fn.

F(n) = ( ((1+sqrt(5))/2)^n - ((1-sqrt(5))/2)^n ) /
sqrt(5)

Thanks. to be frank I'm not very tht strong in math,
but I implementad your formula and it's giving
different results to the earlier method, for large fib
values. I'm giving the src and sample output below.
did I do both correctly? If so which of the two is
correct? I'd be greatful if you can respond.

/* straightforward method */
#include <stdio.h>

double calc_fib(unsigned long);

int main(void)
{
int n;
unsigned long fibn;
double fibn_value;
printf("Enter fibonacci number: ");
n = scanf("%lu", &fibn);
if(n != 1) return 1;
fibn_value = calc_fib(fibn);
printf("\nThe %ld fibonacci number is %f\n", fibn,
fibn_value);
return 0;
}

double calc_fib(unsigned long fibn)
{
unsigned long counter;
double fibn_value = 1;
double previous1 = 1;
double previous2 = 0;
if(fibn == 1) return (double) 0;
else if(fibn == 2) return (double)1;
for(counter = 3; counter <= fibn; counter++) {
fibn_value = previous1 + previous2;
previous2 = previous1;
previous1 = fibn_value;
}
return fibn_value;
}

/* SM Ryan's method */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>

long double fibnld(unsigned long);

int main(int argc, char **argv) {
long double fib;
unsigned long nfib;

if(argc < 2) return EXIT_FAILURE;
else {
errno = 0;
nfib = strtoul(argv[1], NULL, 0);
if(errno == ERANGE || nfib == 0) {
puts("range error.");
return EXIT_FAILURE;
}
else {
fib = fibnld(nfib);
printf("The %lu fibonacci number is: %Lf\n",
nfib, fib);
}
}
return 0;
}

long double fibnld(unsigned long nfib) {
const long double sqr_five = sqrtl(5);
long double tmp1 = (1 + sqr_five) / 2;
long double tmp2 = (1 - sqr_five) / 2;

tmp1 = powl(tmp1, nfib);
tmp2 = powl(tmp2, nfib);
tmp1 -= tmp2;
tmp1 /= sqr_five;
return tmp1;
}
 
C

CBFalconer

Piggybacking here, because Ryan is plonked for refusal to use
proper quotation characters.

The formula has to be faulty. I see no validity to exclusive-oring
a double with an integer.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top