Functions are the way we can structure our code into subroutines that we can:
函数是我们将代码构造为子例程的方式,我们可以:
- give a name to 给...起个名字
- call when we need them 需要我们时打电话
Starting from your very first program, an “Hello, World!”, you immediately make use of C functions:
从第一个程序“ Hello,World!”开始,您立即使用C函数:
#include <stdio.h>
int main(void) {
printf("Hello, World!");
}
The main()
function is a very important function, as it’s the entry point for a C program.
main()
函数是非常重要的函数,因为它是C程序的入口点。
Here’s another function:
这是另一个功能:
void doSomething(int value) {
printf("%u", value);
}
Functions have 4 important aspects:
功能具有四个重要方面:
- they have a name, so we can invoke (“call”) them later 它们有一个名字,所以我们以后可以调用(“调用”)它们
- they specify a return value 他们指定一个返回值
- they can have arguments 他们可以争论
- they have a body, wrapped in curly braces 他们有一个身体,用大括号包裹
The function body is the set of instructions that are executed any time we invoke a function.
函数主体是我们每次调用函数时都会执行的指令集。
If the function has no return value, you can use the keyword void
before the function name. Otherwise you specify the function return value type (int
for an integer, float
for a floating point value, const char *
for a string, etc).
如果函数没有返回值,则可以在函数名称前使用关键字void
。 否则,您将指定函数的返回值类型(对于整数,为int
;对于浮点值,为float
;对于字符串,则为const char *
,等等)。
You cannot return more than one value from a function.
您不能从一个函数返回多个值。
A function can have arguments. They are optional. If it does not have them, inside the parentheses we insert void
, like this:
一个函数可以有参数。 它们是可选的。 如果没有它们,则在括号内插入void
,如下所示:
void doSomething(void) {
/* ... */
}
In this case, when we invoke the function we’ll call it with nothing in the parentheses:
在这种情况下,当我们调用该函数时,将在括号内不加任何名称的情况下调用该函数:
doSomething();
If we have one parameter, we specify the type and the name of the parameter, like this:
如果有一个参数,则指定参数的类型和名称,如下所示:
void doSomething(int value) {
/* ... */
}
When we invoke the function, we’ll pass that parameter in the parentheses, like this:
调用函数时,将在括号中传递该参数,如下所示:
doSomething(3);
We can have multiple parameters, and if so we separate them using a comma, both in the declaration and in the invocation:
我们可以有多个参数,如果这样,我们可以在声明和调用中使用逗号将它们分开:
void doSomething(int value1, int value2) {
/* ... */
}
doSomething(3, 4);
Parameters are passed by copy. This means that if you modify value1
, its value is modified locally, and the value outside of the function, where it was passed in the invocation, does not change.
参数通过copy传递。 这意味着,如果您修改value1
,则将在本地修改其值,并且在调用中传递函数的函数外部的值不会更改。
If you pass a pointer as a parameter, you can modify that variable value because you can now access it directly using its memory address.
如果将指针作为参数传递,则可以修改该变量值,因为现在可以使用其内存地址直接访问它。
You can’t define a default value for a parameter. C++ can do that (and so Arduino Language programs can), but C can’t.
您无法为参数定义默认值。 C ++可以做到这一点(Arduino语言程序也可以做到),但是C不能。
Make sure you define the function before calling it, or the compiler will raise a warning and an error:
确保在调用函数之前定义了该函数,否则编译器将引发警告和错误:
➜ ~ gcc hello.c -o hello; ./hello
hello.c:13:3: warning: implicit declaration of
function 'doSomething' is invalid in C99
[-Wimplicit-function-declaration]
doSomething(3, 4);
^
hello.c:17:6: error: conflicting types for
'doSomething'
void doSomething(int value1, char value2) {
^
hello.c:13:3: note: previous implicit declaration
is here
doSomething(3, 4);
^
1 warning and 1 error generated.
The warning you get regards the ordering, which I already mentioned.
您收到的警告与订购有关,我已经提到过。
The error is about another thing, related. Since C does not “see” the function declaration before the invocation, it must make assumptions. And it assumes the function to return int
. The function however returns void
, hence the error.
该错误与另一件事有关。 由于C在调用之前没有“看到”函数声明,因此它必须进行假设。 并且假定函数返回int
。 但是该函数返回void
,因此返回错误。
If you change the function definition to:
如果将函数定义更改为:
int doSomething(int value1, int value2) {
printf("%d %d\n", value1, value2);
return 1;
}
you’d just get the warning, and not the error:
您只会得到警告,而不是错误:
➜ ~ gcc hello.c -o hello; ./hello
hello.c:14:3: warning: implicit declaration of
function 'doSomething' is invalid in C99
[-Wimplicit-function-declaration]
doSomething(3, 4);
^
1 warning generated.
In any case, make sure you declare the function before using it. Either move the function up, or add the function prototype in a header file.
无论如何,请确保在使用该函数之前先声明该函数。 向上移动函数,或将函数原型添加到头文件中。
Inside a function, you can declare variables.
在函数内部,可以声明变量。
void doSomething(int value) {
int doubleValue = value * 2;
}
A variable is created at the point of invocation of the function, and is destroyed when the function ends, and it’s not visible from the outside.
变量是在函数调用时创建的,并在函数结束时销毁,并且从外部看不到。
Inside a function, you can call the function itself. This is called recursion and it’s something that offers peculiar opportunities.
在函数内部,您可以调用函数本身。 这称为递归 ,它提供了特殊的机会。