Content of the lesson:
A procedure is a separated part of a program which should deal with a problem (see the term procedural programming). Procedures are used often in these cases:
In the C programming language you cannot use procedures like in Pascal, there are only functions. In case you wanted to get the same effect as with procedures, you can use void return value. The term function with void return value will be used in the rest of the lesson.
The syntax consists of the header (keyword void, name of the function and optional group of parameters in brackets). Then you have to write braces and all commands should be placed into them. You can use commands of define local variables inside any function.
void name (parameters); //parameters are
optional
{
program code of function
}
Consider the program from the previous lesson which loaded any number of values into a 2D array and then wrote the array to screen.
#include "stdafx.h"
#define N 5000
int _tmain(int argc, _TCHAR* argv[])
{
int i, pocet, p[N];
printf("Zadej pocet vkladanych cisel (1- %d)\n",n);
scanf("%d", &pocet);
while ((pocet<1) || (pocet>n))
{
printf("Zadej znovu:");
scanf("%d", &pocet);
}
for (i=0; i < pocet; i++)
{
scanf("%d", &p[i]);
}
for (i=0; i < pocet; i++)
{
printf("%d\n", p[i]);
}
fflush(stdin);
getchar();
return 0;
}
This program can be divided into the following sequence of steps:
The program is relatively short but if you see it the first time you will need some time to orientate into it and to understand its principles and functionality. This could be a problem in case that more programmers work together on a project. They should write the source code to be understandable to any colleague. We are going to divide our program:
Dividing it into steps means creating a transcription of every part into a procedure:
void zadanipoctucisel()
{
printf("Zadej pocet vkladanych cisel (1-%d)",n);
scanf("%d", &pocet);
while ((pocet<1) || (pocet>n))
{
printf("Zadej znovu:");
scanf("%d", &pocet);
}
}
void vlozenicisel()
{
for (i=0; i < pocet; i++)
{
scanf("%d", &p[i]);
}
}
void vypiscisel()
{
for (i=0; i < pocet; i++)
{
printf("%d\n", p[i]);
}
}
You got three simple procedures (programs) after dividing our source code and you can re-write your program by assembling these parts together. Move the procedures above the main function and write only the name of the procedure instead of commands in the main part. Inserting the name of each procedure inside the main part will insert its commands to the main part (to the place where you inserted the name).
Because we will use variables in all functions we will not define them locally in the main function but globally before definition of the functions.
#include "stdafx.h"
#define N 5000
int i, pocet, p[N];
void zadanipoctucisel()
{
printf("Zadej pocet vkladanych cisel (1-%d)",n);
scanf("%d", &pocet);
while ((pocet<1) || (pocet>n))
{
printf("Zadej znovu:");
scanf("%d", &pocet);
}
}
void vlozenicisel()
{
for (i=0; i < pocet; i++)
{
scanf("%d", &p[i]);
}
}
void vypiscisel()
{
for (i=0; i < pocet; i++)
{
printf("%d\n", p[i]);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
zadanipoctucisel();
vlozenicisel();
vypiscisel();
fflush(stdin);
getchar();
return 0;
}
You can see that the program contains a standard header with defined variables, then the declaration of each function and finally the main part which runs the functions as needed. The main part can of course contain any other commands between the calls to functions.
To summarize our job, we have created a program with only 3 commands in the main part: zadanipoctucisel, vlozenicisel, vypiscisel. It is absolutely clear what is done and in case of any modification you only have to modify one function, not the whole program. You saw one of three situations when you should use functions for your own good: if you want to make your program well-arranged you should divide the source code to functions (parts).
Take a look at the illustration of the second possible usage of functions (if a complex command or set of commands is repeated inside a program). Consider writing a simple program to compute the sum of two numbers (you can use functions of course to compute complex mathematical formulas but a simple example is enough).
#include "stdafx.h"
int a, b;
int _tmain(int argc, _TCHAR* argv[])
{
printf("Zadejte prosim cislo a: ");
scanf("%d", &a);
printf("Zadejte prosim cislo b: ");
scanf("%d", &b);
printf("Součet čísel %d a %d je %d.\n", a, b ,a+b);
fflush(stdin);
getchar();
return 0;
}
Try to explain this program in your words and divide it into steps as we did with the previous one.
The program can be logically divided into these sequences of steps (variant A):
or the variant B:
You can see the further process using both variants (they are compared).
void zadanicisel()
{
printf("Zadejte prosim cislo a: ");
scanf("%d", &a);
printf("Zadejte prosim cislo b: ");
scanf("%d", &b);
}
void vypocetsouctucisel()
{
printf("Součet čísel %d a %d je %d\n", a, b, a+b);
}
void zadanicislaa()
{
printf("Zadejte prosim cislo a: ");
scanf("%d", &a);
}
void zadanicislab()
{
printf("Zadejte prosim cislo b: ");
scanf("%d", &b);
}
void vypocetsouctucisel()
{
writeln("Součet čísel %d a %d je %d\n", a, b, a+b);
};
Which variant is better and why?
Whether you have chosen the variant A or the variant B, a part of the code is repeated. This is not suitable because in case you want to change anything, you have to change it twice (or even more times - it depends on the final appearance of your source code). You can make a mistake when trying to change something and forget to do some changes (these mistakes are the worst ones because it is difficult to find them). If you, for example, want to change the text "Enter number b:" to "Enter required number:", you have to make two changes in both variants - you solve the same problem at two (or even more) places.
Try to adjust the previous program (any variant) to let it load two different couples of numbers (for example couples a,b and c,d). Then the program computes the sums of both couples (sum of a+b and c+d).
The final program can look like the following one:
#include "stdafx.h"
int a, b, c, d;
void zadanicisel()
{
printf("Zadejte prosim cislo a: ");
scanf("%d", &a);
printf("Zadejte prosim cislo b: ");
scanf("%d", &b);
printf("Zadejte prosim cislo c: ");
scanf("%d", &c);
printf("Zadejte prosim cislo d: ");
scanf("%d", &d);
}
void vypocetsouctucisel()
{
printf("Součet čísel %d a %d je %d.\n",a, b, a+b);
printf("Součet čísel %d a %d je %d.\n",c, d, c+d);
};
int _tmain(int argc, _TCHAR* argv[])
{
zadanicisel()
vypocetsouctucisel()
fflush(stdin);
getchar();
return 0;
}
#include "stdafx.h"
int a, b, c, d;
void zadaniciselab()
{
printf("Zadejte prosim cislo a: ");
scanf("%d", &a);
printf("Zadejte prosim cislo b: ");
scanf("%d", &b);
}
void zadaniciselcd()
{
printf("Zadejte prosim cislo c: ");
scanf("%d", &c);
printf("Zadejte prosim cislo d: ");
scanf("%d", &d);
}
void vypocetsouctucisel()
{
printf("Součet čísel %d a %d je %d.\n",a, b, a+b);
printf("Součet čísel %d a %d je %d.\n",c, d, c+d);
}
int _tmain(int argc, _TCHAR* argv[])
{
zadanicisel()
vypocetsouctucisel()
fflush(stdin);
getchar();
return 0;
}
Take a look at the both variants:
In the variant A you can see that we use the same command for inserting number 4 times in the procedure zadanicisel (we ignore the names of variables a, b, c, d which is generally acceptable) and also we use the same command twice in the function vypocetsouctucisel (using only different couples of variables).In the variant B you can see a similar problem only divided to two generally identical functions zadaniciselab and zadaniciselcd.
The program is well-arranged after adding functions but there are many duplicated commands. Imagine a program to compute a sum of every possible couple from 4 variables (ab, cd, ca, bd... - 8 possible couples). We can also use 10 variables like number1,...,number10 or any other function using more variables (for example 100 variables). The program would be extremely long because of all possible combinations and it would become complicated and you probably would not be able to realize it (imagine a program computing sums of every couples for an array of 15000 items). You can solve all these problems using so called parameters and return values. Parameters will be used for entering input values for a function and return values for sending the result to the parent functions.
A parameter is a variable which is sent inside a function and this function can use it. Take a look at the following example:
#include "stdafx.h"
int a, b, c, d;
int zadanicisla();
{
int cislo;
printf("Zadejte prosim cislo: ");
scanf("%d", &cislo);
return cislo;
};
void vypocetsouctudvoucisel(int cislo1, int cislo2);
{
printf("Součet čísel je %d.\n",(cislo1+cislo2));
};
int _tmain(int argc, _TCHAR* argv[])
{
a = zadanicisla();
b = zadanicisla();
vypocetsouctucisel(a,b);
fflush(stdin);
getchar();
return 0;
}
In the header of the function zadanicisla the type of return value was changed from void to int. This change causes that this function will return an integer result. Then we defined a local variable cislo which will be used to load a value and using the command return cislo; it will be passed to the target variable in the parent function.
The function vypocetsouctucisel does not return any input values, it is used to output values which are passed as input parameters. An input parameter can be passed by writing data type which should be followed by space and the name of parameter inside brackets. In case you want to use more parameters, separate them by a comma.
#include "stdio.h"
int a,b,c,d;
{
int cislo;
printf("Zadejte prosim cislo: ");
scanf("%d", &cislo);
return cislo;
};
void vypocetsouctudvoucisel(int cislo1, int cislo2);
{
printf("Součet čísel je %d.\n",(cislo1+cislo2));
};
int _tmain(int argc, _TCHAR* argv[])
{
a = zadanicisla();
b = zadanicisla();
vypocetsouctucisel(a,b);
c = zadanicisla();
vypocetsouctucisel(a,c);
vypocetsouctucisel(c,b);
fflush(stdin);
getchar();
return 0;
}
Try to re-write the gomoku program from the previous lesson using procedures (you should divide your program to parts - ignore parameters).
Write a program which loads 5 numbers into p1 and p2 array. Then it writes both arrays to screen, sorts the p1 array and then writes both arrays to screen again.