C에서 "정적"은 무엇을 의미합니까?


1135

staticC 코드의 다른 곳에서 사용되는 단어를 보았습니다 . 이것은 C #의 정적 함수 / 클래스와 비슷합니까 (구현이 객체간에 공유되는 경우)?



15
제목 @Lundin의 끝에서 "C 프로그램에서"를 제거하는 이유는 무엇입니까? c 태그가 있으면 약간 중복 되지만 태그를 검사하지 않고도 분류를 더 빨리 볼 수 있습니다. 이 중복은 정적 또는 Google 검색 과 같은 다른 언어에 대한 질문이 포함 된 방향에서 질문에 도달 할 때 매우 편안합니다 .
Palec

5
@Palec 태그 목록에있는 항목이 제목에 중복되는 SO 정책이 있습니다. 이 사이트는 실제 웹 사이트에 C를 자동으로 추가합니다. "C static"에 대한 Google은이 답변을 최고의 인기로 제공합니다. 이것이 변경 된 이유는이 질문이 이제 SO C 언어 FAQ 의 일부이며 추가 된 모든 게시물이 약간 연마 되었기 때문 입니다.
룬딘

1
@Lundin 제목에 "C"를 유지하는 것이 좋습니다. SO는 제목에 하나의 태그 만 추가하기 때문입니다 (가장 일반적입니까?). 언젠가 "구문"이 C보다 더 많은 질문에 도달하면 어떻게 되나요? 차라리 명시 적 행동 :-) 편집 사용하십시오 : 아하지만 그렇지 않으면 말하는 메타 질문이있다 : meta.stackexchange.com/questions/19190/...
치로 틸리冠状病毒审查六四事件法轮功

1
이것은 Quora에서 찾은 설명입니다. 꼭 읽을 가치가 있습니다!
nalzok

답변:


1519
  1. 함수 내부의 정적 변수는 호출간에 값을 유지합니다.
  2. 정적 전역 변수 또는 함수는 선언 된 파일에서만 "본"

초보자라면 (1)이 더 많은 주제입니다.

#include <stdio.h>

void foo()
{
    int a = 10;
    static int sa = 10;

    a += 5;
    sa += 5;

    printf("a = %d, sa = %d\n", a, sa);
}


int main()
{
    int i;

    for (i = 0; i < 10; ++i)
        foo();
}

인쇄합니다 :

a = 15, sa = 15
a = 15, sa = 20
a = 15, sa = 25
a = 15, sa = 30
a = 15, sa = 35
a = 15, sa = 40
a = 15, sa = 45
a = 15, sa = 50
a = 15, sa = 55
a = 15, sa = 60

이것은 함수가 호출간에 상태를 유지해야하고 전역 변수를 사용하지 않으려는 경우에 유용합니다. 그러나이 기능은 매우 드물게 사용해야합니다. 코드가 스레드로부터 안전하지 않고 이해하기 어렵습니다.

(2) "액세스 제어"기능으로 널리 사용됩니다. 일부 기능을 구현하는 .c 파일이있는 경우 일반적으로 일부 "공개"기능 만 사용자에게 노출합니다. static사용자가 액세스 할 수 없도록 나머지 기능을 수행해야 합니다. 이것은 캡슐화, 좋은 습관입니다.

인용 위키 백과 :

C 프로그래밍 언어에서 static은 전역 변수 및 함수와 함께 사용되어 해당 범위를 포함 파일로 설정합니다. 로컬 변수에서 static은 자동 할당 된 메모리 대신 정적 할당 된 메모리에 변수를 저장하는 데 사용됩니다. 언어가 두 가지 유형의 메모리 구현을 지시하지는 않지만 정적으로 할당 된 메모리는 일반적으로 컴파일 타임에 프로그램의 데이터 세그먼트에 예약되며 자동 할당 된 메모리는 일반적으로 임시 호출 스택으로 구현됩니다.

그리고 두 번째 질문에 대답하기 위해 C #과 다릅니다.

그러나 C ++에서는 static클래스 속성 (같은 클래스의 모든 객체간에 공유) 및 메소드를 정의하는 데에도 사용됩니다. C에는 클래스가 없으므로이 기능은 관련이 없습니다.


