cs:c_language:functions_1

Return to Home page

# Differences

If you found any error, or if you want to partecipate to the editing of this wiki, please contact: admin [at] skenz.it

**You can reuse, distribute or modify the content of this page, but you must cite in any document (or webpage) this url: https://www.skenz.it/cs/c_language/functions_1?rev=1551188114&do=diff**

This shows you the differences between two versions of the page.

— |
cs:c_language:functions_1 [2019/02/26 14:35] (current) |
||
---|---|---|---|

Line 1: | Line 1: | ||

+ | ====== Functions (Example 1) ====== | ||

+ | **Concepts:**\\ | ||

+ | Very simple function with arguments passed by value | ||

+ | |||

+ | **Text:**\\ | ||

+ | * Write a function that receives as arguments two float numbers (a and b) | ||

+ | * The function multiplies these two values and it returns the result of the multiplication | ||

+ | * The produced function must be applied to a vector with name ''vet'', in order to multiply all its elements by 3.0 | ||

+ | * The result of the multiplication must be stored in a vector of name ''res'', with the the same dimension of ''vet''. | ||

+ | |||

+ | |||

+ | **Solution:**\\ | ||

+ | <file C functions_1.c> | ||

+ | /* | ||

+ | Write a function that receives as input two float numbers (a and b), | ||

+ | it multiplies them and it returns the result of the multiplications. | ||

+ | The function must be applied to a vector of name vet in order to multiplicate by 3.0 | ||

+ | each element of the vector. | ||

+ | The result of the multiplication must be stored in a vector of name res with the same dimension | ||

+ | of vet. | ||

+ | */ | ||

+ | |||

+ | |||

+ | #include <stdio.h> | ||

+ | #define SIZE 10 | ||

+ | |||

+ | /* Prototype */ | ||

+ | float mul(float a, float b); | ||

+ | |||

+ | int main(){ | ||

+ | |||

+ | float vet[SIZE] = {1.0, 5.0, 3.0, 7.0, 10.0, 1.0, 2.0, 3.0, 4.0, 5.0}; | ||

+ | float res[SIZE]; | ||

+ | int i; | ||

+ | |||

+ | /* Multiplication of each element of vet by 3.0 and storing of the result in res */ | ||

+ | for(i=0; i < SIZE; i++){ | ||

+ | res[i] = mul(vet[i], 3.0); | ||

+ | } | ||

+ | |||

+ | /* Print results, i.e., the content of vector res */ | ||

+ | for(i=0; i < SIZE-1; i++){ | ||

+ | printf("%f ", res[i]); | ||

+ | } | ||

+ | printf("%f\n", res[SIZE-1]); | ||

+ | | ||

+ | return 0; | ||

+ | } | ||

+ | |||

+ | |||

+ | /* Implementation of the function mul that performs the multiplication between a and b */ | ||

+ | float mul(float a, float b){ | ||

+ | float result; | ||

+ | |||

+ | result = a*b; | ||

+ | |||

+ | return result; | ||

+ | } | ||

+ | |||

+ | /* The function mul can be also implemented in the following way */ | ||

+ | /* | ||

+ | float mul(float a, float b){ | ||

+ | return a*b; | ||

+ | } | ||

+ | */ | ||

+ | </file> | ||

+ | |||

+ | **Comments:**\\ | ||

+ | * During the compilation process, the compiler must know in advance the prototypes of all the functions used in the program, before their calling. This is performed or by the ''#include'' directive (that includes a file that usually contains, besides other things, the prototypes of some functions - for instance the file ''stdio.h'' contains among many prototypes that of the functions ''scanf'' and ''printf'') or by writing directly and before their calling the prototypes of the functions that will be used in the following. In the proposed example: | ||

+ | <code c> | ||

+ | /* Prototype */ | ||

+ | float mul(float a, float b); | ||

+ | </code> | ||

+ | indicates that in the following will be used the function with name ''mul'' that receives as input parameters two variables of type ''float'' and it returns a variable of type ''float''. The names of the parameters are not important for the compilation process, therefore this line of code can be substituted with the following one: | ||

+ | <code c> | ||

+ | /* Prototype */ | ||

+ | float mul(float, float); | ||

+ | </code> | ||

+ | **Note:** If you write the //implementation// of the function before its use, the declaration of the //prototype// is not needed. Indeed, the compiler, analyzing the ''float mul(float a, float b)'' part of the implementation of the function, has all the needed information, i.e., the name of the function, the type and the number of parameters and the type of the returned value. The compiler will use such information to check if the function is used in a correct way, in particular if the number and the type of parameters passed to it are consistent with its prototype. | ||

