This is an old revision of the document!
Corning Community College
CSCS1320 C/C++ Programming
~~TOC~~
To implement a programmatic solution (ie simulation) of a real life process- the mental math trick of subtracting certain potentially large numbers from left to right.
In addition to the new skills required on previous projects, to successfully accomplish/perform this project, the listed resources/experiences need to be consulted/achieved:
The allure of using (and learning) a programming language is to be able to effectively use it to solve problems, which in and of themselves are simulations of some process we can do in “the real world”.
In this case, we will be writing a program which will implement the mental math techniques for subtracting certain numbers from left to right– seemingly against the grain from everything we've been taught.
This trick's full name is “All from Nine, the Last from Ten”, and refers to a central detail of the process we will be undertaking.
For starters, let us try it out:
1000 - 941 ==== 059
The thing is, we aren't going to be solving this the usual way. We're going to do it from left to right. So, a walkthrough of what just happened:
Clearly, there are some prerequisites that need to be met in order to use this trick:
Try your hand at another:
1000000000000000 - 928573956013453 ================
Go ahead and try it (work it out on paper).
The answer is: 071426043986547
The task at hand can benefit from loop and array assistance.
For instance, taking the number input and processing it so each digit occupies its own array element would facilate your efforts in the overall task– a process strongly resembling some of the work you had to do in the mbe1 project to get your input ready for the multiply by 11 activity.
As indicated, this task shares many attributes with the mbe1 project; in fact, the mental math process itself may be slightly simpler. That affords us the opportunity to introduce and learn about further programming optimizations, without the concurrent burden of new concepts.
Specifically, we will look at modularizing aspects of our solution, using functions, to make for a cleaner, more organized codebase.
We've been using functions all along (everytime you use fprintf() or fscanf(), for instance), but the value is not just in using pre-existing ones, but also in making our own to use.
Like variables, functions need to be declared.
We can declare them at various scopes (file/global, block/local)… if you wish for the function to be accessible by all functions within a program, you will want to declare it with a global scope.
If a particular function is only to be used by a specific function, and no others, you can opt to declare it local scope (ie within the function that will be calling it).
A function is basically a module or subroutine. It is a mini-program, focusing on the performing of a particular process.
Like a program, it takes input, does processing, and provides output.
Unlike a program, its input may not come from the keyboard, but instead from particular variables, and may not send output to the screen, but instead channel output in a way that it can be stored into a variable.
This distinctions aside, a function can in many ways be viewed as a micro- or sub-program/routine. We use functions to assist us in making our code more readable/organized/navigable.
Keeping everything in ONE file, ONE big function in that one file, is rather monolithic. In time, with sufficiently large programs, such an arrangement would become a tad unwieldy. So functions help to keep our focus short yet attentive.
To create a function we must first declare (or prototype) it. This needs to happen BEFORE said function is ever used (just as with variables- you must declare a variable before it is first used, otherwise the compiler yells).
A function, in many ways, is like a programmable variable (or is a variable with programming attached).
As such, it has a return value of a type (the function's output), a name, and parameters (input).
We see this with main()… here are two variations of a main() function declaration (technically also the start of the definition as well, in the case of main()):
int main()
In this example, we see the declaration of main() where it has a return value of int, meaning, upon completion, main() will return a value corresponding with an int data type (also in main()'s case, being the first function run, we tend to return a status code to the operating system– 0 for success, non-zero for some sort of error or deferred success).
main(), in this case, takes no parameters (just an empty set of parenthesis)… due to this, we refer to this function as a parameterless function. A function without parameters. Without input.
Now: this is technically a different form of input and output than you are used to. Input doesn't ALWAYS have to come from the keyboard, nor does output ALWAYS have to go to the screen. Input instead is desired informating being acquired for the process at hand, and output is the byproduct of performing the operation. Sometimes this means keyboard input and screen output- but not always.
Additionally, with or without parameters, we can always perform additional input (and output) within a given function, through the use of various input and output methods (like fprintf()/fscanf()).
int main(int argc, char **argv)
In this case, our main() function actually takes parameters- two, in fact:
This function takes two parameters, two pieces of input, available to us in the form of variables, by those names, of those types. We make use of them as we need to in accomplishing the program at hand.
So, when we wish to create functions of our own, we need:
For example, let us make a sum() function. Here would be a likely prototype (we'd place it above main()):
int sum(int *, int);
A function prototype (vs. its definition) will have a terminating semi-colon, as you see above.
In our case, our sum() function has the following:
Our sum() function will take an integer array (denoted by the int pointer above), and a size (the second, regular int).
Now, parameter order very much matters. In our case, an “int *” came first, followed by an “int”… we need to be mindful of this order to successfully call and use the function.
While a function prototype is technically optional (you can put the definition in place of the prototype– we just often use prototypes to further allow organization), we MUST have a function definition. This is nothing short of the code that dictates what operations the function in question will perform.
Our sum() function will be defined (below the main() function) as follows:
int sum(int *array, int size) { int result = 0; int i = 0; for (i = 0; i < size; i++) result = result + array[i]; return(result); }
Once we've declared (prototyped) and defined our function, now all we have to do is use it! When you make use of a function, we refer to it as calling. We call the function, by name, providing and required parameters, and capturing any return value as we see fit.
Here would be an example of calling the above-mentioned sum() function:
int scores[4]; int tally = 0; scores[0] = 88; scores[1] = 47; scores[2] = 96; scores[3] = 73; tally = sum(scores, 4);
Note, that it is rather important to match the type and order of parameters. Due to the nature of the array (especially the form of array declaration) used, certain pointer-related details are being hidden from us, giving somewhat of a false impression. Further discussion about pointers will begin to shed light on that.
It is your task to write an optimized version of your multiply by eleven program that will use arrays and loops to enable you to enhance and expand the functional capabilities of your program. No longer will you be limited by 1-, 2-, or 3-digit numbers, but you will be able to input up to 8-digit numbers and have your program successfully determine the result (and 8 is merely an arbitrary value I picked, you should easily be able to up it to the tens of thousands and experience no change in functionality) – actually, our 8-digit limit is considering a data type limitation… the maximum size of an int: signed ints can have a maximum value of 2.4 billion, so unless we change to a different data type (or different method of inputting the source number), this will be our limitation.
Your program should:
Several operating behaviors are shown as examples.
An eight digit value:
lab46:~/src/cprog/mbe1$ ./mbe1 Enter value: 31415926 Digits detected: 8 Obtaining unique digits, storing in array... digit[0] = 6 digit[1] = 2 digit[2] = 9 digit[3] = 5 digit[4] = 1 digit[5] = 4 digit[6] = 1 digit[7] = 3 Applying process... result[0] = 6 + 0 + 0 (sum of 6, carry out of 0) result[1] = 2 + 6 + 0 (sum of 8, carry out of 0) result[2] = 9 + 2 + 0 (sum of 1, carry out of 1) result[3] = 5 + 9 + 1 (sum of 5, carry out of 1) result[4] = 1 + 5 + 1 (sum of 7, carry out of 0) result[5] = 4 + 1 + 0 (sum of 5, carry out of 0) result[6] = 1 + 4 + 0 (sum of 5, carry out of 0) result[7] = 3 + 1 + 0 (sum of 4, carry out of 0) result[8] = 3 + 0 + 0 (sum of 3, carry out of 0) Displaying result... 31415926 x 11 = 345575186 lab46:~/src/cprog/mbe1$
Next, a four digit value:
lab46:~/src/cprog/mbe1$ ./mbe1 Enter value: 7104 Digits detected: 4 Obtaining unique digits, storing in array... digit[0] = 4 digit[1] = 0 digit[2] = 1 digit[3] = 7 Applying process... result[0] = 4 + 0 + 0 (sum of 4, carry out of 0) result[1] = 0 + 4 + 0 (sum of 4, carry out of 0) result[2] = 1 + 0 + 0 (sum of 1, carry out of 0) result[3] = 7 + 1 + 0 (sum of 8, carry out of 0) result[4] = 7 + 0 + 0 (sum of 7, carry out of 0) Displaying result... 7104 x 11 = 78144 lab46:~/src/cprog/mbe1$
Finally, a five digit value:
lab46:~/src/cprog/mbe1$ ./mbe1 Enter value: 56789 Digits detected: 5 Obtaining unique digits, storing in array... digit[0] = 9 digit[1] = 8 digit[2] = 7 digit[3] = 6 digit[4] = 5 Applying process... result[0] = 9 + 0 + 0 (sum of 9, carry out of 0) result[1] = 8 + 9 + 0 (sum of 7, carry out of 1) result[2] = 7 + 8 + 1 (sum of 6, carry out of 1) result[3] = 6 + 7 + 1 (sum of 4, carry out of 1) result[4] = 5 + 6 + 1 (sum of 2, carry out of 1) result[5] = 5 + 1 + 0 (sum of 6, carry out of 0) Displaying result... 56789 x 11 = 624679 lab46:~/src/cprog/mbe1$
The execution of the program is short and simple- obtain the input, do the processing, produce the output, and then terminate.
To successfully complete this project, the following criteria must be met:
To submit this program to me using the submit tool, run the following command at your lab46 prompt:
$ submit cprog mbe1 mbe1.c Submitting cprog project "mbe1": -> mbe1.c(OK) SUCCESSFULLY SUBMITTED
You should get some sort of confirmation indicating successful submission if all went according to plan. If not, check for typos and or locational mismatches.