179
Pax, OP는 정적에 대해 알지 못하므로 컴파일 단위와 파일의 차이점에 그를 빠뜨릴 것을 제안합니까? :-)
Eli Bendersky

138
컴파일 단위는 컴파일러가 보는 단일 파일입니다. .c 파일은 다른 .c 파일을 포함 할 수 있지만 프리 프로세서가 포함을 정렬 한 후 컴파일러는 단일 "컴파일 단위"만 보게됩니다.
Eli Bendersky

81
@robUK : 컴파일러는 .h 파일에 대해서도 알지 못합니다. 이들은 전 처리기의 .c 파일로 결합됩니다. 예, .c 파일은 모든 헤더가 포함 된 단일 컴파일 단위라고 말할 수 있습니다.
Eli Bendersky 2019

6
@TonyD 어쩌면 혼란 스럽지만 컴파일이 작동하는 방식입니다. 일반적으로 하나 .c의 헤더 파일 이 될 수 있지만 악마는 항상 일반적인 것이 아닙니다 .
peterph

7
@TonyD 컴파일러가 컴파일을 수행합니다. 전처리 기는 전처리를 수행합니다. 툴체인을 '컴파일러'라고 부르더라도 그것이 무엇인지 또는 무엇을 바꾸지는 않습니다.
Miles Rout

231

여기에서 다루지 않은 용도가 하나 더 있으며, 이는 함수에 대한 인수로 배열 유형 선언의 일부입니다.

int someFunction(char arg[static 10])
{
    ...
}

이와 관련하여이 함수에 전달 된 인수는 char10 개 이상의 요소가 포함 된 유형의 배열이어야 함을 지정 합니다. 자세한 내용은 내 질문을 참조하십시오 여기 하십시오 .


3
C에 배열 인수가 있다고 생각하지 않았습니까? Linus Torvalds는이 일을하는 사람들에 대해 화를냅니다.
suprjami

13
@jamieb : C 배열 인자를하지 않지만 기능이 기대하는 특정 신택스 수단 arg[0]을 통해이 arg[9](또한 함수는 NULL 포인터를 허용하지 않는 것을 의미한다) 값을 가질 것이다. 컴파일러는이 정보를 어떻게 든 최적화를 위해 사용할 수 있으며 정적 분석기는이 정보를 사용하여 함수에 널 포인터 (또는 지정된 것보다 적은 수의 요소를 가진 배열이 제공되지 않는 경우)가 제공되지 않도록 할 수 있습니다.
dreamlax

19
@Qix-이것은 staticC99에 주어진 새로운 오버로드 의미 입니다. 10 년 반이 넘었지만 모든 컴파일러 작성자가 모든 C99 기능을 수용 한 것은 아니므로 C99는 대체로 알려지지 않았습니다.
Happy Green Kid Naps

@suprjami 내가 100 %를 해요 당신이 무엇을 의미하는 "배열 인수" 하지만 말은 경우 int arr[n];, 다음입니다 VLA (가변 길이 배열) C99에서 추가되었다. 그게 무슨 뜻입니까?
RastaJedi

170

짧은 대답 ... 그것은 달려 있습니다.

  1. 정적 정의 로컬 변수는 함수 호출간에 값을 잃지 않습니다. 다시 말해, 그것들은 전역 변수이지만 그것들이 정의 된 지역 함수의 범위를 갖습니다.

  2. 정적 전역 변수는 정의 된 C 파일 외부에서 볼 수 없습니다.

  3. 정적 함수는 정의 된 C 파일 외부에서 볼 수 없습니다.


8
"정적 기능"과 "개인 기능"도 같은 의미입니까? 마찬가지로 "정적 전역 변수"와 "비공개 전역 변수"도 같은 것입니까?
user1599964

40
이것은 C에 관한 것입니다. C에는 개인 / 공공 인이 없습니다.
chris

19
@ user1599964 privateC 에는 없지만 , 비유는 좋다 : static은 주어진 파일에 "개인"을 만든다. 그리고 C의 파일은 종종 C ++의 클래스에 매핑됩니다.
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功

