1

このプログラムでは:

#include <stdio.h>
#include <stdlib.h>   /* for malloc */
#include <ctype.h>

#define STD_WORK_WEEK 40
#define OVERTIME_RATE 1.5


struct employee
 {
 char first_name[10];
 char last_name[10];
 long id_number;
 float wage;
 float hours;
 float overtime;
 float gross;

 struct employee *next;
 };

/************************************************************************/
/*                      Function: Gross_pay_calc                        */
/*                                                                      */
/*  Purpose:    Calculates gross pay of an employee using hours and     */
/*              wage data that is already stored                        */
/*                                                                      */ 
/*                                                                      */
/*  Parameters: wage - Array of employee wages                          */
/*              hours- Array of number of hours worked by an employee   */
/*              grossPay- Gross Pay of an employee                      */
/*              size-number of employees to process                     */
/*                                                                      */
/*  Returns:    Stores grossPay to be referenced in another function output  */
/*                                                                       */
/************************************************************************/

 /* Function call to calculate gross pay. */
 void Gross_pay_calc (struct employee *emp1)
 { 
  /*Local Variable Declaration */
  struct employee *tmp;   /* tmp pointer value to current node */

            if ( tmp->hours <= STD_WORK_WEEK ) /* Calculates grossPay based on <40 or     >40 for OT */

            {
            tmp->gross = tmp->wage*tmp->hours;
            }

            else

            {
            tmp->gross = (tmp->wage*STD_WORK_WEEK)+((tmp->hours-STD_WORK_WEEK)* (tmp->wage*OVERTIME_RATE));
            } 

   }

 /*-----------------------------------------------------------------------------*/
 /*                                                                             */
 /* FUNCTION:  print_list                                                       */
 /*                                                                             */
 /* DESCRIPTION:  This function will print the contents of a linked             */
 /*               list.  It will traverse the list from beginning to the        */
 /*               end, printing the contents at each node.                      */
 /*                                                                             */
 /* PARAMETERS:   emp1 - pointer to a linked list                               */
 /*                                                                             */
 /* OUTPUTS:      None                                                          */
 /*                                                                             */
 /* CALLS:        None                                                          */
 /*                                                                             */
 /*-----------------------------------------------------------------------------*/
 void print_list(struct employee *emp1)
 {
    struct employee *tmp;   /* tmp pointer value to current node */
    int i = 0;              /* counts the nodes printed          */

        printf ("--------------------------------------------------------------\n");         /*Print Header To Screen */
        printf ("     Name \t     Clock# \t Wage \t Hours \t OT \t Gross\n");
        printf ("---------------------------------------------------------------\n");

    /* Start a beginning of list and print out each value               */
    /* loop until tmp points to null (remember null is 0 or false)      */

    for(tmp = emp1; tmp ; tmp = tmp->next)
    {
        i++;

        /* TODO - print other members as well */
        printf("\n %s %s %6d %8.2f %5.2f %7.2f\n",tmp->first_name,tmp->last_name,tmp->id_number,
                                                  tmp->wage,tmp->hours,tmp->gross);

     }

     printf("\n\nTotal Number of Employees = %d\n", i);

  }

 /*----------------------------------------------------------------------------*/
 /*                                                                            */
 /* FUNCTION:  main                                                            */
 /*                                                                            */
 /* DESCRIPTION:  This function will prompt the user for an employee           */
 /*               id and wage until the user indicates they are finished.      */
 /*               At that point, a list of id and wages will be                */
 /*               generated.                                                   */
  /*                                                                            */
 /* PARAMETERS:   None                                                         */
 /*                                                                            */
 /* OUTPUTS:      None                                                         */
 /*                                                                            */
 /* CALLS:        print_list                                                   */
 /*                                                                            */
 /*----------------------------------------------------------------------------*/
