your programing

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

lovepro 2020. 9. 27. 13:35
반응형

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


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


  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은 자동으로 할당 된 메모리 대신 정적으로 할당 된 메모리에 변수를 저장하는 데 사용됩니다. 언어가 두 유형의 메모리 구현을 지시하지는 않지만 정적으로 할당 된 메모리는 일반적으로 컴파일 타임에 프로그램의 데이터 세그먼트에 예약되는 반면 자동 할당 된 메모리는 일반적으로 일시적 호출 스택으로 구현됩니다.

자세한 내용은 여기여기 를 참조하세요.

두 번째 질문에 대한 답은 C #과 다릅니다.

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


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

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

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


짧은 대답 ... 상황에 따라 다릅니다.

  1. 정적 정의 지역 변수는 함수 호출 사이에 값을 잃지 않습니다. 즉, 전역 변수이지만 정의 된 지역 함수로 범위가 지정됩니다.

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

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


다중 파일 변수 범위 예

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

ac

#include <stdio.h>

/*
Undefined behavior: already defined in main.
Binutils 2.24 gives an error and refuses to link.
https://stackoverflow.com/questions/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.

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

그리고 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_LOCALELF 사양은 http://www.sco.com/developers/gabi/2003-12-17/ch4.symtab.html 에 문서화되어 있습니다 .

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

을 대표하는 완벽한 선택 static입니다.

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

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

여러 비 정적 정의의 링크 오류와 일관됩니다.

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

또한보십시오

C ++ 익명 네임 스페이스

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


때에 따라 다르지:

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

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

ac :

static int foo()
{
}

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

대부분의 C 라이브러리에서 모든 "개인"함수는 정적이고 대부분의 "공용"함수는 그렇지 않습니다.


사람들은 C의 '정적'에는 두 가지 의미가 있다고 계속 말합니다. 단일 의미를 부여하는 다른 방법을 제공합니다.

  • 항목에 '정적'을 적용하면 해당 항목이 두 가지 속성을 갖게됩니다. (a) 현재 범위 밖에서는 보이지 않습니다. (b) 지속적입니다.

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

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

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

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


Wikipedia에서 :

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


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

  1. You can declare a static variable in a C function. This variable is only visible in the function however it behaves like a global in that it is only initialized once and it retains its value. In this example, everytime you call foo() it will print an increasing number. The static variable is initialized only once.

    void foo ()
    {
    static int i = 0;
    printf("%d", i); i++
    }
    
  2. Another use of static is when you implement a function or global variable in a .c file but don't want its symbol to be visible outside of the .obj generated by the file. e.g.

    static void foo() { ... }
    

If you declare a variable in a function static, its value will not be stored on the function call stack and will still be available when you call the function again.

If you declare a global variable static, its scope will be restricted to within the file in which you declared it. This is slightly safer than a regular global which can be read and modified throughout your entire program.


I hate to answer an old question, but I don't think anybody has mentioned how K&R explain it in section A4.1 of "The C Programming Language".

In short, the word static is used with two meanings:

  1. Static is one of the two storage classes (the other being automatic). A static object keeps its value between invocations. The objects declared outside all blocks are always static and cannot be made automatic.
  2. But, when the static keyword (big emphasis on it being used in code as a keyword) is used with a declaration, it gives that object internal linkage so it can only be used within that translation unit. But if the keyword is used in a function, it changes the storage class of the object (the object would only be visible within that function anyway). The opposite of static is the extern keyword, which gives an object external linkage.

Peter Van Der Linden gives these two meanings in "Expert C Programming":

  • Inside a function, retains its value between calls.
  • At the function level, visible only in this file.

In C, static has two meanings, depending on scope of its use. In the global scope, when an object is declared at the file level, it means that that object is only visible within that file.

At any other scope it declares an object that will retain its value between the different times that the particular scope is entered. For example, if an int is delcared within a procedure:

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

   i++;
}

the value of 'i' is initialized to zero on the first call to the procedure, and the value is retained each subsequent time the procedure is called. if 'i' were printed it would output a sequence of 0, 1, 2, 3, ...


It is important to note that static variables in functions get initialized at the first entry into that function and persist even after their call has been finished; in case of recursive functions the static variable gets initialized only once and persists as well over all recursive calls and even after the call of the function has been finished.

If the variable has been created outside a function, it means that the programmer is only able to use the variable in the source-file the variable has been declared.


If you declare this in a mytest.c file:

static int my_variable;

Then this variable can only be seen from this file. The variable cannot be exported anywhere else.

If you declare inside a function the value of the variable will keep its value each time the function is called.

A static function cannot be exported from outside the file. So in a *.c file, you are hiding the functions and the variables if you declare them static.


Static variables in C have the lifetime of the program.

If defined in a function, they have local scope, i.e. they can be accessed only inside those functions. The value of static variables is preserved between function calls.

For example:

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

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

In the above program, var is stored in the data segment. Its lifetime is the whole C program.

After function call 1, var becomes 2. After function call 2, var becomes 3.

The value of var is not destroyed between functions calls.

If var had between non static and local variable, it would be stored in the stack segment in the C program. Since the stack frame of the function is destroyed after the function returns, the value of var is also destroyed.

Initialized static variables are stored in the data segment of the C program whereas uninitialized ones are stored in the BSS segment.

Another information about static: If a variable is global and static, it has the life time of the C program, but it has file scope. It is visible only in that file.

To try this:

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

Now try to link them using:

gcc -o output file1.o file2.o

It would give a linker error as x has the file scope of file1.c and the linker would not be able to resolve the reference to variable x used in file2.c.

References:

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

A static variable is a special variable that you can use in a function, and it saves the data between calls, and it does not delete it between calls. For example:

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();
    }
}

The output:

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


A static variable value persists between different function calls andits scope is limited to the local block a static var always initializes with value 0


There are 2 cases:

(1) Local variables declared static: Allocated in data segment instead of stack. Its value retains when you call the function again.

(2) Global variables or functions declared static: Invisible outside compilation unit (i.e. are local symbols in symbol table during linking).


In C programming, static is a reserved keyword which controlling both lifetime as well as visibility. If we declare a variable as static inside a function then it will only visible throughout that function. In this usage, this static variable's lifetime will start when a function call and it will destroy after the execution of that function. you can see the following example:

#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; 
}

Above program will give us this Output:
First Counter Output = 1
Second Counter Output = 1
Because as soon as we call the function it will initialize the count = 0. And while we execute the counterFunction it will destroy the count variable.

참고URL : https://stackoverflow.com/questions/572547/what-does-static-mean-in-c

반응형