I am finished with my first assignment in a C prog 2 class. I am going to post it here and hopefully get some constructive criticism. This program is nothing really to shout about...adds and subtracts arbitrarily large numbers, not designed to handle negative numbers. I know that there is nothing earthshattering in here, but I have definitely learned a lot in the past two weeks. If some of you programming masters can take a look and provide me with some constructive criticism it would be much appreciated.

I will also attach this as a .c file

I am trying to improve my knowledge of C and programming in general, feel free to be brutal.

Code:// Wes Kendrick // BIGINT.C // THIS PROGRAMS ALLOWS FOR SIMPLE MANIPULATION OF LARGE INTEGERS. // THE USER CAN ADD, OR SUBTRACT TWO LARGE INTEGERS INPUT FROM THE KEYBOARD // THIS PROGRAM DOES NOT ALLOW FOR A NEGATIVE RESULT. THE SMALLER NUMBER WILL // ALWAYS BE SUBTRACTED FROM THE LARGER NUMBER WHEN SUBTRACTION IS THE OPERATION // DESIRED // This program was written in Dev-C++ 4.9.9.2, and is written strictly for use // on a PC. Not all functions used are assumed to be ANSI C #include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FALSE 0 #define ADD 1 #define SUBTRACT 2 #define QUIT 3 #define MAX 200 //Preconditions: the first parameter is string that stores // only contains digits, doesn't start with // 0, and is 200 or fewer characters long. //Postconditions: The function will read the digits of the // large integer character by character, // convert them into integers and place them in // nodes of a linked list. The pointer to the // head of the list is returned. struct integer* read_integer(); //Preconditions: p is a pointer to a big integer, stored in // reverse order, least to most significant // digit, with no leading zeros. //Postconditions: The big integer pointed to by p is // printed out. void print_bigint(struct integer *p); //Preconditions: p and q are pointers to big integers, // stored in reverse order, least to most // significant digit, with no leading zeros. //Postconditions: A new big integer is created that stores // the sum of the integers pointed to by p // and q and a pointer to it is returned. struct integer* add(struct integer *p, struct integer *q); //Preconditions: p and q are pointers to big integers, // stored in reverse order, least to most // significant digit, with no leading zeros. //Postconditions: A new big integer is created that stores // the absolute value of the difference // between the two and a pointer to this is // returned. struct integer* subtract(struct integer *p, struct integer *q); //Preconditions: Both parameters of the function are // pointers to struct integer. //Postconditions: The function compares the digits of two // numbers recursively and returns: // -1 if the first number is smaller than the second, // 0 if the first number is equal to the second number, // 1 if the first number is greater than the second. int compare(struct integer *p, struct integer *q); //Preconditions: Both parameters point to struct integer //Postconditions: Prints spaces so that the numbers are // aligned to the right //Preconditions: p, q, and answer point to struct integer, operation is // the operation to be performed //Postconditions: Formats the output void format_output(struct integer *p, struct integer *q, struct integer *answer, int operation); //Preconditions: choice, low, and high are all int...low is low bound of // acceptable input, high is high bound //Postconditions: Returns TRUE if input is valid, otherwise returns FALSE int valid_choice(int choice, int low, int high); //Preconditions: None //Postconditions: Retrieves the user choice from the keyboard and returns it int get_user_choice(); //Preconditions: how_many is an int, character is a char //Postconditions: prints out character how_many times void print_characters(int how_many, char character); //Preconditions: answer is of type struct integer, it has at least one // leading zero (because method of complements is used for // subtraction.) //Postconditions: All leading zeroes are removed, and the size // of answer is adjusted accordingly void remove_zeroes(struct integer *answer); struct integer { int *digits; int size; }; int main() { int choice, operation; struct integer *bigint1,*bigint2,*answer; // Run until user chooses to quit do { choice=get_user_choice(); if(choice !=QUIT) { system("CLS"); printf("Please enter the first number: "); bigint1=read_integer(); printf("\nPlease enter the second number: "); bigint2=read_integer(); // Executes users choice switch(choice) { case ADD: answer = add(bigint1,bigint2); operation=ADD; break; case SUBTRACT: answer = subtract(bigint1,bigint2); operation=SUBTRACT; break; } // End switch format_output(bigint1,bigint2,answer,operation); system("PAUSE"); // Frees memory free(bigint1); free(bigint2); free(answer); } } while(choice!=QUIT); // End program printf("\n\nThank you for using the Big Int calculator!\n\n\n"); system("PAUSE"); return 0; } int get_user_choice() { int choice; system("CLS"); do { printf("1. Add two large integers\n2. Subtract two large integers\n3. Quit\n"); printf("\n\nEnter the number corresponding to your choice: "); scanf("%d",&choice); } // Checks for valid input in the while loop while(valid_choice(choice,1,3)==FALSE); return choice; } int valid_choice(int choice, int low, int high) { // Checks entry against bounds if(choice<low || choice > high) { printf("\n\nThat is invalid input.\n\n\n"); return FALSE; } else return TRUE; } struct integer* read_integer() { // Temporary string is created to read in the number from the user char string_num[MAX]; // Allocates memory for the struct integer, the address of this will be returned struct integer *temp= (struct integer *)malloc(sizeof(struct integer)); int counter; // Reads string scanf("%s",string_num); // Sets the size of the "integer" temp->size=strlen(string_num); // Dynamically allocates memory for the array of int temp->digits=(int *)(malloc((temp->size*sizeof(int)))); // Subtracts '0' from the character to get the digit...numbers are stored // with the least signifigant digit in index 0...this makes the code // slightly simpler for(counter=temp->size-1;counter>=0;counter--) temp->digits[temp->size-1-counter]=string_num[counter]-'0'; return temp; } struct integer* add(struct integer *p, struct integer *q) { // Allocates integer struct integer *answer=malloc(sizeof(struct integer)); int counter, carry=0; // If p is bigger than q, size the array in answer to the size of p if(compare(p,q)==1) { answer->size=p->size; // To simplify the code, we reallocate memory to the smaller number and set its // size to the size of the bigger one (if they are the same number of digits, nothing // happens q->digits=realloc(q->digits,p->size*sizeof(int)); for(counter=q->size; counter < p-> size; counter++) { q->digits[counter]=0; } } // Q is bigger, repeat process as above, but switch p and q else { answer->size=q->size; if(q->size != p->size) { p->digits=realloc(p->digits,q->size*sizeof(int)); for(counter=p->size;counter< q->size;counter++) p->digits[counter]=0; } } // Allocates enough memory for the array of int inside answer answer->digits=(int *) malloc(answer->size*sizeof(int)); // Runs counter for entire length of answer for(counter=0;counter< (answer->size);counter++) { // Sets answer->digits[counter] to the sum of the digit in the same index position // of q and p, as well as "carry" which is initialized to zero answer->digits[counter]=p->digits[counter]+q->digits[counter] + carry; // Number is greater than 9...must be reduced and reset carry if(answer->digits[counter]>9) { answer->digits[counter]%=10; carry=1; } else // Carry is zero, answer->digits[counter] is less than 10 carry=0; } // End of the for-loop, if carry is still 1, reallocate the size of answer->digits // to answer->size+1, and increment answer->size if(carry==1) { // turns digit from > 10 answer->size++; answer->digits=realloc(answer->digits,answer->size*sizeof(int)); // Will never be greater than one...(worst case example: 999+999 = 1998 (4 digits, leading 1) answer->digits[(answer->size-1)]=1; } // Reallocate p and q to their original sizes, only the added zeroes will be removed p->digits=realloc(p->digits,p->size*sizeof(int)); q->digits=realloc(q->digits,q->size*sizeof(int)); // address of answre is returned return answer; } struct integer* subtract(struct integer *p, struct integer *q) { // COMPLEMENTS stores the nines complement of a digit 0-9 int COMPLEMENTS[10], counter, difference;//, not_a_leading_zero, how_big_answer; // Required for complement method of subtraction, to add one to the result // This segment sets the attributes of one struct integer *one= (struct integer *)(malloc(sizeof(struct integer))); one->size=1; one->digits=(int *)(malloc(one->size*sizeof(int))); one->digits[0]=1; // Nines complement will hold the nines complement of the smaller number struct integer *nines_complement=(struct integer *)(malloc(sizeof(struct integer))); struct integer *answer; // Initializes the nines complement of digits 0-9 for(counter=0;counter<10;counter++) { COMPLEMENTS[counter]=9-counter; } // If p > q if(compare(p,q)==1) { // Difference will represent the number of additional digits that must // be added to make both numbers the same size difference=p->size - q->size; // sets nines_complement->size to the bigger numbers size nines_complement->size=p->size; // Allocates memory for the int array inside nines_complement nines_complement->digits=(int *)(malloc(nines_complement->size*sizeof(int))); // Sets all "unaccounted for digits" to 9...counter stops when it equals the difference in // size between nines_complement and the smaller number for(counter=nines_complement->size-1;counter>=(nines_complement->size-difference);counter--) { nines_complement->digits[counter]=9; } // sets the rest of the "accounted for digits" to the respective digit in the smaller of // the two numbers (in this case q) for(counter=nines_complement->size-difference-1;counter>=0;counter--) { nines_complement->digits[counter]=COMPLEMENTS[q->digits[counter]]; } // This is the method of complements, the intermediate step answer is set to // the sum of the larger number and the nines complement of the smaller number answer=add(nines_complement,p); } // In this case, p is smaller (or equal to) q...same logic as above except the // p's and q's have been switched else { difference=q->size - p->size; nines_complement->size=q->size; nines_complement->digits=(int *)(malloc(nines_complement->size*sizeof(int))); for(counter=nines_complement->size-1;counter>=(nines_complement->size-difference);counter--) { nines_complement->digits[counter]=9; } for(counter=nines_complement->size-difference-1;counter>=0;counter--) { nines_complement->digits[counter]=COMPLEMENTS[p->digits[counter]]; } answer=add(nines_complement,q); } // Second to last step of complements method, one is added to answer answer=add(answer,one); // Finished with nines_complement and one free(nines_complement); free(one); // We know that the size of answer has been incremented by one, and this new // digit holds a 1...final step of this algorithm is to remove the one. answer->digits[(answer->size-1)]=0; // Removes leading zeroes from answer remove_zeroes(answer); return answer; } void remove_zeroes(struct integer *answer) { // First digit will be a zero int not_a_leading_zero=0, counter; // Runs until counter > 0 because if answer is 0 we want it left that way for(counter=answer->size-1;counter>0;counter--) { if(answer->digits[counter]==0 && not_a_leading_zero==0) // Size of answer is smaller answer->size--; else not_a_leading_zero=1; } // Reallocate memory for answer, only the leading zeroes will be removed answer->digits=realloc(answer->digits,answer->size*sizeof(int)); } void print_bigint(struct integer *p) { int counter; // Since the number is stored in reverse order, we print it out in reverse order // to get the number as it should appear for(counter=p->size-1;counter>=0;counter--) { printf("%d",p->digits[counter]); } } int compare(struct integer *p, struct integer *q) { int counter; // If p has more digits then it is larger if(p->size>q->size) return 1; // if p has fewer digits then p is smaller if(p->size<q->size) return -1; for(counter=q->size-1;counter>=0;counter--) { // If any digit from p is greater than the digit in the same place of q // is larger, then p is larger if(p->digits[counter]>q->digits[counter]) return 1; // If any digit from q is greater than the digit in the same place of p // then q is larger if(q->digits[counter]>p->digits[counter]) return -1; } // Digits are equal return 0; } void format_output(struct integer *p, struct integer *q, struct integer *answer, int operation) { int counter, difference=0; printf("\n"); switch(operation) { case ADD: // If p is greater than q, then print p and print spaces equal to the // difference in size of p and q...this is strictly aesthetic if(compare(p,q)==1) { print_bigint(p); printf("\n+\n"); print_characters(p->size-q->size,' '); print_bigint(q); } else { // If q is larger, then we print spaces, then print p, then print q print_characters(q->size-p->size, ' '); print_bigint(p); printf("\n+\n"); print_bigint(q); } printf("\n"); print_characters(answer->size,'-'); break; // The specs for the program do not allow for negative numbers...this uses // the same logic as above, only prints the larger number on top of the smaller // number. Since the result of subtraction can have a variety of sizes, we set // difference to the larger numbers size minus the size of the answer case SUBTRACT: if(compare(p,q)==1) { print_bigint(p); printf("\n-\n"); print_characters(p->size-q->size,' '); print_bigint(q); printf("\n"); print_characters(p->size,'-'); difference=p->size-answer->size; } else { print_bigint(q); printf("\n-\n"); print_characters(q->size-p->size, ' '); print_bigint(p); printf("\n"); print_characters(q->size,'-'); difference=q->size-answer->size; } break; } // End Switch printf("\n"); // Prints spaces to format the answer, this will always be zero // in the case of addition print_characters(difference,' '); print_bigint(answer); printf("\n\n"); } void print_characters(int how_many, char character) { int counter; // Prints character n times for(counter=0;counter<how_many;counter++) printf("%c",character); }