1

I am new to C and am attempting to create a program to find the compound interest of a bank account.

I am using three functions with pointers, one to get data, one for calculations, and one for printing the data into a table. I am assuming that my confusion with pointers is causing the calculated values to print incorrectly in the table.

As it stands I am not receiving any errors, but a number of warnings about my pointers "default to int".

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

//Function declarations
void GETDATA(double* StartAmnt, float* IntrRate, int* NumYears, int* StartYear);

void Mathemagic (double StartAmnt, float IntrRate, int NumYears, int StartYear,
                 float* IntrEarned, float* PercentGained,long double* FutureValue,
                 int* FutureYear);

void PRINTTABLE (double StartAmnt, float IntrRate, int NumYears, int StartYear,
                 float IntrEarned, float PercentGained,long double FutureValue,
                 int FutureYear);

int main(void)
{

    //Local Declarations
    double StartAmnt;
    float IntrRate;
    float IntrEarned;
    float PercentGained;
    long double FutureValue;

    int NumYears;
    int StartYear;
    int FutureYear;

    //Statements
    GETDATA (&StartAmnt, &IntrRate, &StartYear, &NumYears);

    Mathemagic (StartAmnt, IntrRate, StartYear, NumYears, &IntrEarned,
                &PercentGained, &FutureValue, &FutureYear);

    PRINTTABLE (StartAmnt, IntrRate, NumYears, StartYear, IntrEarned,
                PercentGained, FutureValue, FutureYear);


    return 0;
}//main

void GETDATA(double* StartAmnt, float* IntrRate, int* NumYears, int* StartYear)
{
    //Statements
    printf("COP 2220-51014 Project 2: Michael Walt\n\n");
    printf("Enter a Starting amount (dollars and cents): ");
    scanf("%lf", StartAmnt);
    printf("Enter an Interest rate (ex. 2.5 for 2.5%):   ");
    scanf("%f", IntrRate);
    printf("Enter the Number of years (integer number):  ");
    scanf("%d", NumYears);
    printf("Enter the Starting year (four digits):       ");
    scanf("%d", StartYear);
    return;
}//GETDATA


void Mathemagic (double StartAmnt, float IntrRate, int NumYears, int StartYear,
                 float* IntrEarned, float* PercentGained,long double* FutureValue,
                 int* FutureYear)
{
    //Statements

    *FutureValue = StartAmnt*pow((1+(IntrRate/100)),NumYears);

    *PercentGained =((*FutureValue - StartAmnt)/StartAmnt)*100;

    *IntrEarned = (*FutureValue-StartAmnt);

    *FutureYear = (StartYear+NumYears);

    return;
}//Mathemagic

