Each group has 3 memory addresses associated with it. One address (named DDRx) can be used to set the I/O direction. A one written to a bit at that address makes the corresponding line an input, a 0 makes the corresponding line an output. For example for Port D, DDRD is address 0x31. So writing 0xF0 to address 0x31 would make PD0..PD3 output and PD4..PD7 inputs. One address (named PINx) can be used to read data from input lines. If the line is high (3 volts) the corresponding bit will be 1. If the line is low (0 volts) the corresponding bit will be 0. For example for Port D, PIND is address 0x30. One address (named PORTx) can be used to write data to output lines. If a bit is a one the corresponding line will be pulled high (3 volts). If a bit is a zero the corresponding line will be pulled low (0 volts). For example for Port D, PORTD is address 0x32.
Its not a desirable on general purpose machine with multiple processes because it stop the CPU being used for other pusposes.
A compiler might realize the loop is pointless and remove it.
#include <stdio.h>
#include <stdlib.h>
typedef struct purchase purchase;
typedef struct item item;
typedef double price;
typedef long barcode;
struct purchase {
item *what;
int how_many;
purchase *next;
};
struct item {
char *item_name;
price item_price;
barcode item_barcode;
item *next;
};
enum {
MAX_INPUT_LINE_LENGTH = 1024
};
void print_bill(purchase *purchase_list);
purchase *add_purchase(barcode code, purchase *purchase_list, item *item_list);
purchase *find_purchase(item *i, purchase *purchase_list);
item *add_item(item *item_list);
item *find_item(barcode code, item *item_list);
void *salloc(size_t size);
void read_to_newline(void);
int
main(void) {
char command[MAX_INPUT_LINE_LENGTH];
purchase *purchase_list = NULL;
item *item_list = NULL;
printf("Kensington Kwiki-Mart Billing System\n");
while (1) {
printf("Enter Command: ");
if (fgets(command, MAX_INPUT_LINE_LENGTH, stdin) == NULL)
return 0;
if (strcmp(command,"bill\n") == 0) {
while (1) {
barcode code;
printf("Enter barcode: ");
scanf("%ld", &code);
read_to_newline();
if (code == 0)
break;
purchase_list = add_purchase(code, purchase_list, item_list);
}
print_bill(purchase_list);
} else if (strcmp(command, "price\n") == 0) {
item_list = add_item(item_list);
} else {
printf("Unknown command - legal commands are bill and price\n");
}
}
return 0;
}
void
print_bill(purchase *purchase_list) {
price total = 0;
purchase *p;
for (p = purchase_list; p != NULL; p = p->next) {
price x = p->how_many * p->what->item_price;
total += x;
printf("%dx %s @$%.2f = $%.2f\n", p->how_many, p->what->item_name, p->what->item_price, x);
}
printf("Total: $%.2f\n", total);
printf("Thank for Shopping at Kensington Kwiki-Mart\n");
}
purchase *
add_purchase(barcode code, purchase *purchase_list, item *item_list) {
purchase *p;
item *i;
i = find_item(code, item_list);
if (i == NULL) {
fprintf(stderr, "Unknown barcode\n");
return purchase_list;
}
p = find_purchase(i, purchase_list);
if (p != NULL) {
p->how_many++;
return purchase_list;
}
p = salloc(sizeof (purchase));
p->what = i;
p->how_many = 1;
p->next = purchase_list;
return p;
}
purchase *
find_purchase(item *i, purchase *purchase_list) {
purchase *p;
for (p = purchase_list; p != NULL; p = p->next)
if (p->what == i)
return p;
return NULL;
}
item *
add_item(item *item_list) {
barcode code;
char buffer[MAX_INPUT_LINE_LENGTH];
item *i;
printf("Enter barcode: ");
scanf("%ld", &code);
read_to_newline();
i = find_item(code, item_list);
if (i != NULL) {
printf("Enter new price for %s: ", i->item_name);
scanf("%lf", &(i->item_price));
read_to_newline();
return item_list;
}
i = salloc(sizeof (item));
i->item_barcode = code;
printf("Enter name of the item: ");
if (fgets(buffer, MAX_INPUT_LINE_LENGTH, stdin) == NULL || strlen(buffer) == 0) {
fprintf(stderr, "Can not read name\n");
exit(1);
}
buffer[strlen(buffer) - 1] = '\0'; /* remove '\n' */
i->item_name = salloc(strlen(buffer) + 1);
strcpy(i->item_name, buffer);
printf("Enter price: ");
scanf("%lf", &(i->item_price));
read_to_newline();
i->next = item_list;
return i;
}
item *
find_item(barcode code, item *item_list) {
item *i;
for (i = item_list; i != NULL; i = i->next) {
if (i->item_barcode == code)
return i;
}
return NULL;
}
void *
salloc(size_t size) {
void *m = malloc(size);
if (m == NULL) {
fprintf(stderr, "postcode_server: out of memory - attempting to malloc %d bytes\n", (int)size);
exit(1);
}
return m;
}
void
read_to_newline(void) {
int c;
while (1) {
c = getchar();
if (c == '\n' || c == EOF)
return;
}
}