+ | * Analyzing the program: | ||

+ | <code c> | ||

+ | int main(){ | ||

+ | |||

+ | float vet[SIZE] = {1.0, 5.0, 3.0, 7.0, 10.0, 1.0, 2.0, 3.0, 4.0, 5.0}; | ||

+ | float res[SIZE]; | ||

+ | int i; | ||

+ | |||

+ | /* Multiplication of each element of vet by 3.0 and storing of the result in res */ | ||

+ | for(i=0; i < SIZE; i++){ | ||

+ | res[i] = mul(vet[i], 3.0); | ||

+ | } | ||

+ | |||

+ | /* Print results, i.e., the content of vector res */ | ||

+ | for(i=0; i < SIZE-1; i++){ | ||

+ | printf("%f ", res[i]); | ||

+ | } | ||

+ | printf("%f\n", res[SIZE-1]); | ||

+ | | ||

+ | return 0; | ||

+ | } | ||

+ | </code> | ||

+ | after the declaration and the initialization of the vector ''vet'', and after the declaration of all the useful variables, the first ''for'' cycle performs the multiplication of all the element of ''vet'' by ''3.0''. Results are saved on the vector ''res''. | ||

+ | <code c> | ||

+ | res[i] = mul(vet[i], 3.0); | ||

+ | </code> | ||

+ | To perform the multiplication, the function ''mul'' is used. It multiplies its first parameter ''ris[i]'' for its second parameter ''3.0''. The function returns the result of the multiplication as a ''float'' number. | ||

+ | The following line of code: | ||

+ | <code c> | ||

+ | res[i] = mul(vet[i], 1.0+2); | ||

+ | </code> | ||

+ | would have obtained the same result, as well as the following line of code that does not make use of the function ''mul'': | ||

+ | <code c> | ||

+ | res[i] = vet[i]*3.0; | ||

+ | </code> | ||

+ | The second ''for'' cycle prints the content of the vector ''res''. | ||

+ | * The implementation of the function ''mul'' is the following: | ||

+ | <code> | ||

+ | /* Implementation of the function mul that performs the multiplication between a and b */ | ||

+ | float mul(float a, float b){ | ||

+ | float result; | ||

+ | |||

+ | result = a*b; | ||

+ | |||

+ | return result; | ||

+ | } | ||

+ | </code> | ||

+ | In practice, the values passed to the function (i.e., ''ris[i]'' and ''3.0'', are copied in the variables ''a'' and ''b'' of the function, respectively). It is important to notice that all the variable inside the function (i.e., ''a'', ''b'' and ''result'') are local to the function. Indeed, any time the function is executed, a memory space sufficient to store 3 variables is allocated. These variables can be used inside the compound of the function but, at the end of the function, they are deallocated and the memory reserved for them is released. Inside the function the variables ''a'' and ''b'' have the value ''ris[i]'' and ''3.0'' (note, a modification on the value of the variable ''a'' does NOT implies the modification of the value of the variable ''ris[i]''). Inside the implementation of the function, it is declared a local variable with name ''result''. The variable ''result'' is used to store the result of the multiplication of ''a'' and ''b''. The command ''return'' is used to return the value of the variable ''result'' to the caller, i.e. the main program that has called the function ''mul(vet[i], 3.0)''. In practice, it is like the function ''mul(vet[i], 3.0)'' is substituted each time it is called with the result of the multiplication between ''vet[i]'' and ''3.0''. It is worth to notice that the main program is itself implemented like a function, the function with name ''int main()''. The ''main'' function receives no parameter as input (a different way to write the prototype of this function is ''int main(void)'', where ''void'' identifies no type). At the end of the ''int main()'', the last command is ''return 0;''. Such a command indicates that the function returns to the caller the value ''0''. In the case of the ''int main()'' function, the caller is the operating system (Windows, Linux, Mac OS,...), and the value ''0'' returned to the operating system indicates that the program is terminated successfully (note from the prototype of the function ''int main()'' that it returns an //integer// number). | ||

+ | * The function ''float mul(float a, float b)'' can be equivalently written as: | ||

+ | <code c> | ||

+ | float mul(float a, float b){ | ||

+ | return a*b; | ||

+ | } | ||

+ | </code> | ||

+ | in this case it does not use the variable ''result'' to store the result of the multiplication between ''a'' and ''b'', but it immediately returns the result of the operation without using a local variable (''return a*b;''). |

If you found any error, or if you want to partecipate to the editing of this wiki, please contact: admin [at] skenz.it

/web/htdocs/www.skenz.it/home/data/pages/cs/c_language/functions_1.txt ยท Last modified: 2019/02/26 14:35 (external edit)