69 lines
14 KiB
HTML
69 lines
14 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh" dir="ltr" class="client-nojs" xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh">
|
|
<head><meta http-equiv="x-ua-compatible" content="ie=edge">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<title>函数</title>
|
|
<link rel="stylesheet" href="ext.css" />
|
|
<link rel="stylesheet" href="site_modules.css" />
|
|
</head>
|
|
<body class="mediawiki ltr sitedir-ltr ns-0 ns-subject page-cpp_language_functions skin-cppreference2 action-view cpp-navbar">
|
|
<div id="cpp-content-base">
|
|
<div id="content"><a id="top"></a>
|
|
<h1 id="firstHeading" class="firstHeading">函数</h1>
|
|
<div id="bodyContent">
|
|
<div id="contentSub"><span class="subpages">< <a href="cpp.html">cpp</a>‎ | <a href="cpp-language.html">language</a></span></div>
|
|
<div id="mw-content-text" lang="zh" dir="ltr" class="mw-content-ltr" xml:lang="zh">
|
|
<p>函数(function)是把一个<a href="cpp-language-statements.html">语句</a>序列(<i>函数体, function body</i>)关联到一个<i>名字</i>和零或更多个<i>函数形参(function parameter)</i>的列表的 C++ 实体。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="co1">// 函数名:“isodd”</span>
|
|
<span class="co1">// 形参列表拥有一个形参,具有名字 “n” 和类型 int</span>
|
|
<span class="co1">// 返回类型是 bool</span>
|
|
<span class="kw4">bool</span> isodd<span class="br0">(</span><span class="kw4">int</span> n<span class="br0">)</span>
|
|
<span class="br0">{</span> <span class="co1">// 函数体开始</span>
|
|
<span class="kw1">return</span> n <span class="sy2">%</span> <span class="nu0">2</span><span class="sy4">;</span>
|
|
<span class="br0">}</span> <span class="co1">// 函数体结束</span></pre></div>
|
|
</div>
|
|
<p>调用函数时,例如在<a href="cpp-language-operator_other.html#.E5.86.85.E5.BB.BA.E5.87.BD.E6.95.B0.E8.B0.83.E7.94.A8.E8.BF.90.E7.AE.97.E7.AC.A6">函数调用表达式</a>中,以各个<i>实参(argument)</i>(可由调用场所提供,或者<a href="cpp-language-default_arguments.html">默认</a>)来初始化各个形参,然后执行函数体中的语句。如果一个函数的<a href="cpp-language-function.html#.E5.BD.A2.E5.8F.82.E5.88.97.E8.A1.A8">形参列表</a>以 <span class="t-c"><span class="mw-geshi cpp source-cpp">...</span></span> 结尾,那么额外的实参可以提供给该函数,这样的函数被称为<a href="cpp-language-variadic_arguments.html">变参函数</a>。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="kw1">for</span><span class="br0">(</span><span class="kw4">int</span> arg <span class="sy4">:</span> <span class="br0">{</span><span class="sy2">-</span><span class="nu0">3</span>, <span class="sy2">-</span><span class="nu0">2</span>, <span class="sy2">-</span><span class="nu0">1</span>, <span class="nu0">0</span>, <span class="nu0">1</span>, <span class="nu0">2</span>, <span class="nu0">3</span><span class="br0">}</span><span class="br0">)</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> isodd<span class="br0">(</span>arg<span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">' '</span><span class="sy4">;</span> <span class="co1">// isodd 被调用 7 次,</span>
|
|
<span class="co1">// 每次从 arg 复制初始化 n</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>函数调用表达式中<a href="cpp-language-unqualified_lookup.html">无限定</a>的函数名会以一组额外的规则查找,它被称为<a href="cpp-language-adl.html">“实参依赖查找”(argument-dependent lookup/ADL)</a>。</p>
|
|
<p>函数可以通过<a href="cpp-language-return.html">返回</a>或者<a href="cpp-language-throw.html">抛出</a><a href="cpp-language-exceptions.html">异常</a>终止。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx20">
|
|
<td>
|
|
<p>函数可以是<a href="cpp-language-coroutines.html">协程</a>。协程可以暂停执行,以在之后恢复执行。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx20">(C++20 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<p><a href="cpp-language-function.html">函数声明</a>可以在任何作用域中出现,但<a href="cpp-language-function.html">函数定义</a>只能在命名空间作用域出现,或对于<a href="cpp-language-member_functions.html">成员</a>和<a href="cpp-language-friend.html">友元</a>函数,可以在类作用域中出现。在类体中声明而不带 friend 说明符的函数是类成员函数。这种函数拥有许多附加性质,细节见<a href="cpp-language-member_functions.html">成员函数</a>。</p>
|
|
<p>函数不是对象:不存在函数的数组,而且函数不能按值传递或被其他函数所返回。可以有指向/到除<a href="cpp-language-main_function.html">主函数</a>以外的<span class="t-rev-inl t-until-cxx20"><span>所有函数</span> <span><span class="t-mark-rev t-until-cxx20">(C++20 前)</span></span></span><span class="t-rev-inl t-since-cxx20"><span>所有非标准库函数和<a href="cpp-language-extending_std.html#.E5.8F.AF.E5.8F.96.E5.9D.80.E5.87.BD.E6.95.B0">几个标准库函数</a></span> <span><span class="t-mark-rev t-since-cxx20">(C++20 起)</span></span></span>的指针和引用,它们可以用于这些函数自身无法被使用的地方。因此我们说这些函数“可取址”。</p>
|
|
<p>每个函数都具有一个类型,它由函数的返回类型,所有形参的类型(进行数组到指针和函数到指针转换后,见<a href="cpp-language-function.html#.E5.BD.A2.E5.8F.82.E5.88.97.E8.A1.A8">形参列表</a>)<span class="t-rev-inl t-since-cxx17"><span>,函数是否为 <a href="cpp-language-noexcept_spec.html"><code>noexcept</code></a></span> <span><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></span></span>,以及对于非静态成员函数的 cv 限定性<span class="t-rev-inl t-since-cxx11"><span>和引用限定性</span> <span><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></span></span>构成。函数类型同样拥有<a href="cpp-language-language_linkage.html">语言链接</a>。不存在有 cv 限定的函数类型(不要与如 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">int</span> f<span class="br0">(</span><span class="br0">)</span> <span class="kw4">const</span><span class="sy4">;</span></span></span> 这样的 <a href="cpp-language-member_functions.html">cv 限定函数</a>类型,或如 <span class="t-c"><span class="mw-geshi cpp source-cpp"><a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a> <span class="kw4">const</span> f<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span></span></span> 这样的返回 <a href="cpp-language-cv.html">cv 限定类型</a>的函数相混淆)。如果有任何 cv 限定符被添加到到函数类型的别名,那么它会被忽略。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx11">
|
|
<td>
|
|
<p>可以用 <a href="cpp-language-lambda.html">lambda 表达式</a>产生无名函数。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<p>同一作用域中,可以有多个函数拥有相同的名称,只要其形参列表,以及对于非静态成员函数的 cv <span class="t-rev-inl t-since-cxx11"><span>或引用</span> <span><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></span></span>限定不同即可。这被称作<a href="cpp-language-overload_resolution.html">函数重载</a>。只有返回类型<span class="t-rev-inl t-since-cxx17"><span>及 noexcept 说明</span> <span><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></span></span>不同的函数声明之间无法重载。<a href="cpp-language-overloaded_address.html">重载函数的地址</a>有专门的确定方法。</p>
|
|
<h3><span class="mw-headline" id=".E5.87.BD.E6.95.B0.E5.AF.B9.E8.B1.A1">函数对象</span></h3>
|
|
<p>除了函数左值,函数调用表达式还支持函数指针以及重载了函数调用运算符及可转换为函数指针的任何类类型的值<span class="t-rev-inl t-since-cxx11"><span>(包括 <a href="cpp-language-lambda.html">lambda 表达式</a>)</span> <span><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></span></span>。这些类型被统称为<a href="cpp-named_req-FunctionObject.html"><span style="font-style:italic">函数对象</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(FunctionObject)</span></a> ,而且在 C++ 标准库中的各处都有使用,示例可见<a href="cpp-named_req-BinaryPredicate.html"><span style="font-style:italic">二元谓词</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(BinaryPredicate)</span></a> 和<a href="cpp-named_req-Compare.html"><span style="font-style:italic">比较</span> <span style="font-family: Georgia, 'DejaVu Serif', serif; font-style:italic">(Compare)</span></a> 的用法。</p>
|
|
<p>标准库也提供数个预定义的<a href="cpp-utility-functional.html">函数对象模板</a>,以及一些组成新函数对象的方法(包括 <span class="t-lc"><a href="cpp-utility-functional-less.html">std::less</a></span><span class="t-rev-inl t-since-cxx11"><span>、<span class="t-lc"><a href="cpp-utility-functional-mem_fn.html">std::mem_fn</a></span>、<span class="t-lc"><a href="cpp-utility-functional-bind.html">std::bind</a></span> 和 <span class="t-lc"><a href="cpp-utility-functional-function.html">std::function</a></span></span> <span><span class="t-mark-rev t-since-cxx11">(C++11 起)</span></span></span>)。</p>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|