2016-09-29 2 views
3
#include <stdio.h> 

int* func() 
{ 
    static int a = 5; /* line 5 */ 
    printf("%d\n",++a); 
    return &a; /* line 7 */ 
} 

int main(void) 
{ 
    int *b = func(); /* line 12 */ 
    (*b)++; 
    func(); 
} 

이것은 코딩 작업을 테스트하는 코드 예제이므로 반드시 최적 일 필요는 없습니다. 나는 C++과 Java에 대한 기본적인 지식을 갖고 있지만 이것들은 C에서 문제가있는 포인터이다.C.의 포인터이 작은 코드에 대한 설명이 필요합니다

  1. func()의 반환 유형은 포인터이지만 정수 (line7)의 주소를 반환합니다. 정수가 정적이라는 사실 (5 행)은 이것으로 무엇인가해야합니까?

  2. 12 번 줄은 실제로 무엇을합니까? 이 코드의

출력은 다음과 같습니다

6

8

+1

Inc'static' 키워드로 인해 전역 변수로 작동하는 변수 'a'. – LPs

+1

'static '이 없으면 이것은 폭탄이 될 것입니다 ....'a'를 세 번 증가시키는 복잡한 방법이 있습니다. '(* b)'는'a'를 가리킴으로써 라인은'a ++'와 같습니다. –

+4

"저는 C++에 대한 기본적인 지식을 가지고 있습니다"이것은 매우 기본적인 것들입니다. 이 코드가 무엇인지 모르지만 C++ 프로그래밍 작업을 신청할 것이라고 말하고 있습니까? – Lundin

답변

5

그 정수가 정적 인 사실을합니까 (5 호선)이와 아무것도 할 필요가?

예. 그렇지 않으면 포인터를 자동 지역 변수에 반환하면 정의되지 않은 동작이 호출됩니다.

static 로컬 변수의 수명은 프로그램 종료시 종료됩니다. 따라서 메모리 위치는 프로그램이 끝날 때까지 할당되므로 위치를 반환 할 수 있습니다.

값 다음 b 가리키는 및 역 참조 라인 (*b)++;)는 1

1

Func을 (기준 값을 증가 A는 함수의 모든 호출들 사이에서 공유되는 것을 의미 로컬 "정적"변수를 갖는다 .

이 함수는이 변수에 대한 포인터를 반환합니다. 이 포인터를 통해 func() 외부의 세계는이 로컬 정적에 액세스 할 수 있습니다.

그래서 12 행에서 main()에서 포인터를 만들고 a를 가리 키도록 초기화합니다. 그런 다음 deregerence b를 할 때마다 직접 수정 내용을 포함하는 내용에 액세스합니다.

-3

1) 함수 외부에서 로컬 변수의 주소를 반환하는 것은 좋지 않으므로 로컬 변수를 정의해야합니다. 정적 변수로 ..... 그렇기 때문에 5 행은 이것과 관련이 없습니다 .......... 오직 a만을 반환해야하고 &을 반환하지 않아야합니다.

return a; 
+0

참고 : [static-use-of-the-use-of-static-local-variable-when-global-variable-at-th]] (http://stackoverflow.com/questions/15808049)/정적 - 지역 변수 사용 (what-is-the-use-of-the-use-of-the-variable-at-th) – LPs

2

포인터는 Java 또는 C++ 참조와 다르지 않으며 C++에서는 포인터를 사용할 수 있습니다.

func는 정적 변수 a이 포함되어 여기

이 일어나는 것이다. 정적 변수의 수명은 프로그램 전체에 걸쳐 있으며 C 언어는 메인이 호출되기 전에 초기화됩니다 (컴파일 또는 시작 시점 일 수 있음). 여기서 func은 정적 변수의 값을 증가시키고 인쇄하며 주소를 반환합니다.

main은 처음에 func을 호출하고 b 포인터에 정적 변수의 주소를 저장합니다.b은 정적 변수의 값을 높이는 데 사용되며 func이 다시 한 번 호출됩니다.

2

나는 C++

아니, 당신은 정말하지의 기본 지식을 가지고있다. 모든 것을 설명 하겠지만, 이것은 이상한 C 스타일의 것이 아니라, 기본 C와 기본 언어 (기본 언어는 C++)입니다. 포인터를 이해하지 못한다면 대부분 C++의 자바 스타일 하위 집합을 알 수 있습니다.

  1. FUNC()의 리턴 타입은 포인터이지만 정수 (line7)의 ADRESS을 반환합니다. 정수가 정적이라는 사실 (5 행)은 이것으로 무엇인가해야합니까?

    여기에 귀하의 질문이 무엇인지 잘 모르겠습니다.

    정수 a 정적입니다. 실제로 해당 기능이 작동하는 이유와 관련이 있습니다. 그러나 주소를 입력하는 구문과 관련이 없습니다. 그 global_a 제외

    /* static */ int global_a = 5; 
    int* func2() 
    { 
        printf("%d\n",++global_a); 
        return &global_a; 
    } 
    

    가 동일한 변환 수단에서 다른 코드로 표시 될 것이며, 원래의 static a는 함수 내부에서만 볼 :

    함수는이 효과적으로 동일하다. 그렇지 않으면 그들은 같은 평생과 행동을합니다.

    global_a에 대한 static 한정자를 주석 처리했음을 유의하십시오. 이는 여전히 유효하지만 기능 범위가 아닌 전역에서 약간 다른 것을 의미합니다.

    ... ... 괜찮아요없고, a의 수명과는 아무

    반환 유형은 포인터이지만 정수의 주소를 반환합니다. 정수 (&a) 의 주소는 포인터 int *입니다. 이것이 표현의 의미입니다. 이는 항상 모든 변수에 적용되며 static 키워드는 아무 것도 변경하지 않습니다. 위에서 언급 한 바와 같이 그 이름은 함수 내부로 제한 유지하면서, 그것은, 그것을 글로벌과 같은 수명을 제공합니다 - 않습니다 영향을 static 키워드 a의 수명은 무엇

    . 이 다른 버전 비교 :

    int* func() 
    { 
        /*static*/ int a = 5; 
        printf("%d\n",++a); 
        return &a; 
    } 
    

    이것은 완전히 손상되었습니다.

    • 첫째, 항상 각 시간으로 당신이, a라는 새로운 지역 변수를 만들고 5로 설정 한 다음를 증가 함수를 호출, 6을 인쇄 할 수 있습니다. static a은 대신 5 번으로 초기화되고, 동일한 a이 함수가 호출 될 때마다 증가합니다.

    • 두 번째로 호출자가 포인터를 수신 할 때까지 a이 존재하지 않으므로 로컬 변수의 주소를 반환하는 것이 문제가됩니다. astatic이거나 전역 변수이거나 함수 호출보다 오래 지속되지 않는 한 포인터를 반환해도 아무 것도 할 수 없습니다.

  2. 라인 (12)은 실제로 무엇을 하는가?

    int *b

    변수 선언,

    = func()은 우리가

    int *b = func(); 통화 func을 역할을 논의했습니다 func() 함수를 호출 정수로 형 포인터, b라고하고, (포인터를 결과를 할당 주소는 a)에서 변수 b으로 변경됩니다.

    그래서 b은 이제 정수에 대한 포인터입니다. 문제의 정수는 a이며 범위를 벗어난 이름으로 참조 할 수는 없더라도 정적이므로 func 범위 밖에 있습니다. 실제로 a 여전히 입력 int&의 기준을 산출하기 때문에

    발현 *b는 이런 맥락에서 불행 이름 포인터를 역 참조.

0

은 내가 초기화 된 컴파일시 코드에서 값이 제공되는 것들이기 때문에 초기화와 정적 변수에 문제가 있다고 생각합니다. 이들은 일반적으로 컴파일러에 따라 다르지만 DS에 저장됩니다. 다시 특정 컴파일러 비록

다른 형태는 실행시에 초기화되고, BSS 세그먼트에 저장된 초기화 정적 인

#include <stdio.h> 

int* func() 
{ 
    static int a; 
    a = 5; 
    printf("%d\n",++a); 
    return &a; 
} 

int main(void) 
{ 
    int *b = func(); 
    (*b)++; 
    func(); 
} 

코드 출력이

6

6

차이점은 초기화에만 해당합니다.

관련 문제