PRINTTABLE(StartAmnt, IntrRate, NumYears, StartYear, IntrEarned,
           PercentGained, FutureValue, FutureYear)
{
    printf("\n+-----------------------------+--------------+\n");
    printf("| Description                 |  Input Data  |\n");
    printf("|-----------------------------+--------------|\n");
    printf("| Starting amount             | $  %.2f  |\n", StartAmnt);
    printf("| Interest rate               |        %f%% |\n", IntrRate);
    printf("| Number of Years             |        %d     |\n", NumYears);
    printf("| Starting year               |     %d     |\n", StartYear);
    printf("+-----------------------------+--------------+\n");
    printf("| Future value                |   Results    |\n");
    printf("|-----------------------------+--------------|\n");
    printf("| In %d the balance will be | $  %f  |\n", FutureYear, FutureValue);
    printf("| Interest earned             | $   %f  |\n", IntrEarned);
    printf("| Total percent gained        |       %f%% |\n", PercentGained);
    printf("+-----------------------------+--------------+\n");
    return;
}
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
  • 3
    Paste the entire output from the compiler, we really want to see exactly what the warnings were. – shuttle87 Jun 07 '14 at 02:44
  • 1
    How on earth did `PRINTTABLE()` compile with a _definition_ like that? It doesn't even give the types of the parameters! I mean, sure the prototype declares them, but so must the definition. – Iwillnotexist Idonotexist Jun 07 '14 at 02:49
  • 1
    `GETDATA` and `Mathemagic` are both called with `NumYears` and `StartYear` swapped, but this is not your pointer problem. – Iwillnotexist Idonotexist Jun 07 '14 at 02:55
  • 1
    @IwillnotexistIdonotexist IIRC some C/C++ compilers default to int when no type is specified, there's a good chance that is what is causing whatever the issue is (as well as the warning). – IllusiveBrian Jun 07 '14 at 03:05
  • @Namfuak But the `PRINTTABLE()` function that lacks modern parameter type info is also the only one that doesn't have pointer parameters at all, or for that matter pointers period, if we except the format strings. How could it cause the pointer-default-to-int warning OP is mentioning? – Iwillnotexist Idonotexist Jun 07 '14 at 03:08
  • @IwillnotexistIdonotexist I know that in gcc & g++ by default, anytime a type is expected but not given, the compiler will default to int, so for example the program `main(){}` will compile. With `-Wall` added it will point it out. EDIT: Oh, you're right it has no pointers. No idea about the error itself then. – IllusiveBrian Jun 07 '14 at 03:16
  • 1
    Addendum: He never defined the return type of PRINTTABLE in the definition, so perhaps the compiler is calling that a pointer when referring to it being defaulted to int? – IllusiveBrian Jun 07 '14 at 03:24
  • 1
    ALL CAPS are reserved for macros and sometimes constants, don't use it like that – phuclv Jun 07 '14 at 05:10
  • also printing without field width will make your table most probably break on the right side – phuclv Jun 07 '14 at 05:41

2 Answers2

2

The main problem is that your PRINTTABLE function has wrong definition:

PRINTTABLE(StartAmnt, IntrRate, NumYears, StartYear, IntrEarned,
       PercentGained, FutureValue, FutureYear)

while it has previously been declared as

void PRINTTABLE (double StartAmnt, float IntrRate, int NumYears, int StartYear,
                 float IntrEarned, float PercentGained,long double FutureValue,
                 int FutureYear);

If you enable all warnings (which is a must for almost all compilations) you'll see lots of defaults to 'int' warnings as you noticed:

