开发者

Why am I receiving a segmentation fault in my code and can you explain pass by reference, pass by value?

开发者 https://www.devze.com 2023-02-28 14:51 出处:网络
I am writing a program in C.I am trying to learn the difference between pass by reference and pass by value. I\'m not sure if I got those right.

I am writing a program in C. I am trying to learn the difference between pass by reference and pass by value. I'm not sure if I got those right.

I am getting a segmentation fault / core dump error after executing the do while loop for the second time. What am I missing with the loop?

Here is my main:

#include <stdio.h>
#include <stdlib.h>
#include <iomanip>
#include <iostream>

extern void CalculateTaxes(float gross,float defr, float *ft,float *st,float *ssit);
extern float calcGross(float hours, float payrate);
extern void InputEmplData(char *lastname, char *firstname, float *hours, float *payrate, float *defr);
extern void InitAcc(float *totreg, float *totovt, float *totrate, float *totgross, float *totfed, float *totstate, float *totssi, float *totdef,  float *totnet);
extern void AddDetail2Acc(float reghrs, float *totreg, float ovthrs, float *totovt, float pr, float *totpayrate, float theGross, float *totgross,float ft, float *totfed, float st, float *totstate, float ssit, float *totssi, float defr, float *totdef, float net, float *totnet);

int main(void)
{
   float fedtax,statetax,ssitax;
   float theGross;
   //int  counter=0;
   char answer;
   char lastname, firstname;
   float hours, payrate, defr, reghrs, ovthrs, net, numemps;
   float totgross, totpayrate, totreg, totovt, totrate, totfed, totstate, totssi, totdef, totnet;

/*
   FILE * reportFile; // 1) declare a FILE * variable

   reportFile = fopen("./report.txt","wt");
   // 2) open a report file with access mode "write-text"
   if (reportFile == NULL)
   {
     printf("  Report file open failed ...\n");
     fflush(stdin);
     getchar();
     exit(-10); // terminate w/ failure code -10; reqs <stdlib>
   }
*/
   printf("  Welcome to the Employee Tax Program\n");
   printf("  Please enter the number of employees taxes will be calculated:");
   scanf (" %f", numemps);
   InitAcc(&totreg, &totovt, &totrate, &totgross, &totfed, &totstate, &totssi, &totdef, &totnet);

   do 
   {
     In开发者_如何学CputEmplData(&lastname, &firstname, &hours, &payrate, &defr);   
     theGross = calcGross(hours, payrate); // call 3.4
     CalculateTaxes(theGross,defr,&fedtax,&statetax,&ssitax); // 3.5
     net=(theGross-defr)-fedtax-statetax-ssitax;
     AddDetail2Acc(reghrs, &totreg, ovthrs, &totovt, payrate, &totpayrate, theGross, &totgross,fedtax, &totfed, statetax, &totstate, ssitax, &totssi, defr, &totdef, net, &totnet);
     printf("    Fedtax    = %8.2f",fedtax);
     //fprintf(reportFile,"    Fedtax    = %8.2f",fedtax);
     //fprintf(stdout,"    Fedtax    = %8.2f",fedtax);
     printf("    Statetax  = %8.2f",statetax);
     //fprintf(reportFile,"    Statetax  = %8.2f",statetax);
     //fprintf(stdout,"    Statetax  = %8.2f",statetax);
     printf("    SSItax    = %8.2f\n",ssitax);
     //fprintf(reportFile,"    SSItax    = %8.2f\n",ssitax);
     //fprintf(stdout,"    SSItax    = %8.2f\n",ssitax);
     //printf(" %f %f %f %f %f %f %f %f", totreg, totovt, totrate, totfed, totstate, totssi, totdef, totnet);
     printf("  Do you have another employee(YES = 1 / No = 2) ==> ");
     fflush(stdin);
     scanf (" %c", answer);
     answer = getchar();
     getchar(); // removes '\n' from response

   } while (answer == 'y' || answer == 'y');

   //fclose(reportFile); // 4) close the file
   printf(" Press any key ... ");
   fflush(stdin);
   getchar();
   return 0;
}

Here are my functions:

#include <stdio.h>

void InputEmplData (char *lastname, char *firstname, float *hours, float *payrate, float *defr);

void InputEmplData (char *lastname, char *firstname, float *hours, float *payrate, float *defr)
{   
   printf("  Please enter your lastname: ");
   scanf (" %s", lastname);
   fflush(stdin);

   printf("  Please enter your firstname: ");
   scanf (" %s", firstname);
   fflush(stdin);

   printf("  Please enter the hours you have worked including overtime: ");
   scanf (" %f", hours);
   while (hours < 0)
   {
    printf(" Please enter a valid number. Must be between 0.");
    scanf (" %f", hours);
   }
   printf("  Please enter your payrate(15.00): ");
   scanf (" %f", payrate);
   while (payrate <= 0)
   {
    printf(" Please enter a valid number. Must be above 0.");
    scanf (" %f", payrate);
   }
   printf("  Please enter the amount exempt from taxes: ");
   scanf (" %f", defr);

   while (defr <= 0)
   {
    printf(" Please enter a valid number. Must be above 0.");
    scanf (" %f", defr);
   }
}

CalculateTaxes function:

#include "./taxrates.h" //user defined header for tax rates

