⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 returnby.html

📁 关于 C++ 的历史无须我来介绍了
💻 HTML
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>

  
  <link rel="stylesheet" href="css/stdlayout.css" type="text/css">

  
  <link rel="stylesheet" href="css/print.css" type="text/css">

  
  <meta content="text/html; charset=gb2312" http-equiv="content-type">

  
  <title>return 的传值、传参考</title>
</head>


<body>

<h3><a href="http://caterpillar.onlyfun.net/GossipCN/index.html">From
Gossip@caterpillar</a></h3>

<h1><a href="CppGossip.html">C++
Gossip:&nbsp;<span class="Topic">return 的传值、传参考</span><br>

</a></h1>

<br>

在定义函式时,一定要定义函式的传回值型态,如果函式不传回值,则使用void表示不传回任何数值;一旦指定函式的传回值不为void,则在函式中一定要
使用return传回一个数值,否则编译器将回报错误。 <br>

<br>

在之前的范例中,您只是使用传值的方式传回函式的执行结果,事实上您也可以传回一个指标或是参考,传回指标通常意味着您要对这个指标所指向的记忆体位置作
取值或更动的动作,例如下面的程式中,您在函式中动态建立一个阵列,并传回它的指标值: <br>

<br>

<pre>#include &lt;iostream&gt; <br>using namespace std; <br><br>int* createArray(int);<br>void deleteArray(int*);<br><br>int main() { <br>    int m = 0; <br><br>    cout &lt;&lt; "阵列大小: "; <br>    cin &gt;&gt; m; <br><br>    int *arr = createArray(m); <br><br>    for(int i = 0; i &lt; m; i++) {<br>        arr[i] = i; <br>    }<br>    <br>    for(int i = 0; i &lt; m; i++) {<br>        cout &lt;&lt; "arr[" &lt;&lt; i &lt;&lt; "] = " <br>             &lt;&lt; arr[i] &lt;&lt; endl; <br>    }<br><br>    deleteArray(arr);<br><br>    return 0; <br>} <br><br>// 传回建立的阵列位址<br>int* createArray(int m) { <br>    int *a = new int[m]; <br><br>    for(int i = 0; i &lt; m; i++) {<br>        a[i] = 0; <br>    }<br><br>    return a; <br>}<br><br>void deleteArray(int* arr) {<br>     delete [] arr; <br>}</pre>

<span class="postbody"><br>

执行结果:</span><br>

<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">

  <tbody>

    <tr>

      <td style="background-color: rgb(0, 0, 0);"><small><span style="color: rgb(255, 255, 255);">阵列大小: 5<br>

arr[0] = 0<br>

arr[1] = 1<br>

arr[2] = 2<br>

arr[3] = 3<br>

arr[4] = 4</span></small><span style="color: rgb(255, 255, 255);"><br>

      </span></td>

    </tr>

  
  </tbody>
</table>

<br>

由于您使用动态配置的方式,所以在使用delete之前,这块被配置的记忆体并不会自动清除,所以您可以直接传回给呼叫函式的主函式,注意如果您不是使用
new来配置,则在副函式中所宣告的变数记忆体,在函式执行结束后都会自动消失,则您传回指标值也就没有意义,也会造成存取错误,因为该块记忆体在副函式
执行完毕后已经自动回收了。 <br>

<br>

在这边的范例您也看到了如何传递阵列给函式,以及如何传回一个阵列,在C++中传递阵列或传回阵列一律使用传址方法,因为阵列名称本身就是个指标,储存有
位址资讯。<br>

<br>

在进一步讨论传参考之前,您先要了解到,在C++中传递一个物件,预设也是使用传值的方式,例如下面这个程式: <br>

<br>

<pre>#include &lt;iostream&gt; <br>#include &lt;string&gt; <br>using namespace std; <br><br>string foo(); <br><br>int main() { <br>    string str; // 空字串<br><br>    str = foo(); <br><br>    cout &lt;&lt; "address: " &lt;&lt; &amp;str <br>         &lt;&lt; endl &lt;&lt; str &lt;&lt; endl; <br>    <br>    return 0; <br>} <br><br>string foo() { <br>    string s = "This is caterpillar speaking."; <br><br>    cout &lt;&lt; "address: " &lt;&lt; &amp;s <br>         &lt;&lt; endl &lt;&lt; s &lt;&lt; endl; <br><br>    return s; <br>}<br></pre>

<span class="postbody"><br>

执行结果:</span><br>

