English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Golang 프로그래밍 언어에서 포인터는 다른 변수의 메모리 주소를 저장하는 변수입니다. 함수에 포인터를 전달할 수 있으며, Golang 함수에서 포인터를 반환할 수 있습니다. C/ 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: 함수 ‘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에서포인터및포인터를 함수로 전달