void CalculateTaxes(float gross,float defr, float *ft,float *st,float *ssit);
float calcFed(float gross, float defr);
float calcState(float ft);
float calcSSI(float gross,float defr);

void CalculateTaxes(float gross,float defr, float *ft,float *st,float *ssit)
{
  *ft = calcFed(gross,defr);
  *st = calcState(*ft);
  *ssit = calcSSI(gross,defr);
}

float calcFed(float gross, float defr)
{
  return (gross-defr)*FEDTAXRATE;
}

float calcState(float ft)
{
  return ft * STATETAXRATE;
}

float calcSSI(float gross,float defr)
{
  return (gross-defr)*SSITAXRATE;
}


float calcGross(float h, float pr);

float calcGross(float h, float pr) 
{
  return h <= 40? h * pr : 40 *h + (h-40)*1.5*pr;
}

Function to initialize counters:

void InitAcc(float *totreg, float *totovt, float *totrate, float *totgross, float *totfed, float *totstate, float *totssi, float *totdef,  float *totnet);

void InitAcc(float *totreg, float *totovt, float *totrate, float *totgross, float *totfed, float *totstate, float *totssi, float *totdef, float *totnet)
{
  *totreg = 0;
  *totovt = 0;
  *totrate = 0;
  *totgross = 0;
  *totfed = 0;
  *totstate = 0;
  *totssi = 0;
  *totdef = 0;
  *totnet = 0;
}

Function to use counters (unfinished):

#include <stdio.h>

 void AddDetail2Acc(float reghrs, float *totreg, float ovthrs, float *totovt, 
            float pr, float *totpayrate, float theGross, float *totgross,
            float ft, float *totfed, float st, float *totstate, float ssit, float *totssi, 
            float defr, float *totdef, float net, float *totnet);

 void AddDetail2Acc(float reghrs, float *totreg, float ovthrs, float *totovt, 
            float pr, float *totpayrate, float theGross, float *totgross,
            float ft, float *totfed, float st, float *totstate, float ssit, float *totssi, 
            float defr, float *totdef, float net, float *totnet)
{
    *totgross+= theGross;
    *totreg += reghrs;
    *totovt += ovthrs;
    *totpayrate += pr;
    *totfed += ft;
    *totstate += st;
    *totssi += ssit;
    *totdef += defr;
    *totnet += net;

}

Makefile:

calc.obj:   calctaxes.cpp taxrates.h
    g++ -c calctaxes.cpp -o calc.obj

main2.exe:  main2.cpp calc.obj cGross.obj InputEmplData.obj InitAcc.obj
    g++ main2.cpp calc.obj cGross.obj InputEmplData.obj InitAcc.obj AddDetail2Acc.obj -o main2.exe

cGross.obj: calcGross.cpp InputEmplData.obj
    g++ -c calcGross.cpp -o cGross.obj

InputEmplData.obj:  InputEmplData.cpp
    g++ -c InputEmplData.cpp -o InputEmplData.obj

InitAcc.obj:    InitAcc.cpp InputEmplData.obj
    g++ -c InitAcc.cpp InputEmplData.obj -o InitAcc.obj

AddDetail2Acc.obj:  AddDetail2Acc.cpp
    g++ -c AddDetail2Acc.cpp InitAcc.obj -o AddDetail2Acc.obj


There is really a lot of code here, but here is the first error I see:

//...
extern void InputEmplData(char *lastname, char *firstname, float *hours, float *payrate, float *defr);
//...

    char lastname, firstname;

//...
    InputEmplData(&lastname, &firstname, &hours, &payrate, &defr);

//...
void InputEmplData (char *lastname, char *firstname, float *hours, float *payrate, float *defr)
{   
   printf("  Please enter your lastname: ");
   scanf (" %s", lastname);
   fflush(stdin);

   printf("  Please enter your firstname: ");
   scanf (" %s", firstname);
   fflush(stdin);

Unless you aren't assuming that lastname and firstname lengths is 1, then here is your first error. You are receiving segmentation fault because you are writing a string with lentgh of more then 1 into char.

Possible correction is to define:

char lastname[NAME_LENGTH], firstname[NAME_LENGTH];

/...
InputEmplData(lastname, firstname, &hours, &payrate, &defr);

With this you will achieve desired effect. I used arrays of char for lastname and firstname, but you can allocate memory for lastname and etc dynamically with malloc, but I wouldn't recommend you to do this without clear understanding of what you are doing.

Also, I have just several small advices, not considering segmentation fault:

1.Try to create some structures, that would represent different groups of variables. Then you can write, for example, instead of

void AddDetail2Acc(float reghrs, float *totreg, float ovthrs, float *totovt, 
            float pr, float *totpayrate, float theGross, float *totgross,
            float ft, float *totfed, float st, float *totstate, float ssit, float *totssi, 
            float defr, float *totdef, float net, float *totnet);

something like this:

void AddDetail2Acc(AccStruct *in_out_sourceAcc, AddDataStruct in_addData);

This is more readable and less error prone.

2.As I understand from variables name you are performing some operations with money values. Try not to use float variables to represent money value. Floating point arithmetic one day can give you a small suprise. Try to use integer types.

0

精彩评论

暂无评论...
验证码 换一张
取 消