int main ()
{

char   answer[80];       /* to see if the user wants to add more employees */
int    more_data = 1;    /* flag to check if another employee is to be processed */
char   value;             /* gets the first character of answer */

struct employee *current_ptr,   /* pointer to current node */
                *head_ptr;       /* always points to first node */

  /* Set up storage for first node */
head_ptr = (struct employee *) malloc (sizeof(struct employee));
current_ptr = head_ptr;

while (more_data)
{
   /* Read in Employee ID and Hourly Wage */

    printf("\nEnter employee ID: ");
    scanf("%li", & current_ptr -> id_number);

    printf("\nEnter employee weekly wage: ");
    scanf("%f", & current_ptr -> wage);

    printf("\nEnter employee weekly hours: ");
    scanf("%f", & current_ptr -> hours);

    printf("\nEnter First Name: ");
    scanf("%s", & current_ptr -> first_name);

    printf("\nEnter Last Name: ");
    scanf("%s", & current_ptr -> last_name);

    printf("Would you like to add another employee? (y/n): ");
    scanf("%s", answer);

    Gross_pay_calc(head_ptr);

    /* Ask user if they want to add another employee */
    if ((value = toupper(answer[0])) != 'Y')
       {
       current_ptr->next = (struct employee *) NULL;
       more_data = 0; 
       }
    else
       {
       /* set the next pointer of the current node to point to the new node */
       current_ptr->next = (struct employee *) malloc (sizeof(struct employee));
      /* move the current node pointer to the new node */
       current_ptr = current_ptr->next;
       }
} /* while */

/* print out listing of all employee id's and wages that were entered */


print_list(head_ptr);

  printf("\n\nEnd of program\n");

 return 0;
 }

Gross_pay_calcを使用して、リクエストに入力した各従業員の総賃金を計算しようとしています。ただし、print_list関数でtmp-> Gross値を出力しようとすると、正しく計算されません。なぜこれが起こっているのかわからないので、正確に計算する方法についての提案があればいいのですが。

4

1 に答える 1

3

2つのこと、最初に、あなたの当面の問題。コメントで述べたように、Gross_pay_calcでは、不確定なポインタを介してメモリにアクセスしていますtmp。逆参照される前に有効なメモリに設定されることはないため、未定義の動作です。emp1代わりに、渡されたパラメーターを使用してみてください。

/* Function call to calculate gross pay. */
void Gross_pay_calc (struct employee *emp1)
{
    if ( emp1->hours <= STD_WORK_WEEK ) /* Calculates grossPay based on <40 or     >40 for OT */
    {
        emp1->gross = emp1->wage*emp1->hours;
    }
    else
    {
        emp1->gross = (emp1->wage*STD_WORK_WEEK) + 
                      ((emp1->hours-STD_WORK_WEEK) * (emp1->wage*OVERTIME_RATE));
    }
}

第二に、リンクリストを作成するためのアルゴリズムが酷使されています。単純なポインターからポインターへのポインターは、そのループをはるかに簡潔にすることができます。

int main ()
{
    char answer[80];       /* to see if the user wants to add more employees */

    struct employee *head_ptr = NULL; /* the list head pointer */
    struct employee **next_ptr = &head_ptr; /*always holds the address of the next pointer to fill */

    do
    {   /* allocate new node wherever *next_ptr says to. initially it will be
           the head pointer. after that, the next-ptr of the last node added. */
        *next_ptr = calloc(1, sizeof(**next_ptr));

        /* Read in Employee ID and Hourly Wage */
        printf("\nEnter employee ID: ");
        scanf("%li", &(*next_ptr)->id_number);

        printf("\nEnter employee weekly wage: ");
        scanf("%f", &(*next_ptr)->wage);

        printf("\nEnter employee weekly hours: ");
        scanf("%f", &(*next_ptr)->hours);

        printf("\nEnter First Name: ");
        scanf("%s", (*next_ptr)->first_name);

        printf("\nEnter Last Name: ");
        scanf("%s", (*next_ptr)->last_name);

        Gross_pay_calc(*next_ptr);

        // move to the next pointer we'll be filling
        next_ptr = &(*next_ptr)->next;

        /* Ask user if they want to add another employee */
        printf("Would you like to add another employee? (y/n): ");
        scanf("%s", answer);
        if (toupper(answer[0]) != 'Y')
            break;

    }  while (1);

    // always set the last pointer to nothing.
    *next_ptr = NULL;

    /* print out listing of all employee id's and wages that were entered */
    print_list(head_ptr);

    printf("\n\nEnd of program\n");

    return 0;
}

同様に、印刷機能も少しクリーンアップできます。

void print_list(struct employee *emp1)
{
    int i = 0;              /* counts the nodes printed          */

    printf ("--------------------------------------------------------------\n");
    printf ("     Name \t     Clock# \t Wage \t Hours \t OT \t Gross\n");
    printf ("---------------------------------------------------------------\n");

    /* Start a beginning of list and print out each value               */
    /* loop until tmp points to null (remember null is 0 or false)      */
    for (;emp1; ++i, emp1 = emp1->next)
    {
        printf("\n %s %s %6ld %8.2f %5.2f %7.2f\n",
               emp1->first_name,emp1->last_name,emp1->id_number,
               emp1->wage,emp1->hours,emp1->gross);
    }
    printf("\n\nTotal Number of Employees = %d\n", i);
}
于 2013-03-25T07:00:36.900 に答える