Function exercise
Exercise:
Write a program to do mathematical operations such as addition, subtraction, multiplication, and division of integers.
You have to follow these two steps.
- Do all the mathematical operations in separate functions in a file called math.c
- Call the functions from the main.c to test them.
Basically, your project should contain two source files.
One is math.c, it is written by you. And inside the math.c you have to write functions to do the mathematical operations.
Another source file is main.c. It is written by someone else, and main.c uses functions of math.c.
Here you can use the concept of the header file. So, you write all the function definitions in the math.c, and you write all the function prototypes in a file called math.h, and then share that math.h with the main.c.
The implementer of main.c will come to know about the prototype of math.c supported functions by looking at math.h shared by the implementer of math.c.
I created a project called math. After that, let’s add two source files. Right-click on project math, click on New, go-to Source file, and I call this as main.c and click on Finish.
And I added another source file that is math.c.
So, math.c is excluded from the project. Don’t worry. For you, it may not be like this. To solve this, go to the properties, go to the C and C++ build, and uncheck the option Exclude resource from build. Then click Apply, Apply and Close, as shown in Figure 3.
In the math.c, we will write all the functions for our arithmetic operations. Before writing functions, let’s first create the function prototypes.
So, let’s create a first function prototype. Name it as math_add (this is a function name) and after that, give the parenthesis, and inside the parenthesis, write the input arguments. So, this function takes two arguments. It is used to add two numbers of integer type. So, int n1, and int n2.
It returns a result back to the caller. So, the type of the return value, let’s consider it as int. Then give the semicolon to terminate the function prototype.
int math_add(int n1, int n2); //This is a first function prototype.
After that, create the function prototypes for other functions. So, let me name it math_sub, math_mul, and math_div.
And for the subtraction also, I would like to use the same math_add prototype.
After that multiplication. n1 will be multiplied into n2. So, the result may exceed an int range. That’s why I would like to use the return type long long int.
For the division, here, n1 will be divided by n2, and the result may be float. So, two integer divisions can result in a float. But in ‘C,’ integer divisions result in integers, so they will not result in float, but we’ll see how to convert that into float.
These are the function prototypes. And let’s implement all these functions (Figure 4).
Let’s not keep those function prototypes inside math.c. So, for that create one more file called math.h. Let’s create that header file.
Right-click on the project, select New, and select Header file. After that, Give the header file name as math.h, select the option Default C header template, and click on Finish.
So, once you create the header file, this IDE automatically adds the macros you can see in Figure 6. These are called as include guards. So, you should make sure that your header file contains this include guards, so if the header file doesn’t contain this include guards, then you should write this include guards manually.
So, here #ifndef, #define, #endif is called a pre-processing or pre-processing directive of the ‘C’ compiler. And MATH_H can be any value, so it can be a set of any characters. So, it avoids multiple inclusion of the contents of the same header file in a project.
Now we are going to keep our function prototypes between these statements.
So, we go to math.c and cut the function prototype code from there, and let’s put that in math.h. So, these are also called exposed function prototypes because the main.c can include this, and it will come to know about the function prototypes of math.c functions.
#ifndef MATH_H_ #define MATH_H_ /*these are also called as exposed function prototypes */ int math_add(int n1, int n2); int math_sub(int n1, int n2); long long int math_mul(int n1, int n2); float math_div(int n1, int n2); #endif /* MATH_H_ */
Now let’s implement the functions. In math.c, let me just return n1+ n2. So, only one line of code. In math_sub, let me return n1 – n2.
In math_mul, let’s return n1 multiplied by n2. To multiply, you have to use the asterisk(*). This results in an integer value. Because n1 is an integer, and n2 is an integer, and if you multiply those two numbers, it will result in an integer.
Let’s move on to the math division. Here, let me want to do n1 divided by n2. And this is also integer division, so here we are dividing two integers. The result will be an integer. It will not be a float value. So, later we will see how to fix this.
int math_add(int n1, int n2) { return n1+n2; } int math_sub(int n1, int n2) { return n1-n2; } long long int math_mul(int n1, int n2) { return n1 * n2 ; } float math_div(int n1, int n2) { return )n1 / n2; }
Our math.c is completed.
Now let’s go to main.c. In main.c, first, let’s write the main function. And after that, let’s give the header file #include “math.h” because we will use those functions implemented in math.c. So, this is how you include a user-defined header file. Functions are written by the user, not given by the standard library. That’s why I have to include like this. I have to mention the name between the double-quotes. So, all the user-defined header files must be within two double-quotes. And let me include the standard library header file #include <stdio.h>.
After that, let’s use those functions. So, let me print those statements. printf(“Add,%d\n”, math_add(0x0FFF1111, 0x0FFF1111)); Let me print the result of adding two numbers, so here I use %d.
And here in the printf, I can directly call the math_add function. So, you have to call this function with two numbers. Let me write the first number in hex, 0FFF1111. This is a 4-byte value and positive value because the most significant bit is 0. That’s why this is a positive value. And after that, let me add another number in hex. So, let me give the same number. So here, math_add(0x0FFF1111, 0x0FFF1111) is a function call.
Note that you need not to terminate this function call with a semicolon here. It is not required. Because this is a complete ‘C’ statement, and a ‘C’ statement is terminated by a semicolon. And the math_add returns the result. So, that result will be printed with a format specifier %d.
#include <stdio.h> #include "math.h" int main(void) { printf("Add : %d\n",math_add(0x0FFF1111 , 0x0FFF1111 ) ); return 0; }
Let’s run the program and see the output (Figure 7). You can use a calculator to verify the output.
Suppose you want to print the function in hex format, use format specifier %X here.
#include <stdio.h> #include "math.h" int main(void) { printf("Add : %X\n",math_add(0x0FFF1111 , 0x0FFF1111 ) ); return 0; }
After that, let’s call multiplication on the same number. The multiplication of these two numbers will result in a bigger number, and it will be of size 8 bytes. That’s why I have to use the format specifier long long int. So, that is I64X. And now, let’s see how it goes.
#include <stdio.h> #include "math.h" int main(void) { printf("Add : %X\n", math_add(0x0FFF1111 , 0x0FFF1111 ) ); printf("Mul : %I64x\n", math_mul(0x0FFF1111 , 0x0FFF1111 ) ); return 0; }
Let’s run our code and see the output. This must be the correct answer. And also, let’s verify it in a calculator. We multiplied by the same number, which resulted in a very big number. The results are shown in Figure 9. Now you can see that the multiplication result is wrong.
So, it just printed the last 4 bytes, and the upper 4 bytes are actually discarded. That means there is an information loss.
The reason for that is, if you take a look into the math_mul function in math.c, here we do integer multiplication. Integer multiplied with integer results in an integer. So, now to solve this problem, you have to consider one among these numbers as long long int. That means you have to typecast one of the variables.
About typecasting, we’ll see later. But, let’s use typecasting to solve this issue here. Let’s change the type of this number to long long int. To casting, in front of the variable name, open the parenthesis and mention the data type name to which you want to cast, as shown Below.
Here I am casting to the math_mul variable. I’m changing the type of this variable to long long int. A long long int variable multiplied with int and results in long long int. So, now it should be good and more on a typecasting we’ll explore in the later lectures.
There are two types of casting. One is explicit casting, and another one is implicit casting. And this is explicit casting. That is, you are manually doing that.
After that, we use typecasting in math_div because an integer divided by integer results in an integer. So, you also have to consider this number as a float. So, you change it to float.
long long int math_mul(int n1, int n2) { return (long long int)n1 * n2 ; } float math_div(int n1, int n2) { return (float)n1 / n2; }
use the typecasting
In main.c, let’s write a printf statement to test the division, and the format specifier is %f for float, and let’s divide 100 by 8. So, now let’s run the program, and here you can see that we get the correct answer.
#include <stdio.h> #include "math.h" int main(void) { printf("Add : %X\n", math_add(0x0FFF1111 , 0x0FFF1111 ) ); printf("Mul : %I64x\n", math_mul(0x0FFF1111 , 0x0FFF1111 ) ); printf("Div : %f\n", math_div(100, 8)); return 0; }
Now the answer is correct. In the following article, I’ll be covering typecasting.
FastBit Embedded Brain Academy Courses
Click here: https://fastbitlab.com/course1