66

다중 파일 변수 범위 예

여기서 정적이 여러 파일에서 함수 정의 범위에 미치는 영향을 설명합니다.

ac

#include <stdio.h>

/*
Undefined behavior: already defined in main.
Binutils 2.24 gives an error and refuses to link.
/programming/27667277/why-does-borland-compile-with-multiple-definitions-of-same-object-in-different-c
*/
/*int i = 0;*/

/* Works in GCC as an extension: https://stackoverflow.com/a/3692486/895245 */
/*int i;*/

/* OK: extern. Will use the one in main. */
extern int i;

/* OK: only visible to this file. */
static int si = 0;

void a() {
    i++;
    si++;
    puts("a()");
    printf("i = %d\n", i);
    printf("si = %d\n", si);
    puts("");
}

main.c

#include <stdio.h>

int i = 0;
static int si = 0;

void a();    

void m() {
    i++;
    si++;
    puts("m()");
    printf("i = %d\n", i);
    printf("si = %d\n", si);
    puts("");
}

int main() {
    m();
    m();
    a();
    a();
    return 0;
}

GitHub의 상류 .

컴파일하고 실행하십시오.

gcc -c a.c -o a.o
gcc -c main.c -o main.o
gcc -o main main.o a.o

산출:

m()
i = 1
si = 1

m()
i = 2
si = 2

a()
i = 3
si = 1

a()
i = 4
si = 2

해석

  • si파일마다 하나씩 두 개의 개별 변수가 있습니다.
  • 단일 공유 변수가 있습니다 i

평소와 같이 범위가 작을수록 좋습니다. 가능하면 항상 변수를 선언하십시오 static.

C 프로그래밍에서 파일은 종종 "클래스"를 나타내는 데 사용되며 static변수는 클래스의 전용 정적 멤버를 나타냅니다.

그것에 대해 말하는 표준

C99 N1256 draft 6.7.1 "스토리지 클래스 지정자"는 "스토리지 클래스 지정자"라고 말합니다 static.

6.2.2 / 3 "식별자의 연결"은 다음을 static의미합니다 internal linkage.

객체 또는 함수에 대한 파일 범위 식별자 선언에 스토리지 클래스 지정자 정적이 포함되어 있으면 식별자에 내부 연결이 있습니다.

그리고 6.2.2 / 2는 internal linkage우리 예제에서와 같이 동작 한다고 말합니다 :

전체 프로그램을 구성하는 변환 단위 및 라이브러리 세트에서 외부 링크가있는 특정 식별자의 각 선언은 동일한 객체 또는 함수를 나타냅니다. 하나의 변환 단위 내에서 내부 연결이있는 식별자의 각 선언은 동일한 객체 또는 함수를 나타냅니다.

여기서 "번역 단위는 전처리 후 소스 파일입니다.

GCC가 ELF (Linux)를 위해 어떻게 구현합니까?

와 더불어 STB_LOCAL 바인딩.

우리가 컴파일하면 :

int i = 0;
static int si = 0;

다음과 같이 심볼 테이블을 분해하십시오.

readelf -s main.o

출력에는 다음이 포함됩니다.

Num:    Value          Size Type    Bind   Vis      Ndx Name
  5: 0000000000000004     4 OBJECT  LOCAL  DEFAULT    4 si
 10: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    4 i

바인딩은 그들 사이의 유일한 중요한 차이점입니다. 섹션에 Value대한 오프셋 일 뿐이 .bss므로 차이가있을 것으로 예상합니다.

STB_LOCALhttp://www.sco.com/developers/gabi/2003-12-17/ch4.symtab.html 의 ELF 사양에 설명되어 있습니다 .

STB_LOCAL 로컬 심볼은 해당 정의를 포함하는 오브젝트 파일 외부에 표시되지 않습니다. 동일한 이름의 로컬 기호가 서로 방해하지 않고 여러 파일에 존재할 수 있습니다

표현하기에 완벽한 선택 static입니다.

정적 변수가없는 변수 STB_GLOBAL는 사양이며 다음과 같이 말합니다.

링크 편집기가 재배치 가능한 여러 오브젝트 파일을 결합 할 때 동일한 이름을 가진 STB_GLOBAL 기호의 다중 정의를 허용하지 않습니다.

이는 여러 비 정적 정의의 링크 오류와 일치합니다.

로 최적화를 크랭크 -O3하면 si심볼이 심볼 테이블에서 완전히 제거됩니다. 어쨌든 외부에서는 사용할 수 없습니다. TODO 최적화가 없을 때 왜 심볼 테이블에 정적 변수를 유지합니까? 그들은 무엇이든 사용할 수 있습니까? 아마도 디버깅을 위해.

또한보십시오

C ++ 익명 네임 스페이스

C ++에서는 정적 대신 익명 네임 스페이스를 사용하여 비슷한 효과를 얻을 수 있지만 유형 정의를 숨 깁니다. 이름이없는 / 익명 네임 스페이스와 정적 함수


39

때에 따라 다르지:

int foo()
{
   static int x;
   return ++x;
}

이 함수는 1, 2, 3 등을 반환합니다. --- 변수가 스택에 없습니다.

ac :

static int foo()
{
}

이 함수는이 파일에서만 범위를 갖습니다. 따라서 ac와 bc는 서로 다른 foo()s를 가질 수 있으며 foo는 공유 객체에 노출되지 않습니다. 따라서 AC에서 foo를 정의 b.c하면 다른 곳 에서 또는 다른 곳에서 액세스 할 수 없습니다 .

대부분의 C 라이브러리에서 모든 "비공개"기능은 정적이며 대부분의 "공용"기능은 아닙니다.


18
스택 또는 힙에없는 x를 언급하면 ​​+1입니다. 정적 메모리 공간에 있습니다.
Gob00st

1
@ Gob00st 정적 메모리 공간? "데이터 세그먼트"를 의미 했습니까?
Yousha Aleayoub

24

사람들은 C에서 '정적'은 두 가지 의미가 있다고 계속 말합니다. 나는 그것을 의미하는 대체 방법을 제공합니다.

  • 항목에 '정적'을 적용하면 해당 항목에 다음 두 가지 속성이 있습니다. (b) 영구적이다.

그것이 두 가지 의미를 갖는 것처럼 보이는 이유는 C에서 '정적'이 적용될 수있는 모든 항목이 이미이 두 가지 속성 중 하나를 가지고 있기 때문에 특정 용도가 다른 것만 포함하는 것처럼 보입니다 .

예를 들어 변수를 고려하십시오. 함수 외부에서 선언 된 변수는 이미 데이터 세그먼트에서 지속성을 가지고 있으므로 '정적'을 적용하면 현재 범위 (컴파일 단위) 외부에서만 보이지 않습니다. 반대로, 함수 내부에 선언 된 변수는 이미 현재 범위 (함수) 외부에 표시되지 않으므로 '정적'을 적용하면 지속될 수 있습니다.

함수에 '정적'을 적용하는 것은 전역 변수에 적용하는 것과 같습니다. 코드는 반드시 영구적이어야합니다 (적어도 언어 내에서). 따라서 가시성 만 변경할 수 있습니다.

참고 :이 주석은 C에만 적용됩니다. C ++에서 클래스 메소드에 '정적'을 적용하면 키워드에 다른 의미가 부여됩니다. C99 배열 인수 확장의 경우와 유사합니다.


귀하의 (a)는 중복됩니다. 범위 밖에서 볼 수있는 변수는 없습니다. 그것은 단순히 범위의 정의입니다. C 표준 에서는 연계 라고 합니다. 식별자에 내부 연결static제공합니다 .
Jens

16

Wikipedia에서 :

C 프로그래밍 언어에서 static 은 전역 변수 및 함수와 함께 사용되어 해당 범위를 포함 파일로 설정합니다. 로컬 변수에서 static은 자동 할당 된 메모리 대신 정적 할당 된 메모리에 변수를 저장하는 데 사용됩니다. 언어가 두 가지 유형의 메모리 구현을 지시하지는 않지만 정적으로 할당 된 메모리는 일반적으로 컴파일 타임에 프로그램의 데이터 세그먼트에 예약되며 자동 할당 된 메모리는 일반적으로 임시 호출 스택으로 구현됩니다.


