.. _c-lab-1: ********************** Lab 1: Factorial ********************** .. include:: /includes/prolog.inc .. include:: ../c-urls.rst .. contents:: Table of Contents You will practice using what you've previously learned in your programming classes to get comfortable working in C again. You will use common programming principles, such as variables, constants, branching, loops and functions to complete this assignment. .. hint:: Write and compile code online at |ide.judge0.com|! Overview ========== You will create a C program that displays the factorial of a number. The |factorial| of a number is the product of all positive integers less than or equal to *n*: For example, 5! is 5 * 4 * 3 * 2 * 1 = 120 Task 1: Create a Simple Factorial Program ========================================== You will create a simple program that calculates the factorial of a given number. #. Start with the command line template from :ref:`c-templates`. a. Wait till the next step to set the value from the command arg. #. Focus on developing the algorithm before adding complexity. #. Create a function with this prototype: .. code-block:: C int get_factorial(int); #. Print the result in ``main()``. Sample output ------------- .. code-block:: bash 5! is: 120 Task 2: Accept the Value from the Command Line =============================================== It is not common to prompt users for input when writing low-level code. Instead, data is passed into the program through parameters or arguments. #. The program should accept a single integer parameter. #. Check the number of args. If the arg is missing, generate the following message and exit gracefully. .. code-block:: C usage: factorial integer .. note:: Remember to use function ``atoi(string)`` to convert the input arg to an integer. Sample output ------------- .. code-block:: bash ./factorial usage: factorial integer ./factorial 5 5! is: 120 Task 3: Process Improvements ============================== The program works but is error-prone and does not use resources efficiently. The return type based on the function prototype of ``int get_factorial(int);`` is not appropriate because a factorial value must be a positive integer. The default data types in C are signed. Furthermore, entering an integer that is too large or a negative value will produce inaccurate results. .. code-block:: bash ./factorial 86 86! is: 0 ./factorial 29 29! is: -1241513984 ./factorial -8 -8! is: 1 Test Cases ---------- #. Use an |online factorial calculator| to determine the result of 20!. #. Try calculating the factorial of 20 in your program. a. What value did you get? Was it negative? If so, what could cause that? #. Determine the maximum integer value used to calculate the factorial for types: .. code-block:: text short: _____________ unsigned short: _____________ int: _____________ unsigned int: _____________ long: _____________ unsigned long _____________ Resource Management -------------------- We should use the appropriate data types for the size of our values. #. Chose an unsigned |C data type| that you want to use for the factorial result. #. Change the data type in the function prototype to use that type. .. code-block:: C type get_factorial(int); #. Verify that your program produces the correct results up to the maximum value. .. code-block:: C :caption: Example using type ``char`` (0-255) // Prototype char get_factorial(int); // Output 5! is: 120 6! is: -48 Error Handling --------------- We should prevent invalid input by checking the size before performing the calculation. It is not enough to add error handling before calling the function. We need to add error handling inside of the function. We can't trust that the caller will check the input value. #. Determine the largest integer value that a user can enter for your chosen data type. For example, a type ``char`` will hold the correct results up to 5! (120). 6! is 720, which exceeds an 8-bit value. #. Create a global ``const`` of the type above ``main()`` that contains the maximum input value for your data type. - Type the name of the ``const`` variable in ALL_CAPS to follow the common C style guide. #. Return ``0`` from function ``get_factorial()`` if the value is too large or a negative value. .. hint:: Use the ``const`` instead of hard-coding the integer value. #. Generate an error message if the user enters a value that is too big. Inform the user of the largest value possible for your program. Sample output ------------- .. code-block:: bash ./factorial 8 Error. '8' is out of range. Accepted input is a positive integer from 0 to 5. ./factorial -5 Error. '-5' is out of range. Accepted input is a positive integer from 0 to 5. ./factorial 5 5! is: 120