函数
function是一组语句,在程序的某处调用时便执行这些语句。以下是其格式:
type name(parameter1, parameter2, ...) {
// 语句
}
函数用法举例:
int foo(int a,int b) {
return a + b;
}
int sum;
sum = foo(3,4); // 'sum' is 7
在使用函数之前仅能定义一种函数原型:
int foo(int a,int b);
foo(5,2);
int foo(int a,int b) {
return a + b;
}
所有函数为全局范围。
Returning a Value返回值#
voidvoid#
空函数代表函数中无变量,这种函数被用来在不返回结果的函数中作为返回值使用。
// 这种函数不会返回任何数值。
void func() {
log.message("func is called\n");
}
Return Values返回值#
Parameter Passing Mechanism参数传递机制#
Passing Arguments by Reference使用引用传递参数#
默认情况下,函数参数通过数值进行传递因此如果在函数范围内更改了参数值,并不会对函数外的部分产生任何影响。如果想通过函数对其参数进行修改,就必须使用引用进行参数传递。
如果总是想通过引用进行函数参数的传递,在定义函数时使用(&)符号对其进行标记。
void foo(int &a,int b) {
a = 13; // 这样将影响到变量以外的部分因为'a' 被作为引用进行传递
b = 14;
}
int a = -1;
int b = 20;
foo(a,b);
log.message("%d %d\n",a,b);
// 结果为: "13 20"
通常使用引用将容器和类的实例进行传递。例如:
class Foo {
int v;
};
void foo(int &v) {
if(v) log.message("%d ",v);
v = 13;
}
Foo f = new Foo();
foo(f.v);
foo(f.v);
int v[] = (0);
foo(v[0]);
foo(v[0]);
Foo f1[] = (new Foo());
foo(f1[0].v);
foo(f1[0].v);
//输出为: 13 13 13
Passing Containers as Arguments将容器作为参数进行传递#
要将 向量 或 贴图 作为参数进行传递,需使用适当的函数说明,如下所示:
void foo(int a[]) {
a[13] = 321;
}
int arr[] = ( 1, 2, 3, 4 );
foo(arr);
Accessing Elements of the Function访问函数的元素#
可以下列方式对函数返回的数值元素进行访问:
vec3 foo() { return vec3(1.0,2.0,3.0); }
log.message("%f %f\n",foo().x,foo()[0]); // 结果为: 1 1
log.message("%f %f\n",translate(1.0,2.0,3.0).m23,translate(1.0,2.0,3.0)[14]); // 结果为:3 3
请注意如果返回值为class,需对其强制转换为自身类型。
class Bar {
string toString() {
return "bar";
}
};
Bar bar() { return new Bar() };
log.message("%s\n",Bar(bar()).toString());
Default Argument Values默认参数值#
可为函数参数提供默认值。此后如果您参数为空,就会使用默认值。省略的参数可使用逗号进行表示(不需留空白区域)。
void foo(int a = 1,int b = 2) {
log.message("%d %d\n",a,b);
}
foo(); // 结果为: 1 2
foo(3,4); // 结果为: 3 4
foo(3); // 结果为: 3 2
foo(,4); // 结果为: 1 4
Technique of Using Functions函数使用方法#
Function Overloading函数过载#
可在此处了解函数过载内容
Using Inline Functions使用内联函数#
拥有下列标记和实体的函数将自动进行内联,这样的方式可使用户自定义的类实现明显的速度优化:
void get() { return a; }
void set(int b) { a = b; }
void get(int i) { return a[i]; }
void set(int i,int b) { a[i] = b; }
__FUNC____FUNC__#
__FUNC__预处理器常数会时刻对正确的函数进行报告。任何情况下都不会影响到性能。
// __FUNC__ == 函数标记
class MyClass {
int doSomethingWithNode(Node node) {
if(node == NULL) {
log.error("%s: node is NULL\n",__FUNC__);
}
}
};
// 输出: MyClass::doSomethingWithNode(): node is NULL
Using Anonymous Functions使用匿名函数#
使用匿名函数来创建无函数名的函数。 当您需要调用简短函数或在代码其它地方不需要再使用的函数(因此这种函数的名称并不重要),匿名函数就显得很有用。 使用C++的语法方式对匿名函数进行声明:
[]() { log.message("hello!\n");
匿名函数的声明(the []() {}; construction)总是会返回函数的标识符。
- 传递给Async类的run()函数(参看data/samples/systems/socket_3实例)。
- 传递给call()容器函数:
int a[0]; // 将2种匿名函数附加给数组 a.append([](int a) { log.message("array callback 0 %d\n",a); }); a.append([](int a) { log.message("array callback 1 %d\n",a); }); // 调用存在数组中的所有函数 a.call(1); // 输出: // array callback 0 1 // array callback 1 1
- 传递给call()的控制语句:
call([]() { log.message("foo\n"); }); call([](int a) { printf("foo %d\n",a); },1); // 输出: // foo // foo 1
int f = []() { log.message("callback\n"); }; call(f); //输出: callback