16

static 다른 맥락에서 다른 것을 의미합니다.

  1. C 함수에서 정적 변수를 선언 할 수 있습니다. 이 변수는 함수에서만 볼 수 있지만 한 번만 초기화되고 값을 유지한다는 점에서 전역처럼 동작합니다. 이 예에서는 전화 foo()할 때마다 번호가 증가합니다. 정적 변수는 한 번만 초기화됩니다.

    void foo ()
    {
    static int i = 0;
    printf("%d", i); i++
    }
  2. static의 또 다른 사용은 .c 파일에서 함수 또는 전역 변수를 구현하지만 파일에서 .obj생성 된 심볼 외부에서 심볼을 표시하지 않으려 는 경우입니다. 예 :

    static void foo() { ... }

8

정적 함수에서 변수를 선언하면 해당 값은 함수 호출 스택에 저장되지 않으며 함수를 다시 호출 할 때 계속 사용할 수 있습니다.

전역 변수 static을 선언하면 해당 범위는 선언 한 파일 내로 제한됩니다. 이것은 전체 프로그램에서 읽고 수정할 수있는 일반 전역보다 약간 안전합니다.


8

나는 오래된 질문에 대답하기는 싫지만 "C 프로그래밍 언어"의 A4.1 섹션에서 K & R이 어떻게 설명하는지 언급 한 사람은 없다고 생각합니다.

간단히 말해서 static이라는 단어는 두 가지 의미 로 사용됩니다 .

  1. 정적은 두 스토리지 클래스 중 하나입니다 (다른 하나는 자동). 정적 객체는 호출간에 값을 유지합니다. 모든 블록 외부에서 선언 된 객체는 항상 정적이며 자동으로 만들 수 없습니다.
  2. 그러나 static 키워드 (코드에서 키워드로 사용되는 키워드에 중점을 두는 키워드)를 선언과 함께 사용하면 해당 개체 내부 연결을 제공하므로 해당 번역 단위 내에서만 사용할 수 있습니다. 그러나 키워드가 함수에 사용되면 객체의 스토리지 클래스가 변경됩니다 (오브젝트는 해당 함수 내에서만 볼 수 있음). static과 반대되는 extern키워드는 객체에 외부 연결을 제공합니다.

Peter Van Der Linden은 "전문가 C 프로그래밍"에서 다음 두 가지 의미를 제공합니다.

  • 함수 내에서 호출간에 값을 유지합니다.
  • 기능 수준에서이 파일에서만 볼 수 있습니다.

세 번째 스토리지 클래스 인 register가 있습니다. 일부 사람들은 malloc과 친구들이 반환 한 스토리지에 대해 할당 된 네 번째 스토리지 클래스 를 제시합니다.
Jens

@Jens 'register'는 컴파일러에 대한 힌트 일뿐입니다. C 소스 내에서 레지스터 스토리지를 시행 할 수 없습니다. 그래서 나는 그것을 스토리지 클래스로 간주하지 않을 것입니다.
GermanNerd

1
이 명확하게 만들면서 내가보기로 ISO C 표준에 동의하지를 두려워 @GermanNerd 저장소 클래스 지정자 (C99 6.7.1 스토리지 클래스 지정자를). 또한 힌트 일뿐입니다. 예를 들어 컴파일러가 레지스터를 할당하는지 여부에 관계없이 스토리지 클래스가있는 객체에 주소 연산자 를 적용 할 수 없습니다. register&register
Jens

@에 대해 상기시켜 주셔서 감사합니다. 어쨌든 'register'는 스토리지 클래스 지정자이지만 실제로 컴파일러는 'register'와 동일한 (무용 한) 'auto'지정자에 대해 동일한 머신 코드를 생성합니다. '지정자. 따라서 남아있는 것은 주소를 가질 수 없다는 소스 코드 수준의 제한입니다. BTW,이 작은 토론으로 인해 Netbeans에서 버그가 발견되었습니다. 최신 업데이트 이후, 새로운 C 프로젝트에서 g ++ 툴 체인이 기본값입니다!
GermanNerd