<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">

  <tbody>

    <tr>

      <td style="background-color: rgb(0, 0, 0);"><small><span style="color: rgb(255, 255, 255);">address: 0x22ff40<br>

This is caterpillar speaking.<br>

address: 0x22ff50<br>

This is caterpillar speaking.</span></small><span style="color: rgb(255, 255, 255);"><br>

      </span></td>

    </tr>

  
  </tbody>
</table>

<br>

您可以发现到,两个字串的记忆体位置并不相同,表示传回的字串在传值时是复制一份新的传回,您可以改用传参考的方式将字串值传回,方式如下所示: <br>

<br>

<pre>#include &lt;iostream&gt; <br>#include &lt;string&gt; <br>using namespace std; <br><br>string&amp; foo(); <br><br>int main() { <br>    string &amp;str = foo(); <br><br>    cout &lt;&lt; "address: " &lt;&lt; &amp;str <br>         &lt;&lt; endl &lt;&lt; str &lt;&lt; endl; <br><br>    delete &amp;str; <br><br>    return 0; <br>} <br><br>string&amp; foo() { <br>    string *s = new string("This is caterpillar speaking."); <br><br>    cout &lt;&lt; "address: " &lt;&lt; s <br>         &lt;&lt; endl &lt;&lt; *s &lt;&lt; endl; <br><br>    return *s; <br>}<br></pre>

<span class="postbody"><br>

</span><span class="postbody">执行结果:</span><br>

<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">

  <tbody>

    <tr>

      <td style="background-color: rgb(0, 0, 0);"><small><span style="color: rgb(255, 255, 255);">address: 0x3d2458<br>

This is caterpillar speaking.<br>

address: 0x3d2458<br>

This is caterpillar speaking.</span></small><span style="color: rgb(255, 255, 255);"><br>

      </span></td>

    </tr>

  
  </tbody>
</table>

<br>

使用传参考的方式是直接告知物件的记忆体位置,而没有作物件复制的动作,可以加快程式执行的效率,而某些情况下,编译器也会自行将物件的传回结果自动设定
为传参考,即使语法上并没有指定,例如: <br>

<br>

<pre>#include &lt;iostream&gt; <br>#include &lt;string&gt; <br>using namespace std; <br><br>string foo(); <br><br>int main() { <br>    string str = foo(); // 空字串<br><br>    cout &lt;&lt; "address: " &lt;&lt; &amp;str <br>         &lt;&lt; endl &lt;&lt; str &lt;&lt; endl; <br>    <br>    str = foo(); // 指定新字串,会复制一份<br>    <br>    cout &lt;&lt; "address: " &lt;&lt; &amp;str <br>         &lt;&lt; endl &lt;&lt; str &lt;&lt; endl; <br>    <br>    return 0; <br>} <br><br>string foo() { <br>    string s = "This is caterpillar speaking."; <br><br>    cout &lt;&lt; "address: " &lt;&lt; &amp;s <br>         &lt;&lt; endl &lt;&lt; s &lt;&lt; endl; <br><br>    return s; <br>}<br></pre>

<span class="postbody"><br>

</span><span class="postbody">
执行结果:</span><br>

<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">

  <tbody>

    <tr>

      <td style="background-color: rgb(0, 0, 0);"><small><span style="color: rgb(255, 255, 255);">address: 0x22ff50<br>

This is caterpillar speaking.<br>

address: 0x22ff50<br>

This is caterpillar speaking.<br>

address: 0x22ff40<br>

This is caterpillar speaking.<br>

address: 0x22ff50<br>

This is caterpillar speaking.</span></small><span style="color: rgb(255, 255, 255);"><br>

      </span></td>

    </tr>

  
  </tbody>
</table>

<br>

在这个程式中,第一行宣告str并指定foo()传回值时,虽然并没有指定传回参考,但是您可以看到两个字串变数的值都指向同一块记忆体,但是编译器会自
动判断并以传参考的方式来传回这个物件,而不是使用传值的方法传回,这是编译器的功能,您可以将之当作一个效率上的考量作法,但不可以将之当作一个传参考
的方式来使用。 <br>

<br>

必须注意的是,函式中的区域变数在函式开始时被配置,在函式结束后所占有的记忆体位址也会被清除,绝对不要传回一个区域变数的位址给呼叫者,或是以传参考
的方式传回一个区域变数,因为您所存取的记忆体位址中资料是未知的,所以结果是不可预期的。<br>

<br>

</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -