English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Golangプログラミング言語のポインタは、他の変数のメモリアドレスを保存する変数です。ポインタを関数に渡すことができますし、Golangの関数からポインタを返すこともできます。C/ c++中,不建议在函数外部返回局部变量的地址,因为它在函数返回后超出了作用域。因此,要在C/ c++中、函数返回指针时,必须将局部变量定义为静态变量。
例:まずCの例を見てみましょう++例えば、以下のプログラムでは、コード行(int lv = n1 * n1;)は警告を発生させます。なぜなら、それは関数のローカルコードであるからです。警告を避けるために、それを静的変数に設定してください。
// C ++プログラムが返します //関数からのポインタ #include <iostream> using namespace std; //ポインタを返す型を持つ引数を受け取る int* rpf(int); int main() { int n = 745; //nの値を表示 cout << n << endl; //関数を呼び出します cout << *rpf(n) << endl; } //関数を定義 int* rpf(int n1) { //ローカル変数を取得 //関数内部で int lv = n1 * n1; // static int lv = n1 * n1; //C++ 中 これは警告を発生させることになります //アドレスを返します return &lv; }
警告
prog.cpp: In function ‘int* rpf(int)’:
prog.cpp:24:9: warning: address of local variable ‘lv’ returned [-Wreturn-local-addr]
int lv = n1 * n1;
出力:
745
この場合の主な理由は、コンパイラが常に関数呼び出しにスタックを生成することです。関数が終了すると、関数のスタックも削除され、関数のローカル変数が範囲外になります。これを静的に設定することで問題を解決できます。なぜなら、静的変数はその範囲を超えても値を保持する性質を持っているからです。
しかしGoコンパイラは非常に賢いです!。これは、関数のローカル変数にスタック上のメモリを割り当てるのではなく、ヒープ上に割り当てます。以下のプログラムでは、変数lvメモリはヒープ上に割り当てられます。なぜなら、Goコンパイラは変数をローカル範囲から逃げるために逃れ分析を実行するからです。
//Go関数はポインタを返します package main import "fmt" func main() { //関数を呼び出します n := rpf() //値を表示 fmt.Println("nの値: ", *n) } //整数を引数に持つ関数を定義しています //ポインタを返す型として func rpf() *int { //ローカル変数 //関数内部で短い演算子を使って宣言しています lv := 100 // lvのアドレスを返します return &lv }
出力:
nの値: 100
注意: GolangはCのように / C ++このようなポインタアルゴリズムのサポートは全く提供されていません。実行すると、コンパイラがエラーを発生させ、無効な操作と判断します。
関連知識: Goでのポインタおよびポインタを関数に渡す