6

C에서 static은 사용 범위에 따라 두 가지 의미를 갖습니다. 전역 범위에서 파일 수준에서 개체를 선언하면 해당 개체는 해당 파일 내에서만 볼 수 있습니다.

다른 범위에서는 특정 범위를 입력 한 다른 시간 사이에 값을 유지하는 객체를 선언합니다. 예를 들어, int가 프로 시저 내에서 분리되는 경우 :

void procedure(void)
{
   static int i = 0;

   i++;
}

프로 시저를 처음 호출 할 때 'i'값이 0으로 초기화되고, 프로 시저가 호출 될 때마다 값이 유지됩니다. 'i'가 인쇄되면 0, 1, 2, 3, ...의 시퀀스를 출력합니다.


5

함수의 정적 변수는 해당 함수의 첫 번째 항목에서 초기화되고 호출이 완료된 후에도 지속된다는 점에 유의해야합니다. 재귀 함수의 경우 정적 변수는 한 번만 초기화되고 모든 재귀 호출과 함수 호출이 끝난 후에도 지속됩니다.

변수가 함수 외부에서 작성된 경우 프로그래머가 변수가 선언 된 소스 파일의 변수 만 사용할 수 있음을 의미합니다.


5

이것을 mytest.c파일로 선언하면 :

static int my_variable;

그런 다음이 변수는이 파일에서만 볼 수 있습니다. 변수는 다른 곳으로 내보낼 수 없습니다.

함수 안에서 선언하면 변수의 값은 함수가 호출 될 때마다 값을 유지합니다.

정적 함수는 파일 외부에서 내보낼 수 없습니다. 따라서 *.c파일에서 함수와 변수를 정적으로 선언하면 함수와 변수를 숨 깁니다.


4

C의 정적 변수는 프로그램 수명이 있습니다.

함수에 정의 된 경우 로컬 범위를 가지므로 해당 함수 내에서만 액세스 할 수 있습니다. 정적 변수의 값은 함수 호출간에 유지됩니다.

예를 들면 다음과 같습니다.

void function()
{
    static int var = 1;
    var++;
    printf("%d", var);
}

int main()
{
    function(); // Call 1
    function(); // Call 2
}

위 프로그램에서 var 에서 데이터 세그먼트에 저장됩니다. 수명은 전체 C 프로그램입니다.

기능 호출 1 var후에 2 var가됩니다. 기능 호출 2 후에 3이됩니다.

의 가치 var함수 호출 사이 소멸되지 않습니다.

var정적이 아닌 변수와 로컬 변수 사이에 있으면 C 프로그램의 스택 세그먼트에 저장됩니다. 함수가 반환 된 후 함수의 스택 프레임이 소멸되므로var 도 소멸됩니다.

초기화 된 정적 변수는 C 프로그램의 데이터 세그먼트에 저장되고 초기화되지 않은 변수는 BSS 세그먼트에 저장됩니다.

정적에 대한 또 다른 정보 : 변수가 전역 및 정적 인 경우 C 프로그램의 수명은 있지만 파일 범위가 있습니다. 해당 파일에서만 볼 수 있습니다.

이것을 시도하려면 :

file1.c

static int x;

int main()
{
    printf("Accessing in same file%d", x):
}

file2.c

    extern int x;
    func()
    {
        printf("accessing in different file %d",x); // Not allowed, x has the file scope of file1.c
    }

run gcc -c file1.c

gcc -c file2.c

이제 다음을 사용하여 연결하십시오.

gcc -o output file1.o file2.o

x에 file1.c의 파일 범위가 있고 링커가 file2.c에 사용 된 변수 x에 대한 참조를 확인할 수 없으므로 링커 오류가 발생합니다.

참고 문헌 :

  1. http://en.wikipedia.org/wiki/Translation_unit_(programming)
  2. http://en.wikipedia.org/wiki/Call_stack

데이터가 영구적이라는 것을 이해합니다. 즉, 각 함수 호출 후에도 데이터가 손실되지 않지만 static int var = 1;매번 값을 다시 1로 변경 하지 않는 이유는 무엇입니까?
Eames

3

정적 변수는 함수에서 사용할 수있는 특수 변수이며 호출간에 데이터를 저장하며 호출간에 삭제하지 않습니다. 예를 들면 다음과 같습니다.

void func(){
    static int count; // If you don't declare its value, the value automatically initializes to zero
    printf("%d, ", count);
    ++count;
}

void main(){
    while(true){
        func();
    }
}

출력 :

0, 1, 2, 3, 4, 5, ...


printf("%d, ", count); count++;`printf ( "% d,", count ++)로 바꿀 수 있습니다 (중요하지는 않습니다 : P).
RastaJedi

2

정적 변수 값은 다른 함수 호출 사이에서 지속되며 범위는 정적 변수가 항상 값 0으로 초기화되는 로컬 블록으로 제한됩니다.


2

2 가지 경우가 있습니다 :

(1) 지역 변수 선언 static: 스택 대신 데이터 세그먼트에 할당됩니다. 함수를 다시 호출해도 값이 유지됩니다.

(2) 전역 변수 또는 선언 된 함수 static: 외부 컴파일 유닛 외부에 보이지 않습니다 (즉, 링크하는 동안 심볼 테이블에 로컬 심볼이 있음).


1

정적 변수는 범위를 벗어난 후에도 유지 하는 속성을 갖습니다 ! 따라서 정적 변수는 이전 범위에서 이전 값을 유지하고 새 범위에서 다시 초기화되지 않습니다.

예를 들어보십시오-정적 int 변수는 프로그램이 실행되는 동안 메모리에 남아 있습니다. 변수가 선언 된 함수 호출이 끝나면 일반 또는 자동 변수가 삭제됩니다.

#include<stdio.h> 
int fun() 
{ 
  static int count = 0; 
  count++; 
  return count; 
} 

int main() 
{ 
  printf("%d ", fun()); 
  printf("%d ", fun()); 
  return 0; 
}

출력됩니다 : 1 2

정적로 선언 된대로 1이 메모리에 머무르면서

전역 변수와 같은 정적 변수는 명시 적으로 초기화되지 않은 경우 0으로 초기화됩니다. 예를 들어 아래 프로그램에서 x 값은 0으로 인쇄되는 반면 y 값은 가비지입니다. 자세한 내용은 이것을 참조하십시오.

#include <stdio.h> 
int main() 
{ 
    static int x; 
    int y; 
    printf("%d \n %d", x, y); 
}

출력됩니다 : 0 [some_garbage_value]

이들은 내가 초보자를 위해 위에서 설명하지 않은 주요 것들입니다!


-1

C 프로그래밍에서 static 수명과 가시성을 모두 제어하는 ​​예약 키워드입니다. 함수 내에서 변수를 정적으로 선언하면 해당 함수 전체에서만 볼 수 있습니다. 이 사용법에서이 정적 변수의 수명은 함수 호출시 시작되며 해당 함수 실행 후 소멸됩니다. 다음 예제를 볼 수 있습니다.

#include<stdio.h> 
int counterFunction() 
{ 
  static int count = 0; 
  count++; 
  return count; 
} 

int main() 
{ 
  printf("First Counter Output = %d\n", counterFunction()); 
  printf("Second Counter Output = %d ", counterFunction()); 
  return 0; 
}

위의 프로그램은 우리에게 다음과 같은 결과를 줄 것입니다.

First Counter Output = 1 
Second Counter Output = 1 

함수를 호출하자마자을 초기화하기 때문 count = 0입니다. 그리고 우리가 counterFunction그것을 실행하는 동안 카운트 변수를 파괴합니다.


2
위의 프로그램은 다음과 같이 출력합니다 : 첫 번째 카운터 출력 = 1 두 번째 카운터 출력 = 1 <참이 아닙니다. 정적 변수는 한 번만 초기화됩니다. 따라서 출력은 1, 2 등이됩니다.
GermanNerd
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.