Table of Contents
Introduction to Structured Programming
- The C programming language was designed to allow the programmer to apply a structured approach to software development.
- Structured programming allows the software engineer and programmer to build easy-to-maintain software.
- The following is an example of how structured programming simplifies the coding process:
//structuredC
//First Code in Kagirison.com
//Preprocessor directive to add files from the standard input and output
#include <stdio.h>
//Writing the first function that marks the start of an executable program
int main(void)
{
printf("Welcome to Kagirinoesis, the educational section of Kagirison! \a\n");
printf("Welcome to Kagirinoesis, the educational section of Kagirison! \\ \"");
}
//End of the first function
//End of Code
- The symbols // indicate the beginning of a comment, and this comment is never processed by the compiler.
- A comment is used by the programmer to document the program, and this in turn improves the readability of the code by a human. For a long comment which is usually a multi-line comment, the symbol used is:
/*
Long multi-line comment
Long multi-line comment
Long multi-line comment
*/
- Good programming practice requires that the first comment in any program should be the name (i.e filename) of that program, and the second comment should describe what the program intends to achieve. In this example, the filename is structuredC written using camel casing, and this program is just meant to show the first code written by the Kagirison as a programmer.
- A full stop should not be used in a single-line comment.
- The code shown above has 18 lines of code (abbreviated as LoC), with the first two lines being comments.
- The #include in line 6 is the C preprocessor directive.
- The C preprocessor directive is an instruction sent to the compiler to process a command before it can begin the actual compilation of the program. It is also described as the preprocessor command.
- The preprocessor serves to process input data (normally a directive) and then deliver output data to the compiler. This output data is described as preprocessed data (because it has been worked on by the preprocessor). The preprocessor is also called the precompiler.
- The symbol # alerts the compiler of a preprocessor directive. The command is concatenated to this symbol without any space separating the command directive from the alert e.g #include which instructs the compiler to include contents of a standard input and output header into the code.
- The preprocessor directive is not a statement and thus it does not terminate in a semicolon (;).
- The command when concatenated to the alert becomes a directive. The syntax of the directive is written as #(command) e.g #include, #define, #if, #else, #elif, #endif, #line, #error, #warning, #region, and #endregion. This directive instructs the precompiler on what data to import, as well as how it should handle the program code in the file.
- To write a full C preprocessor directive, the directive is combined with a built-in function or file to be imported into the code e.g #include <stdio.h> which imports the contents of the header files of the standard input/output (stdio) library. Thus, the syntax for the preprocessor directive is as follows:
#directive <precoded file with its extension e.g header (.h) file>
- Among the stdio.h content imported is library functions such as printf.
- Lines 3,5,7,9,15, and 17 are empty; and they are described as white space.
- A white space can be an empty line or an empty space before a character (which can be created using either the tab button [thus becoming a tab character] or the space bar [thus becoming a space character]). The compiler ignores the whitespace just as it ignores comments. This means that the compiler only acts on only 12 LoC in the code above. Nonetheless, both comments and white space make the code more readable to a human.
What is a Function?
- Line 10 initiates the executable part of the program by introducing a program building block called a function. So, what really is a function, what are its purposes, and how does it work?
- The function is the smallest building block of a program that can initiate a programming task and complete it. For this reason, the function is described as a subprogram.
- Because C is an imperative programming language that requires the program to complete a task using a set of instructions, then the function uses a step-by-step approach to implement its sets of instructions with the first instruction being implemented before the next instruction can be implemented. This creates a sequential process for completing the task, and for this reason, this function is also called a procedure.
- This procedure/function can be used in other parts of the program, and for this reason, the function needs to be named so that it can be easily called (i.e referenced) for reuse in other parts of a program. This reusable function is described as a callable unit. The naming of this callable unit is known as defining the function.
- If this function can prove that it has completed its task by returning a specific value e.g 1 for a completed task and 0 for an aborted task, then it is called a routine.
Purposes of a Function
The 7 main purposes of a function are:
- Encapsulation of Tasks: A function does encapsulate a task or a set of related tasks. As described, the function is a set of programming code that initiates and completes a task or a group of related tasks. This is important for a callable unit because it allows one to call a function to complete tasks thus reducing the work of coding a program. Likewise, this encapsulation of tasks within a single block of code is what defines a function.
- Code Reuse: The function allows for code reuse. This is important if one is writing a large program where a specific block of code needs to be used repeatedly. It is not advisable to copy and paste the block of code throughout the file because the process is not error-free (e.g one can omit characters when copying a code) and if the original block of code is changed, then one is forced to change all the code blocks that have been copy-pasted.
- Program Segmentation: Functions allow for the segmentation of a program by separating unrelated tasks. This segmentation allows for different programmers to work on different aspects of the program thus reducing the program development time, besides creating a source code that is elegant and easy to maintain.
- Shareability: Functions are portable and can be shared. A single function can be used by different programmers to execute tasks that the function was built for. This shareability of the function is a property of its portability. The function is portable because it is a standalone subprogram that can be duplicated anywhere throughout the program. Also, the function can be stored in an external library where it can be called by different programs.
- Simplifies Code Debugging: The use of functions simplifies the process of code debugging and testing. A code that is not easy to read because it is tangled and lacks structure is called a spaghetti code. Functions introduce structure into a code, and this improves readability as well as allows for unit testing of the code. A test performed on a single function to ensure that it works as it should is called a unit test. If a function fails a unit test, the programmer can easily read through the function and identify errors and correct them. This process is called debugging.
- Logic Abstraction: The function is a subprogram that serves as the logic for handling data. This logic is separate from the data, and this way, the function separates the program logic from the data that it processes. This is described as abstraction of logic or simply, logic abstraction. It allows for the logic to process different user data that are supplied to the function. Equally, logic abstraction is key to secure C programming as it allows for the safe handling of formatted user input data without suffering access violation (which is explained later)
- Acceleration of Software Development: Built-in functions are used to accelerate the process of program development. Each programming language comes with a set of built-in functions that can be called in the program where they are expected to work seamlessly with user-generated functions.
The Main Function
- A function that does not return a value is called a subroutine. The subroutine is described as a void function when it completes its set of instructions.
- Each program needs functions to operate.
- It is good practice to precede any function with a comment about the purpose of that function.
- In the code above, the function is defined as main (and can simply be called the main function). The main function is the principal subprogram of any C program because the compiler begins executing the program when it reaches the main procedure/function. This function is a routine because it returns a value, and the information that it returns is indicated by the keyword int that precedes the name of the function. This keyword indicates the data type, which in this case is an integer.
Syntax of a Function
- The function can receive information, and the source of this information is stated inside the brackets () that are concatenated with the name of the function. In the sample code, the (void) indicates that the function does not receive information.
- The code of the function is encapsulated within the curly brackets/braces {}.
- Any information encapsulated inside these braces constitutes the body of the function, with the opening (left) brace { marking the start of the body which is then closed by the closing (right) brace }. The body of the function and its encapsulating braces constitute the function block. In the sample code, lines 11-14 constitute the function block.
- The proper syntax for writing a function in C is:
keyword functionName(data_source)
{
body_of_function
}
- In the body of the function, another function can be used if it is paired with an argument.
- The argument is the data that the function is required to act on, and is contained within brackets () as such: function(argument); with the semicolon serving as the termination control character.
- The semicolon ; affirms that the function and argument can complete an intended task or set of tasks. This means that if there is no semicolon, then it cannot complete any task.
- The function, its argument, and termination semicolon form a complete statement. It is for this reason that the statement is said to be complete if it terminates in a semicolon. Thus, the semicolon is described as the statement terminator.
- As mentioned, the function serves to process and output information. The output information is defined in the body of the function as the output statement which is delivered when the computer completes a specific set of tasks as set out in the function. Thus the output statement is confirmation that the computer has completed an action that has been assigned to it.
- In the sample code, printf is a function that instructs the compiler to display the argument on a monitor/screen as a string of characters. This string of characters is described as the message or literal, and they are enclosed inside double quote (quotation) marks “”.
- In this code, the literal is “Welcome to Kagirinoesis, the educational section of Kagirison! \n”. The printf function instructs the compiler to print a formatted (hence the f in printf) literal on the display device, and thus the screen will display the following: Welcome to Kagirinoesis, the educational section of Kagirison!
- This shows that the syntax for a message that is to be displayed on the screen can be written as:
function(“output statement”);
Escape Character, Linker, and Escape Sequence
- In the sample code, there are the characters \n that are not displayed on the screen. This is because the backslash \ instructs the compiler to interpret the next character differently from how it has interpreted previous characters. For this reason, the backslash is called an escape character. This escape character needs to be concatenated with another character to form an escape sequence because the compiler can only execute the command of an escape sequence, not that of an escape character. Thus \n is an escape sequence, and it instructs the compiler to move the cursor to a new line.
- Some escape sequences that are found in this programming language are:
- \t which instructs the compiler to move the cursor one horizontal tab space to the right.
- \v instructs the compiler to move the cursor to one vertical tab space.
- \a instructs the compiler to produce an audible audio alert or visual alert. It does not impact the cursor position.
- To insert a backslash or closing quotation marks in a literal/message, the following characters are used \\ (double backslashes) and \” (backslash followed by the double quote mark). For example, “Welcome to Kagirinoesis, the educational section of Kagirison! \\ \”.” outputs Welcome to Kagirinoesis, the educational section of Kagirison! \ “.
- The printf in the sample code is called a built-in function because it is a function that comes already coded in the Standard C Library. It is thus described as a standard library function. The compiler does not know where the location of this function is in the library, and so what it does is it creates space for the printf function when it compiles the printf statement. To fill this space, the compiler engages the linker which searches the library and locates the function, and then imports its code into this space. This process of locating a library function and importing its code into the body of the (user-generated) function is called a call.
- The linker searches for the library function based on its name, and thus a misspelled name of a library function will generate an error because the misspelled function is not found in the library.
- After inserting the appropriate calls in the compiled program code, the linked program becomes an executable that can be run on a computer.
- It is recommended that the body of the function is indented to improve code readability and create a logical code structure. One can use the tab key for indentation, but it is preferable that one uses 3 spaces instead a tab space (i.e 3 space characters are preferable to a tab character).
C Boilerplate and Preparing to Build a Simple Calculator using Standard C Library Functions
- The function can receive input from the standard input i.e keyboard and deliver the result to the standard output i.e monitor. To do this, this function needs to use two calls from the standard C library – the scanf and printf calls.
- Scanf is a built-in function that obtains keyboard input data and then uses this data as values to be processed in the function’s statement. As expected, the statement syntax for the scanf statement should be:
scanf(arguments);
//Because one of this argument is the data that the user provides, the above statement can be written as
scanf("user_input_data_with_conversion_specification", argument);
//Conversion specification is necessary because the function can handle only specific data types
- A value is any character(s) that the user inputs into a program.
- To ensure that the scanf statement receives values from the keyboard, the user needs to be notified to enter the value and this requires the use of the printf built-in function as follows:
printf(“request user to enter values in the keyboard”);
- The above printf statement is called a prompt because it notifies the user that (s)he should complete the requested action(s).
- This prompt is combined with the scanf argument as follows:
printf(“request user to enter values in the keyboard”);
scanf(value included in argument);
- This information is enough to start building a simple calculator that will do basic arithmetic operations of addition, subtraction, division, and multiplication; as well as square the values and then add, subtract, and multiply these squared values. The calculator will also compute the average of two user values.
- To start building this calculator, the basic C program boilerplate is written down first. This is the basic C boilerplate that is used by Kagirison’s Kagirinoesis:
//Name of Program
//Purpose of Program
//Preprocessor Directive
#include <stdio.h>
//Main function of the calculator
int main(void)
{
body of function
}
//End of function
//End of program
- The boilerplate is the standard formatted code that must be included in any program. Because this is a C program, then its boilerplate is aptly called the C boilerplate.With the boilerplate ready, the body of the function can be coded. This is done and presented as the fully functional calculator code in this section. However, before coding the functions, the variable must be explained.
What is a Variable?
- Before creating a user function, the types of values that the user can enter into the function must be defined. This definition is based on the data type that is to be processed in the body of the function. For this calculator program, the values that are to be used are whole numbers, and thus they are defined as integers. The keyword used to define integers in C programming language is int.
- Because any value that is generated by the user can frequently change, they need to be stored in a memory space that allows for frequent changes of stored data. The location of this memory space is called a variable, and this variable needs to be named. Naming a variable is important because it allows for importing of its data when the variable name is called inside a function.
Variable Identifier, Definition, and Initialization
- The variable name is called its identifier. It must start with a lowercase letter, and it can be a multi-word identifier made up of two words concatenated together directly or through camel casing or separated by an underscore _. This identifier should not start with a number, underscore, nor capital letter. Because C language is case sensitive, the identifiers variable1 and Variable1 are recognized as two different identifiers. The reason for this is that the uppercase letter and lowercase letter of the same alphabet is assigned different bit values under the ASCII standard.
- A good identifier enhances program documentation and reduces the number of comments in the program.
- The variable can be initialized by assigning it a value using the assignment = operator e.g variable1 = 0. This means that if the user does not input any value, the value that is stored in the variable’s memory space is 0. Initialization of the variable is not mandatory. If a variable is not initialized, it is assigned a garbage value, which is the value that existed in the memory space allocated to it i.e it inherits the value that it found in its assigned memory location.
- In any function, the variable needs to be defined. Definition of a variable simply means assigning a name and data type to the variable. This ensures that only the right type of value is stored in the correct memory space (of the variable). It is mandatory that the variable is defined before it is used.
- Definition of a variable is sometimes described as variable declaration. Thus, defining a variable is considered to be declaring the variable.
- Variable declaration has 3 mandatory attributes:
- Name
- Type
- Value
- The syntax for variable definition is:
definedDataType variableName = assignedValue
- In the Simple Calculator program, there needs to be at least two variables so that any calculation can be done. These variables are defined as follows in the program:
int number1=0;
int number2=0;
(int is the definition of the data type, number1 and number2 are the two variable names, = is the assignment operator, and 0 is the assigned value to initialize the variable. The semicolon terminates the variable identity)
- When an input value is to be assigned to a variable that is used as an argument inside a function, then the variable name needs to be assigned an address operator and this is done by concatenating the ampersand symbol & to the left of the variable name as such: &variableName. This evaluates the syntax to:
function(argument1, &variableName);
- In the above function, the value assigned to argument1 is stored in the variable.
- In this Calculator code, &number1 is a valid argument.
Execution-Time Error, Access Violation, and Segmentation Fault
- The & is the address operator, and it directs the function to the location of the variable in memory. If this address operator is not used, the function cannot locate the variable which results in an execution-time error. In operating systems, this execution-time error is identified as an access violation because the function is trying to gain access to memory space without the required authorization. In other systems, this execution-time error is described as a segmentation fault.
- Arguments in a function are separated from each other using a comma.
Format Control String and Conversion Specification
- To control what type of data the user inputs as a value for a variable, the programmer needs to define the format control string.
- The format control string determines what types of user-generated values will be accepted by a function e.g to only accept whole numbers, the format control string used is “%d”.
- The format control string is made up of two parts – the conversion specification and the enclosing (double) quotation marks “”.
- The conversion specification is what determines the data type of the value that will be accepted by the function e.g %d is the conversion specification for whole numbers (also called decimals and denoted by d). This conversion specification is enclosed in quotation marks to yield the format control string “%d”. The syntax of format control string is:
“%conversionSpecification”
- When the user enter a value following a prompt, (s)he is required to send this value to the variable and this is called return. Usually, this return is performed by simply pressing the Enter key in the keyboard.
- It is recommended that the programmer explains to the user how to return his/her value when issuing the prompt e.g Enter value (press Enter when finished): . In this prompt, the prompt literal is Enter value: and the (press Enter when finished) instructs the user on how to return the input value to the program.
- Built-in functions like scanf and printf that require the user to interact with the program through a series of prompts are critical to interactive computing. In this form of computing, the prompts serve as dialogue between the user and the program.
- A keyword is a reserved word that has been assigned a special meaning by the compiler. For example, int is a keyword that means integer data type. A keyword cannot be used as an identifier of a variable.
Binary Arithmetic Operators
- A mathematical equation is a statement that expresses how inputs are combined to produce an output. It basically denotes a mathematical operation where a calculation is performed on one or two input values so as to produce a result, which is the desired output. For example, x + y = z is a mathematical operation that reveals that the inputs x and y are added together to produce the sum z. x and y are analogous to variables, and z is analogous to the output of a function. Basically, the equation shows the procedure whereby inputs are used to produce a new value which is the output.
- The input value in any mathematical operation is called an operand, and the symbol that represents the mathematical operation is called the operator. Therefore, + and = are the operators.
- The combination of operands and operators is called an expression.
- There are 2 main types of operators: the unary operator and the binary operator.
- The unary operator uses only one input value to yield an output e.g the additive inverse and the multiplicative inverse.
- In the additive inverse, an operand is added to the input value so as to get a sum of zero. Because this operand is the negative of the input value, then this unary operation is called a sign change operation. For example, 4 + (operand) = 0 reveals that the operand is -4. This additive inverse can be expressed as -x (the unary minus) for an input value of x, or be expressed as x (the unary plus) for an input value of -x.
- In the multiplicative inverse, the input value is multiplied by an operand so as to yield the product of 1 (as its multiplicative identity) e.g 4 x (operand) = 1, and thus the operand is ¼. It is also called a reciprocal operation. It is expressed as 1/x for an input value of x.
- The binary operator requires two operands (input values) to produce an output. The four basic types of binary operators are +, –, /, and ×; which denote addition, subtraction, division, and multiplication respectively. The = symbol is also considered as a binary operator because it relates the operands of any of the four aforementioned binary operators to an output i.e a+b=c.
- In C language, this = symbol is defined as the assignment operator. For an equal to operator, the symbol used is ==, e.g x == y.
- It is recommended that a single space character is placed before and after the operator so as to optimize readability by making the operator stand out in the expression e.g 2 + 2 = 4.
- The basic binary arithmetic operators in C language are:
- The operator + denotes addition.
- The operator – denotes subtraction.
- The operator * denotes multiplication.
- The operator / denotes division. Division by 0 (zero) leads to program termination, hence it creates a fatal error. In a non-fatal error, the program completes the task but outputs the wrong results.
- The operator % denotes modulus. Modulus is the remainder obtained following division e.g 5/2 = 2 remainder 1 (or 2 mod 1, or in C, 2 % 1).
- In the C program code, the programmer must express all equations in their straight-line forms, not in their standard notations as used in mathematical algebra. For example, 1/4 is used as the straight-line form of ¼.
- Parenthesis (brackets) are used in C language just as they are used in algebraic expressions. For example, x * (y + z) is the same as the natural notation x(y+z). The equation inside the brackets is solved first just as in standard linear equations.
Rules of Operator Precedence
C language is notable for its rules of operator precedence. Basically, this means that not all operators are treated equally. These rules are:
- The expression inside the parenthesis/brackets is solved first. If there is another expression nested in brackets inside this parenthesis, then the expression in the nested brackets is solved first. For example, in x * (y (a-b)+ z), (a-b) is solved first.
- Multiplication, division, and modulus operations have an equal level of precedence, and they are applied after any expression in parenthesis has been evaluated/solved. If the expression has several multiplication and division calculations, then the priority of precedence proceeds from left to right. For example, a * b / c = (a * b)/c This shows that the priority of precedence is determined by how the operators can be grouped. This grouping of operators is called associativity. Basically, this means that if the operands in the parenthesis are rearranged, the result will not be affected e.g x * y * z = (x * y) * z = x * (y * z). The parenthesis used this way is called redundant parenthesis as it can be eliminated without affecting the results.
- Addition and subtraction have an equal level of precedence, but at a lower level than the multiplication and division operations. If the expression has several addition and subtraction calculations, then the priority of precedence proceeds from left to right.
- The last binary operator that is evaluated is the assignment operator =.
- Understanding the aforelisted rules of precedence allows a programmer to write a complex equation in a straight-line form.
- C language lacks the exponentiation operator. Therefore, exponentiations are written in their straight-line form e.g 23 is written as 2 * 2 * 2. An alternative to the straight-line form is to use the built-in pow (power)function in the standard C library.
Building the Calculator and Using It
- The scanf in this program has two arguments – the format control string and the argument formed from the variable name.
- At this point, the calculator can be built.
- The first process is to import the C Boilerplate, and assign it the right descriptions. This is followed by coding the body of the main function. This results in the following code, which is an actual calculator program.
//Simple Calculator
//Calculator for performing simple binary operations, squaring of values, and averaging of values
//Preprocessor directive
#include <stdio.h>
//Main function of the program
int main(void)
{
//Definition of Variables
int number1 = 0; //Definition of the first variable
int number2 = 0; //Definition of the second variable
//Prompts of the function
printf("Enter the First Number: \a\n(then Press Enter to Continue)");//Request the user to provide a value for the first variable
scanf("%d", &number1);//Assign the value provided by the user to the first variable
printf("Enter the Second Number: \a\n(then Press Enter to Continue)"); //Request the user to provide a value for the second variable
scanf("%d", &number2);//Assign the value provided by the user to the second variable
//Conditional if Statements and their outputs
if (number1 == number2)
{
printf("First Number is equal to the Second Number, therefore their difference is 0. \n");
printf("First Number is equal to the Second Number, therefore their product is equal to the square of the either number. \n");
printf("First Number is equal to the Second Number, therefore their quotient is unity. \n");
}
if (number1 != number2)
{
printf("First Number is NOT equal to the Second Number. \n");
}
if (number1 == 0)
{
printf("First Number is Zero, therefore the its Square and any of its Product is 0. \n");
printf("First Number is Zero, therefore the Quotient of any of its division is 0. \n");
}
if (number2 == 0)
{
printf("Second Number is Zero, therefore the its Square and any of its Product is 0. \n");
printf("Second Number is Zero, therefore the Quotient of any of its division is 0. \n");
}
if (number1 > number2)
{
printf("First Number is larger than the Second Number, therefore their difference is a positive number. \n");
printf("First Number is larger than the Second Number, therefore their quotient is greater than one. \n");
}
if (number1 < number2)
{
printf("First Number is less than the Second Number, therefore their difference is a negative number. \n");
printf("First Number is less than the Second Number, therefore their quotient is less than one. \n");
}
//Calculations of sum, difference, product, and quotient
int sum = 0; //Definition of sum
sum = number1 + number2; // Addition of the variable gives the sum
printf("Their sum is %d \n", sum); // The sum is displayed on the screen
int difference = 0;
difference = number1 - number2;
printf("Difference is %d \n", difference);
int product = 0;
product = number1 * number2;
printf("Their product is %d \n", product);
double quotient = (double) number1 / (double) number2;
if (number2 != 0)
{
printf("Their quotient is %f \n", quotient);
}
else
puts("This operation is not allowed.");
double average = 0;
average = ((double) number1 + (double) number2)/2;//The averange of the two variables
printf("The average is %f \n", average);
//Calculation of Squares, Product of Squares, their Sum, and Difference.
int squarenumber1 = 0;
squarenumber1 = number1 * number1; //Square of the first variable
printf("The square of the first number is %d \n", squarenumber1);
int squarenumber2 = 0;
squarenumber2 = number2 * number2; //Square of the first variable
printf("The square of the second number is %d \n", squarenumber2);
//Sum of the square of the variables
printf("The sum of the squares of the first and second numbers is %d \n", squarenumber1 + squarenumber2);
//Difference of the squares of the two variables
printf("The difference between the first number and the second number is %d \n", squarenumber1 - squarenumber2);
//Product of squares of the two variables
printf("The product of the squares of the first and second numbers is %d \n", product*product);
}
//End of function
//End of Code
Basic Memory Concepts
- Each variable has a name, type, value, and memory space. This memory space holds the value of the variable.
- In the calculator program above, the memory space of number1 holds the value that the user inputs to the program e.g 33. Initially, the placeholder value in this space was 0, and when the user submits his/her value, the 0 is deleted and replaced with 33. This process of substitution of the value of a variable is described as destructive because the initial value is lost and the new value becomes the variable’s value. This process is destructive because a new value is written into the memory space.
- In the calculator code, the variable sum is obtained by adding the number1 and number2 variables as such: sum = number1 + number 2. If the values for the 2 operands are 17 and 23 respectively, then the value of the sum variable is: sum = 17 + 23 = 40. As can be noted, the function used the values of variable1 and variable2 without changing them. This is because the function read from the memory location, and this results in a nondestructive process that leaves the read variables intact.
- It can be concluded that writing into memory is a destructive process, while reading from memory is a nondestructive process.