*.c:76:1: warning: return type defaults to 'int' [-Wreturn-type]
 PRINTTABLE(StartAmnt, IntrRate, NumYears, StartYear, IntrEarned,
 ^
*.c:76:1: warning: conflicting types for 'PRINTTABLE' [enabled by default]
*.c:12:6: note: previous declaration of 'PRINTTABLE' was here
 void PRINTTABLE (double StartAmnt, float IntrRate, int NumYears, int StartYear,
      ^

Because you have different declaration and definition for PRINTTABLE, the compiler will use the last one that appears in your code. Prior to C99, without type in the declaration all arguments are default to int and the return value is also implied as int, making the conflicting type warnings above.

That's also why there are lots of other warnings in wrong conversion and format specifier (which invokes undefined behavior) like

*.c:82:5: warning: format '%f' expects argument of type 'double', but argument 2 has type 'int' [-Wformat=]
     printf("| Starting amount             | $  %.2f  |\n", StartAmnt);

StartAmnt is an int due to the implied type rule and you're printing it as double

For more information about the rule read

Another problem is that you missed a percent sign in this line

printf("Enter an Interest rate (ex. 2.5 for 2.5%):   ");
                                               ↑

You also use the wrong format specifier in another place. FutureValue has type long double but you're printing it by %f. It should be %Lf.

printf("| In %d the balance will be | $  %f  |\n", FutureYear, FutureValue);

In practice the higher precision of long double (if available) is unnecessary in most applications. long double may also takes more space and is much slower in many cases because of the precision and the use of old x87 FPU or software floating-point libraries. I also don't know why you're mixing float, double and long double like that, it just costs you time to convert between types and reduce precision in other cases. In general double is the recommended type, even floating-point literals without a suffix like 1.23 are also double. float is most often used for storage instead because the precision is very limited. All non-double literals must be used with a suffix

And don't use ALL CAPS for functions or variables like that

phuclv
  • 37,963
  • 15
  • 156
  • 475
1

You had given parameters in incorrect order. That was the reason your results were not computed correctly. Also you didn't specify parameter types in function definition of PRINTTABLE. It's working correctly now.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

//Function declarations
void GETDATA(double* StartAmnt, float* IntrRate, int* NumYears, int* StartYear);

void Mathemagic (double StartAmnt, float IntrRate, int NumYears, int StartYear,
             float* IntrEarned, float* PercentGained,long double* FutureValue,
             int* FutureYear);

void PRINTTABLE (double StartAmnt, float IntrRate, int NumYears, int StartYear,
             float IntrEarned, float PercentGained,long double FutureValue,
             int FutureYear);

int main(void)
{

//Local Declarations
double StartAmnt;
float IntrRate;
float IntrEarned;
float PercentGained;
long double FutureValue;

int NumYears;
int StartYear;
int FutureYear;

//Statements
GETDATA (&StartAmnt, &IntrRate, &NumYears, &StartYear);

Mathemagic (StartAmnt, IntrRate, NumYears,  StartYear, &IntrEarned,
       &PercentGained, &FutureValue, &FutureYear);

PRINTTABLE (StartAmnt, IntrRate, NumYears, StartYear, IntrEarned,
        PercentGained, FutureValue, FutureYear);


return 0;
}//main

void GETDATA(double* StartAmnt, float* IntrRate, int* NumYears, int* StartYear)
{
//Statements
printf("COP 2220-51014 Project 2: Michael Walt\n\n");
printf("Enter a Starting amount (dollars and cents): ");
scanf_s("%lf", StartAmnt);
printf("Enter an Interest rate (ex. 2.5 for 2.5%):   ");
scanf_s("%f", IntrRate);
printf("Enter the Number of years (integer number):  ");
scanf_s("%d", NumYears);
printf("Enter the Starting year (four digits):       ");
scanf_s("%d", StartYear);
return;
}//GETDATA


void Mathemagic (double StartAmnt, float IntrRate, int NumYears, int StartYear,
             float* IntrEarned, float* PercentGained,long double* FutureValue,
             int* FutureYear)
{
//Statements

*FutureValue = StartAmnt*pow((1+(IntrRate/100)),NumYears);

*PercentGained =((*FutureValue - StartAmnt)/StartAmnt)*100;

*IntrEarned = (*FutureValue-StartAmnt);

*FutureYear = (StartYear+NumYears);

return;
}//Mathemagic

void PRINTTABLE(double StartAmnt, float IntrRate, int NumYears, int StartYear,
             float IntrEarned, float PercentGained,long double FutureValue,
             int FutureYear)
{
 printf("\n+-----------------------------+--------------+\n");
 printf("| Description                 |  Input Data  |\n");
 printf("|-----------------------------+--------------|\n");
 printf("| Starting amount             | $  %.2f  |\n", StartAmnt);
 printf("| Interest rate               |        %f%% |\n", IntrRate);
 printf("| Number of Years             |        %d     |\n", NumYears);
 printf("| Starting year               |     %d     |\n", StartYear);
 printf("+-----------------------------+--------------+\n");
 printf("| Future value                |   Results    |\n");
 printf("|-----------------------------+--------------|\n");
 printf("| In %d the balance will be | $  %f  |\n", FutureYear, FutureValue);
 printf("| Interest earned             | $   %f  |\n", IntrEarned);
 printf("| Total percent gained        |       %f%% |\n", PercentGained);
 printf("+-----------------------------+--------------+\n");
 return;
}
phuclv
  • 37,963
  • 15
  • 156
  • 475
Murtaza Zaidi
  • 599
  • 3
  • 14