Yanuar Aditya bio photo

Yanuar Aditya

Dota & Volvo Cars

Email Twitter LinkedIn Instagram Github Steam

For the complete list of the tutorial on this blog, you can check these following links:

1. Introduction
2. First C-Program
3. Types and Variables
4. Conditional Statements
5. Function and Math Operations
6. Arrays
7. Pointers
8. I/O in C


Now that you should have some basic on C, such as variables, data type, basic I/O, and control flow (conditional & loops), this part of the tutorial, we will learn more about function and math operations in C. Some compile-able examples are provided to help you to gain better understanding. We will try to design a C code to compute a math quadratic polynomial with specific inputs.

Function in C

Function is a group statements that together they perform a specific task. At least, one function main()always be found on C program. A programmer can divide his code into separate functions. These functions can be located in different files, later on we will call this source codes. A group of source codes containing independent functions called library.

The C standard library provides numerous built-in functions that can be called without us defining them. We have used printf() function so far to let some texts to be displayed. Each built-in functions have specific purposes and mostly, we have to include corresponding header #include <header> to be able to use the built-in functions.

We can define our own function that will work depends on how we want them to. However, ones must know the general form of a function within C language.

return_type function_name( arg_type parameters, ... )
{
    body of the function

    return (return_type) value
}

return_type is the type datas of the value that the function will return. In other words, when we call a function B from function A, we’re expecting something happen inside the function B and when the function ends, it has some values that will be used by the calling function A. There are several ways for function B to pass this value to A, but for now we will use return. If the function does not have any value to return, then the return_type can be set to void, e.g, void main(). arg_type defines type of the data for the input arguments, e.g, int, char, float, etc. It is exactly similar with how you declare a variable in the main code block.

To find a square root product in C, the native built-in function is sqrt().To use this function, we must include corresponding library for it in line:02. As you observe the whole codes, we have two additional functions to the main() function, quadratic() and squareRoot().

In line:5, on function quadratic() declaration, it has int return type because in the application, whenever we call it, we expect the function to return the result of a quadratic computation from variable int a. Meanwhile, squareRoot() function has different return type, which is float because we’re gonna deal with real numbers as a result of square root computation from float b.

Another difference between these two functions, is how the declaration and code blocks are located. quadratic() function has both declaration and code block located before main(). The code block spans from line:6 to 8. While squareRoot() has been declared before main() in line:11 with the code block is presented after main() from line:23 to 26. This will have same result in the end, just matter of preference on how you as the programmer feel comfort with one of them. Please do notice on latter method, you have to write the full function name twice.

Now, when you started to develop a big C program, probably you will encounter numerous of independent function that needs to be called from different files. Next section will give you the big picture with examples.

Multiple Source Codes in C

Now, let’s split the code into separate files. First, create header source.h that consist declaration of every functions. Generally, other than the function declarations, macro parameters are found in header as well.

Afterward, define what will happen inside of each functions on the source file, source.c. Start by including the header file on top of the code. This is optional actually if you use C99 compiler. If the name of the header and the source (just the name, without file extension) are same, in this case source, then actually you don’t have to write #include "source.h" inside source.c. It will linked automatically thanks to the smart compiler.

For now, we have fully modular source codes for function quadratic() and squareRoot(). As the functions are ready, now other functions can use those functions just by calling the header name. Let’s main() inside main.c calls both functions. Keep in mind, that here we assume that all of these files are located in same directory.

+ directory
|__ source.h
|__ source.c
|__ main.c

However, you can also put the source codes inside a directory, e.g. src like this,

+ directory
|__ + src
|   |__ source.h
|   |__ source.h
|__ main.c

and modify the main.c to link to the proper directory of source.h like this #include "src/source.h".

Compile Multiple Source Files

Allright, so we have source.c in addition to main.c. Both have to be compiled in order to make an executable program. As there is a function inside source.c that is invoked within main.c, we have to link the corresponding object in compilation. Following command is the fastest and straightforward to generate an executable program named programTest:

$ gcc main.c source.c -o programTest

In sort, when the compilation happen, it transforms source code written in C language into some binary codes which known as object code. This object code can only be read by the machine. However, as the compiling process is done, both object files from the sources are deleted and leave only the executable program. Same result can also be achieved using a method that compiles each source files separately to retain the object files.

$ gcc -c source.c
$ gcc -c main.c
$ gcc source.o main.o -o programTest

This second method will give you two object files *.o. Then the third line will link both of them to become an executable program named programTest. Now, when there is a modifincation on certain file, e.g., source.c, then we have to update the object file of source.o, thus we just need to compile the corresponding source to update the object code.

$ gcc -c source.c
$ gcc source.o main.o -o programTest

Note that main.c does not need to be compiled. Thus, time to rebuild the whole program is much shorter considering that probably we’ll gonna have much more source codes than our circumstance right now.

Arithmetic Operators

C programming language contains some mathematical operators. All of the arithmetic operators are shown on table below. Assume that two variables are given, A and B with assigned values are 10 and 5 respectively. These two variables are called operands. From the table you can find the result from each operations.

symbols functions results
+ adding two operands A + B equals to 15
- subtract two operands A - B equals to 5
* multiply two operands A * B equals to 50
/ divide two operands A / B equals to 2
% modulus, remainder A % B equals to 0
++ increment, increase value A++ will give 11
decrement, decrease value B– will give 4

Keep in mind that each operations can be used to form more complex calculations and over time, performance of your C codes is judged by how efficient the design of algorithm on C level. Now, let’s write a function to compute some practical math problems.

\[\begin{align*} & y = x^2 + x + 5 \end{align*}\]

We have a quadratic polynomial function that takes x as an input and store the result on y. The value of x can be arbitrary, thus we would like to use float x and store the output to float y.

We can initiate the function, let’s call it polyQuadratic. It will take float x as an input and return a float value, thus the function itself has to be declared using float data type.

Let’s add the function into source.h where two previous functions exist.

float polyQuadratic (float x);

The computation itself requires a quadratic operation and addition. For the quadratic, let’s utilise already defined quadratic() function. However, we will encounter an issue here because of the difference on data type between return value of quadratic() which is integer and the input data, which is float x. However, such this problem, can be solved using casting. The compiler will automatically change one type of data into another if it makes sense. For instance, if you assign an integer value to a floating-point variable, the compiler will insert code to convert the int to a float.

float polyQuadratic (float x)
{
	return ((float)quadratic((int)x) + x + 5);
}

The idea is, as quadratic() takes an integer input, while the input here is float, we have to tell compiler to assume that it is an integer. Thus, (int)x will cast float x into something similar with int x. But you should be warned that the value of float will be rounded to closest decimal. Second implementation of casting here is to cast return value of quadratic() to float although it is not necessary. An integer value doesn’t need a casting if it is gonna be used with float numbers. You will get some potential warning from the compiler though.

You can check the final sourceModified.h, sourceModified.c and main.c below.

The x as the input for the equation should be arbitrary. However, for the simplicity 5 is just the value that pops out in my head. Thus, y value after computation should be 35.

welcome to the simplest example ever
calculate y = x^2 + x + 5 with x is set to 5.000000
entering the black-box...
we've got the result now!
y-value is 35.000000

Next, we will learn about how C stores sequences of same element datas, known as array.

Cheers!