Having not such a long way from our first lesson to that, you “reached” to the study of functions in C++. Functions – It is a named piece of code, which is repeated in the program 2 or more times . When we write the function, you must give it a name in the future, чтобы её вызвать в программе (ofmain() or another function), It is necessary to refer to it by this name.
We have already met functions in previous lessons. This functions for strings (character arrays) strlen(), strcmp(), function for generating random numbers rand(). We used them in programs and, for example, passed to the function strlen() string, and she returns to us the number of characters in this string (integer).
This of course was not magically, and the function took our string, handle it and return to us the value, that counted. That is, someone wrote to us this is the function code, which considers the length of the string and we successfully use it in your programs. And this feature is great saves our time, reduces the number of strings of code and facilitates its readability.
Yes – we have these wonderful standard library functions, that we can apply in their programmes, но в большинстве случаев каждое новое задание уникально и стандартные функции не всегда подойдут. В С++ программист может самостоятельно написать собственную функцию и применять её с таким же успехом, as library functions.
Up to a certain time, you can do without features. Instead, to produce the same section of code in the entire program. But if you have to change the code (update or remove something from it), we need to make changes throughout the program. It is better to learn the topic features and actively apply.
Define the function in two ways:
- to main-functions;
- aftermain-functions. In this case it is necessary to main-function to announce its own function prototype.
In this article and the following, we will use the second method, as it is more common. The first method can be used, if one function and its code is very small. While we write simple programs, this happens often. But for the more difficult programs, will write more functions that will not consist of 2-3 strings, and more. Will show you what it looks like a function definition to main():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <iostream> using namespace std; void ourFunctionForPrint() // определение функции до main() { cout << "Сайт purecodecpp.com\n"; cout << "Изучаем функции в C++\n"; cout << "Эта функция выводит на экран три строки\n\n"; } int main() { setlocale(LC_ALL, "rus"); cout << "Вызов ourFunctionForPrint() из main()\n\n"; ourFunctionForPrint(); cout << "Функция ourFunctionForPrint() отработала!\n"; cout << "Далее продолжает работу main()\n\n"; return 0; } |
Using a prototype it will look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include <iostream> using namespace std; void ourFunctionForPrint(); // прототип int main() { setlocale(LC_ALL, "rus"); cout << "Вызов ourFunctionForPrint() из main()\n\n"; ourFunctionForPrint(); cout << "Функция ourFunctionForPrint() отработала!\n"; cout << "Далее продолжает работу main()\n\n"; return 0; } void ourFunctionForPrint() // определение { cout << "Сайт purecodecpp.com\n"; cout << "Изучаем функции в C++\n"; cout << "Эта функция выводит на экран три строки\n\n"; } |
The function prototype is placed within a string 4, and its definition is at the bottom of the program in strings 20 – 25. With regard to the implementation of the programme: first prototype compiler reads. This will give him to know about, that somewhere after the main() the definition of this function is located.
Next, begin execution of the main function main(). It will be performed, the compiler does not yet meet the function nameourFunctionForPrint(). Then he will find the function definition, which is the value following main(), by name, in the specified prototypes, executes its code, then back to running commands main-functions.
As a result, the screen will see:
Let's talk about the definition of functions.
Functions in C ++ may not return any values (as in the example) and may return any value. If the function returns nothing, it is a function of type void.
Function syntax, that does not return a value:
The function name should be given to keeping the rules for variable names. Only – it is desirable to contain a verb, because the function performs an action. For example, if it considers the arithmetic mean, you can give a namecalculateAverage, if the output is something on screen – showText. The name should speak for itself, it was not necessary to leave unnecessary comments in the code.
Options (or function arguments) – this data, which receives and processes function in the body. If the function does not need anything accept for processing, parentheses are left empty. According to the rulesHigh Integrity C++ Coding Standard it is advisable not to define functions with greatandnumber of parameters (more 6).
Consider a couple of examples of the functions, that accept parameters and does not return values.
It takes one parameter:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include <iostream> using namespace std; void printQuestion(int questionCount); int main() { setlocale(LC_ALL, "rus"); printQuestion(7); cout << endl << endl; return 0; } void printQuestion(int questionCount) { for (int i = 0; i < questionCount; i++) { cout << '?'; } } |
In the 10th string of code gets the parameter function – integer 7. With him (with this number) happens then, that described in the definition of the function – strings 16 – 22. Namely – This number is placed in the header of the loop for. Expression i < questionCount would be equivalent to i < 7 . As a result, we will see on the screen 7 question marks.
It takes three parameters:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include <iostream> using namespace std; void printOurSymbol(int symbCount, int lineCount, char ourSymbol); int main() { setlocale(LC_ALL, "rus"); printOurSymbol(7, 5, '@'); cout << endl << endl; return 0; } void printOurSymbol(int symbCount, int lineCount, char ourSymbol) { for (int i = 0; i < lineCount; i++) { for (int j = 0; j < symbCount; j++) { cout << ourSymbol; } cout << endl; } } |
Function syntax, that returns a value:
These functions differ, that you must specify the type of the value, which returns a function as a result of its work. Itself returns the value in the program is executed by the operator return and that the value of the program will receive at the point, where the function was called . return can return a variable, constant or result of the expression (for example: return variable1 - variable2; ). The body of the function may be several operators return. Then, work function is complete, if the work of some of these operators. For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include <iostream> using namespace std; int calculateSomeDigits(int d1, int d2, char ch); int main() { setlocale(LC_ALL, "rus"); int digit1 = 0; int digit2 = 0; int res = 0; char chVar = 0; cout << "1-е число: "; cin >> digit1; cout << "2-е число: "; cin >> digit2; cout << "Операция(+ или -): "; cin >> chVar; res = calculateSomeDigits(digit1, digit2, chVar); cout << "res = " << res << endl; return 0; } int calculateSomeDigits(int d1, int d2, char ch) { if (ch == '+') return d1 + d2; if (ch == '-') return d1 - d2; } |
The function definition is located in strings 28 – 34. If the user enters +, work flow if in string 30, and accordingly it will work return d1 + d2; . Then the function code will no longer be processed further. The compiler will return to perform main-functions.
You may have noticed, that in the previous code, the parameter names in the prototype and the function definition differ from variable names, which are passed to the function of main. The point following – parameters defining the function prototype and the formal. When we pass the variables as parameters, function will not work with the original variable, and their replicas. These copies are created in the main memory at the time of calling a function. It works with the local copy, and upon completion of the work, copies are destroyed. So the prototype, you can use the exact variable names, but in any case, the function will not work directly with them, and with their counterparts. That is, the variables do not change, it may. When you become familiar with the following lessons pointers and links – learn, how you can change the values of variables passed in the function body.
A little more about the prototype: reading it before main, compiler receives information about, what type of return value is a function (or she does not return a value – has type void) and that, which parameters are transferred into it, how much and in what sequence.
Prototype int calculateSomeDigits(int d1, int d2, char ch); He tells the compiler, that function will return to the scene of her call to an integer and that, that when you call it two integers and a character to be transmitted. When calling a function, we have to give her as many parameters as indicated in its title when determining.
Transmit parameters must be in the same order, as identified in parentheses following the name of the function. Otherwise errors will occur when you compile a program does not work correctly.
Syntax function prototype:
If several parameters – they must be separated by a comma. The easiest way to declare the prototype – This is a copy from the first string of the function definition (header) and after the closing parenthesis to add a semicolon.
Variable names prototype parameters can be omitted. The following is equivalent to prototype, that the above.
In my opinion, it is better to declare the function prototypes, indicating the names of the parameters. Especially if several options and they have the same type. For readability and understanding of the program it would be better.
To fix it, what does this article, need to practise. See the article with tasks for functions in C++ . In it you will find information on how to, how to pass arrays to functions as parameters. Council – do not just read, and write code! Preferably on their own.
Related Videos:
>> Function - is a named piece of code, which is repeated in the program 2 или больше раза .
Function – is a named piece of code. By name (he also named) This fragment can be caused by any number of times (even zero times). In the old books written, if the program has a code snippet, which is repeated 2 or more times, it claims to, to become a function.
That's how I would have revealed about this idea.
>> When we write the function, you must give it a name in the future, to its cause in the main-function, It is necessary to refer to it by this name.
Easier. Functions should be named for, so that we can refer to it (by name). Consult can be anywhere, not only because of main().
For example:
int foo() { return 1; }
int bar() { return foo(); } // типа обращаемся к функции не из main
int main() {
cout < < bar(); }
Define the function in two ways: to main-function; after the main-function.
The function can be defined anywhere, even in another file (not main.cpp, and say, in foo.cpp).
Function definition includes a header (is one piece, where we specify the return value, function name and argument types) and body (it is actually the code, which performs the function).
But we can declare the function, but her body did not write. So do to tell the compiler that this function somewhere in there he does not showered us errors. If in the end will not function (when building a program), then we will give a linker error (he engaged in this business).
function declaration contains a header.
In short, if the function foo() raises bar function(), then the function bar() It should either be declared, or determined by code higher than foo().
For example
int foo() { return 1; }
int bar() { return foo(); }
It works without error.
int bar() { return foo(); }
int foo() { return 1; }
You will receive a compiler message that, that the function foo() no.
int foo(); // this ad without the implementation of
int bar() { return foo(); }
int foo() { return 1; } // This code can be anywhere (Good(), after the bar() or even in another file
It works without error.
>> If the function does not need anything accept for processing, parentheses are left empty. According to the rules High Integrity C ++ Coding Standard preferably not define a function with a large number of parameters(more 6).
That's right. You can meet friends, that in the absence of write parameters void in parentheses, so:
int foo(void) { return 1; }
It seems to be some kind of throwback to the ancient implementations of C compilers. So it is not necessary to do.
About the large number of parameters is also true, I have not read the High Integrity C ++ Coding Standard (I will now know what is there about 6 written arguments), but I read very popular in the narrow circles of the book Martin “clean code”. There he writes, that the less options, all the better. Ideally – no settings, But ultimately, he seems to be calling a number of parameters, equal to three. Martin motivates this epic high complexity testing functions with a large number of parameters.
I'm just a little to supplement your thesis :).
>> You may have noticed, that in the previous code, the parameter names in the prototype and the function definition differ from variable names, are passed to the function from the main.
To her, they may differ, but it is better if they match. The function prototype names generally can not write, so:
int foo(int, float);
// …
int foo(int a, float b) { return a + b; }
But best of all of them still write, tk. development environment (Your Visual Studio) will tell you the type and name parameter, When you type the function name and the open parenthesis. IDE takes the information from the prototype. If you give the parameters of good names – the visual studio will be able to help you better quality :)
fully support – better, to variable names and parameter names in the function header match. For ourselves, we know, that in fact they are different memory areas, and when the function is called – really real help.
That, better to prescribe the parameter names in the prototype also agree.
In the prototype, there are no memory areas. You wrote, that memory is allocated at the beginning of the function and released at the end of. A prototype – it's just a mark to the compiler, that he did not swear…
That's right. On the different memory areas – it was about the variables and parameters in the function header.
All afraid I'm embarking on this topic. But after reading your article about the functions realized, it is not so scary, it seemed! Thanks to the administrator for work! I am your regular reader Now :)
By the way in the book “clean code” Martin's a whole section dedicated to functions. I think is very interesting.
For example, if you believe Martin, the function should perform exactly one task, and the name of the function that clearly describe the problem. It follows that, the size of the features to be very small (in old books written that function should fit into 80 strings {on an old monitor is one screen}, but really, I believe that most of the function can and should be shortened).
Well, all these “If the code snippet is repeated several times…” too are not quite relevant in this approach,. Just, if the code fragment performs some meaningful operation, it is logical to give this operation a name, wrapping the code in a function.
There is a small overhead functions associated with the function call (and how can we write correctly, copying the parameters in the transmission of meaningfully {as do all of the examples in this article}), but with the right approach, most of the functions can be declared as inline and constexpr, and the parameters passed by reference (I think, wishing to take up literature :) ).
Programmer_blog, Thank you, that complemented my article interesting relevant information.
You have a column should be allocated on our website, Articles comments )