程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> 關於C >> c++返回局部變量的指針

c++返回局部變量的指針

編輯:關於C

 函數返回指針。本來就是一個比較容易出問題的操作。在霍頓的《VC++ 入門經典》一書中,給出了一個很有代表性的例子,如下:

  // Ex5_11.cpp

  #include <iostream>

  using std::cout;

  using std::endl;

  double* treble(double); // Function prototype

  int main(void)

  {

  double num = 5.0; // Test value

  double* ptr = 0; // Pointer to returned value

  ptr = treble(num);

  cout << endl

  << "Three times num = " << 3.0*num;

  cout << endl

  << "Result = " << *ptr; // Display 3*num

  cout << endl;

  system("pause");

  return 0;

  }

  // Function to treble a value - mark 1

  double* treble(double data)

  {

  double result = 0.0;

  result = 3.0*data;

  return &result;

  }

  兩個輸出語句,一個直接輸出3*5=15.另一個在一個函數中進行了乘法運算,也是5*3, 存到result變量中也沒有任何問題。返回這個變量的指針,輸出時再接觸引用。貌似也沒有錯誤。兩條輸出語句似乎都應該輸出15.但事實不是這樣。編譯 器會拋出[Warning] address of local variable `result' returned 這樣一個警告信息。程序運行後的結果也並非是我們預想的那樣。第二條輸出語句會輸出一個不可預見的值。這是怎麼回事呢?

  仔細分析一下,result是作用域在treble函數中的局部變量。當函數執行結束後。變量result會被析構。其原先占用的內存區域已經被系統回收,可以存儲任何數據。而返回的指向該地址的指針也失去了其原有的意義。因此我們得到這樣一條准則:

  永遠不要從函數中返回局部自動變量的地址。

  如果你真的需要這樣操作。你可以在函數的參數表中傳入一個指針變量。然後將需要寫入的數據寫入到該指針變量指向的地址。由於該指針指向的變量,作用域在函數體 之外。因此不會在函數結束結束時被回收。

  現在回到我們遇到的問題。時間函數localtime就是一個返回指針的函數。返回值類 型:tm*

  該如何接收這個返回值?當然是聲明一個與之類型相同的變量。

  於是你會這樣寫:tm* result;

  接下來呢?還用問?賦值嘛。是不是這樣:result=localtime(....);

  返回什麼類型,當然要給什麼類型的變量 賦值。但是這樣卻發生了我們不想看到的結果。

  也許你想到了。就是這個指針!返回的指針在函數結束後不再有效。正確的方法可以是:

  tm result;

  result = *localtime(....);

  也可以是:

  tm* result;

  *result = *localtime(...);

  正確的方法的共同特點是在函數結束前,對返回的指針解除引用。然後用這個數值,為變量或指針指向的內存區域賦值。也就是說必須要復制函 數的返回值。因為函數體中變量會被析構。

  指針是靈活而強大的,避免低級錯誤,明確基本概念。才能讓指針更好的為我們服務。

*
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved