//********************************************************
//
// Assignment 10 - Linked Lists, Typedef, and Macros
//
// Name: John Semenuk
//
// Class: C Programming, Spring 2026
//
// Date: April 20, 2026
//
// Description: Program which determines overtime and
// gross pay for a set of employees with outputs sent
// to standard output (the screen).
//
// Also calculates taxes, totals, averages, min, and max
// using linked lists, pointers, and macros.
//
//********************************************************
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#define STD_HOURS 40.0
#define OT_RATE 1.5
#define MA_TAX_RATE 0.05
#define NH_TAX_RATE 0.0
#define VT_TAX_RATE 0.06
#define CA_TAX_RATE 0.07
#define DEFAULT_STATE_TAX_RATE 0.08
#define FED_TAX_RATE 0.25
#define FIRST_NAME_SIZE 10
#define LAST_NAME_SIZE 10
#define TAX_STATE_SIZE 3
// Macros
#define CALC_OT_HOURS(h) ((h > STD_HOURS) ? (h - STD_HOURS) : 0)
#define CALC_STATE_TAX(p,r) ((p)*(r))
#define CALC_FED_TAX(p) ((p)*FED_TAX_RATE)
#define CALC_NET_PAY(p,s,f) ((p)-((s)+(f)))
#define CALC_NORMAL_PAY(w,h,ot) ((w)*((h)-(ot)))
#define CALC_OT_PAY(w,ot) ((ot)*(OT_RATE*(w)))
#define CALC_MIN(v,m) ((v)<(m)?(v):(m))
#define CALC_MAX(v,m) ((v)>(m)?(v):(m))
// Structures
struct name {
char firstName[FIRST_NAME_SIZE];
char lastName[LAST_NAME_SIZE];
};
typedef struct employee {
struct name empName;
char taxState[TAX_STATE_SIZE];
long int clockNumber;
float wageRate;
float hours;
float overtimeHrs;
float grossPay;
float stateTax;
float fedTax;
float netPay;
struct employee *next;
} EMPLOYEE;
typedef struct totals {
float total_wageRate;
float total_hours;
float total_overtimeHrs;
float total_grossPay;
float total_stateTax;
float total_fedTax;
float total_netPay;
} TOTALS;
typedef struct min_max {
float min_wageRate, min_hours, min_overtimeHrs, min_grossPay, min_stateTax, min_fedTax, min_netPay;
float max_wageRate, max_hours, max_overtimeHrs, max_grossPay, max_stateTax, max_fedTax, max_netPay;
} MIN_MAX;
// Prototypes
EMPLOYEE *getEmpData(void);
int isEmployeeSize(EMPLOYEE *head_ptr);
void calcOvertimeHrs(EMPLOYEE *head_ptr);
void calcGrossPay(EMPLOYEE *head_ptr);
void calcStateTax(EMPLOYEE *head_ptr);
void calcFedTax(EMPLOYEE *head_ptr);
void calcNetPay(EMPLOYEE *head_ptr);
void calcEmployeeTotals(EMPLOYEE *head_ptr, TOTALS *t);
void calcEmployeeMinMax(EMPLOYEE *head_ptr, MIN_MAX *m);
void printHeader(void);
void printEmp(EMPLOYEE *head_ptr);
void printEmpStatistics(TOTALS *t, MIN_MAX *m, int size);
// MAIN
int main()
{
EMPLOYEE *head_ptr;
int size;
TOTALS employeeTotals = {0,0,0,0,0,0,0};
MIN_MAX employeeMinMax = {0};
MIN_MAX *emp_minMax_ptr = &employeeMinMax;
head_ptr = getEmpData();
size = isEmployeeSize(head_ptr);
if (size <= 0)
{
printf("\n**** No employees ****\n"); return 0;
}
calcOvertimeHrs(head_ptr);
calcGrossPay(head_ptr);
calcStateTax(head_ptr);
calcFedTax(head_ptr);
calcNetPay(head_ptr);
calcEmployeeTotals(head_ptr, &employeeTotals);
calcEmployeeMinMax(head_ptr, emp_minMax_ptr);
printHeader();
printEmp(head_ptr);
printEmpStatistics(&employeeTotals, emp_minMax_ptr, size);
printf("\n\n*** End of Program ***\n"); return 0;
}
//**************************************************************
// Input Function
//**************************************************************
EMPLOYEE *getEmpData(void)
{
char answer[80];
int more_data = 1;
char value;
EMPLOYEE *current_ptr, *head_ptr;
head_ptr
= (EMPLOYEE
*)malloc(sizeof(EMPLOYEE
)); current_ptr = head_ptr;
while (more_data)
{
printf("\nEnter employee first name: "); scanf("%s", current_ptr
->empName.
firstName);
printf("Enter employee last name: "); scanf("%s", current_ptr
->empName.
lastName);
scanf("%s", current_ptr
->taxState
);
printf("Enter clock number: "); scanf("%li", ¤t_ptr
->clockNumber
);
scanf("%f", ¤t_ptr
->wageRate
);
scanf("%f", ¤t_ptr
->hours
);
printf("Add another employee? (y/n): ");
if (value != 'Y')
{
current_ptr->next = NULL;
more_data = 0;
}
else
{
current_ptr
->next
= (EMPLOYEE
*)malloc(sizeof(EMPLOYEE
)); current_ptr = current_ptr->next;
}
}
return head_ptr;
}
//**************************************************************
int isEmployeeSize(EMPLOYEE *head_ptr)
{
int count = 0;
EMPLOYEE *cur = head_ptr;
while (cur != NULL)
{
count++;
cur = cur->next;
}
return count;
}
//**************************************************************
void calcOvertimeHrs(EMPLOYEE *head_ptr)
{
for (EMPLOYEE *cur = head_ptr; cur; cur = cur->next)
cur->overtimeHrs = CALC_OT_HOURS(cur->hours);
}
//**************************************************************
void calcGrossPay(EMPLOYEE *head_ptr)
{
for (EMPLOYEE *cur = head_ptr; cur; cur = cur->next)
{
float normal = CALC_NORMAL_PAY(cur->wageRate, cur->hours, cur->overtimeHrs);
float ot = CALC_OT_PAY(cur->wageRate, cur->overtimeHrs);
cur->grossPay = normal + ot;
}
}
//**************************************************************
void calcStateTax(EMPLOYEE *head_ptr)
{
for (EMPLOYEE *cur = head_ptr; cur; cur = cur->next)
{
if (strcmp(cur
->taxState
, "MA") == 0) cur->stateTax = CALC_STATE_TAX(cur->grossPay, MA_TAX_RATE);
else if (strcmp(cur
->taxState
, "VT") == 0) cur->stateTax = CALC_STATE_TAX(cur->grossPay, VT_TAX_RATE);
else if (strcmp(cur
->taxState
, "NH") == 0) cur->stateTax = CALC_STATE_TAX(cur->grossPay, NH_TAX_RATE);
else if (strcmp(cur
->taxState
, "CA") == 0) cur->stateTax = CALC_STATE_TAX(cur->grossPay, CA_TAX_RATE);
else
cur->stateTax = CALC_STATE_TAX(cur->grossPay, DEFAULT_STATE_TAX_RATE);
}
}
//**************************************************************
void calcFedTax(EMPLOYEE *head_ptr)
{
for (EMPLOYEE *cur = head_ptr; cur; cur = cur->next)
cur->fedTax = CALC_FED_TAX(cur->grossPay);
}
//**************************************************************
void calcNetPay(EMPLOYEE *head_ptr)
{
for (EMPLOYEE *cur = head_ptr; cur; cur = cur->next)
cur->netPay = CALC_NET_PAY(cur->grossPay, cur->stateTax, cur->fedTax);
}
//**************************************************************
void calcEmployeeTotals(EMPLOYEE *head_ptr, TOTALS *t)
{
for (EMPLOYEE *cur = head_ptr; cur; cur = cur->next)
{
t->total_wageRate += cur->wageRate;
t->total_hours += cur->hours;
t->total_overtimeHrs += cur->overtimeHrs;
t->total_grossPay += cur->grossPay;
t->total_stateTax += cur->stateTax;
t->total_fedTax += cur->fedTax;
t->total_netPay += cur->netPay;
}
}
//**************************************************************
void calcEmployeeMinMax(EMPLOYEE *head_ptr, MIN_MAX *m)
{
EMPLOYEE *cur = head_ptr;
m->min_wageRate = m->max_wageRate = cur->wageRate;
m->min_hours = m->max_hours = cur->hours;
m->min_overtimeHrs = m->max_overtimeHrs = cur->overtimeHrs;
m->min_grossPay = m->max_grossPay = cur->grossPay;
m->min_stateTax = m->max_stateTax = cur->stateTax;
m->min_fedTax = m->max_fedTax = cur->fedTax;
m->min_netPay = m->max_netPay = cur->netPay;
cur = cur->next;
for (; cur; cur = cur->next)
{
m->min_wageRate = CALC_MIN(cur->wageRate, m->min_wageRate);
m->max_wageRate = CALC_MAX(cur->wageRate, m->max_wageRate);
}
}
//**************************************************************
void printHeader(void)
{
printf("\n*** Pay Calculator ***\n"); }
//**************************************************************
void printEmp(EMPLOYEE *head_ptr)
{
for (EMPLOYEE *cur = head_ptr; cur; cur = cur->next)
printf("%s %s %.2f %.2f %.2f %.2f\n", cur->empName.firstName,
cur->empName.lastName,
cur->wageRate,
cur->hours,
cur->grossPay,
cur->netPay);
}
//**************************************************************
void printEmpStatistics(TOTALS *t, MIN_MAX *m, int size)
{
printf("\nTotals: %.2f %.2f %.2f %.2f %.2f %.2f %.2f", t->total_wageRate,
t->total_hours,
t->total_overtimeHrs,
t->total_grossPay,
t->total_stateTax,
t->total_fedTax,
t->total_netPay);
printf("\nEmployees: %d\n", size
); }