programing

C은 무엇인가"정적"기능을 합니까?

nicescript 2022. 8. 16. 22:08
반응형

C은 무엇인가"정적"기능을 합니까?

문제는 평범한 c기능 아니라 c++에 관한 것이었다. static법,, 의의는명명 명다다 졌졌

static입니다만, 변수란 입니까?static기??

하면 왜 '어느 정도'라고 거죠?void print_matrix 「 」라고 합시다a.c(내)a.h )와 ( )을 포함합니다."a.c". -알겠습니다"print_matrix@@....) already defined in a.obj" 이렇게 '아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 맞다.static void print_matrix★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★?

그저 사물을 분명하게 하-나는 이 같은 아UPDATE..c★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★을 비우기 거예요.main.c 모든 을 알 수 있을 ..h ★★★★★★★★★★★★★★★★★」.c임시적이고 빠른 해결책일 뿐이에요

static함수는 같은 파일(더 정확히는 같은 변환 단위) 내의 다른 함수에만 표시되는 함수입니다.

편집: 질문 작성자가 '클래스 메서드'를 의미한다고 생각하는 사용자: 질문에 태그가 부착되어 있습니다.CC로 하다(메서드의 경우 (C++/Java/...) " " "static이 메서드는 클래스 자체에서 호출할 수 있으며 해당 클래스의 인스턴스는 필요하지 않습니다.

C의 정적 함수와 C++의 정적 멤버 함수는 큰 차이가 있습니다.C에서 정적 함수는 변환 유닛(컴파일된 객체 파일) 외부에 표시되지 않습니다.즉, 함수를 스태틱하게 하면 그 범위가 제한됩니다.정적 함수는 *.c 파일에 대해 "개인"이라고 생각할 수 있습니다(단, 엄밀하게는 올바르지 않습니다).

C++에서는 "static"이 클래스의 멤버 함수 및 데이터 멤버에도 적용될 수 있습니다.정적 데이터 멤버는 "클래스 변수"라고도 하며, 비정적 데이터 멤버는 "인스턴스 변수"입니다.이것은 Smalltalk 용어입니다.즉, 클래스의 모든 객체가 공유하는 스태틱데이터 멤버의 복사본은 1개뿐이지만 각 객체에는 스태틱데이터 멤버의 복사본이 있습니다.따라서 정적 데이터 멤버는 기본적으로 글로벌 변수이며 클래스의 멤버입니다.

비정적 멤버 함수는 클래스의 모든 데이터 멤버(스태틱 및 비정적)에 액세스할 수 있습니다.정적 멤버 함수는 정적 데이터 멤버에서만 작동할 수 있습니다.

이를 생각할 수 있는 한 가지 방법은 C++에서는 정적 데이터 멤버와 정적 멤버 함수가 어떤 오브젝트에도 속하지 않고 클래스 전체에 속한다는 것입니다.

최소 실행 가능 다중 파일 범위 예제

에서는 어떻게 하는지 설명하겠습니다.static는 여러 파일에 걸친 함수 정의의 범위에 영향을 줍니다.

교류

#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
 */
/*void f() { puts("a f"); }*/

/* OK: only declared, not defined. Will use the one in main. */
void f(void);

/* OK: only visible to this file. */
static void sf() { puts("a sf"); }

void a() {
    f();
    sf();
}

메인

#include <stdio.h>

void a(void);        

void f() { puts("main f"); }

static void sf() { puts("main sf"); }

void m() {
    f();
    sf();
}

int main() {
    m();
    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
./main

출력:

main f
main sf
main f
a sf

해석

  • sf
  • 은 1은 1은 1은 1번입니다.f

항상 하십시오.static네가 할 수 있으면.

에서는 파일은 를 나타내기 되며, C는 "classes"를 나타냅니다.static함수는 클래스의 "개인" 메서드를 나타냅니다.

인 C 은 "C"를 통과시키는 것입니다.thisC++가 후드에서 하는 첫 번째 "방법" 인수로 구조화됩니다.

어떤 기준에 의해 규정되어 있는가?

C99 N1256 드래프트 6.7.1 "스토리지 클래스 지정자"에 따르면static는 "스토리지 클래스 지정자"입니다.

에는 6.2.2/3 "식별자 연결"이 있습니다.staticinternal linkage:

객체 또는 함수의 파일스코프 식별자 선언에 스토리지 클래스 지정자 static이 포함되어 있는 경우 식별자는 내부 링크를 가집니다.

.2는, 6.2.2/,internal linkage하다

전체 프로그램을 구성하는 변환 유닛과 라이브러리의 집합에서, 외부 링크를 가진 특정 식별자의 각 선언은 동일한 객체 또는 함수를 나타낸다.하나의 변환 유닛 내에서 내부 링크를 가진 식별자의 각 선언은 동일한 객체 또는 함수를 나타낸다.

여기서 "정보 유닛"은 전처리 후의 소스 파일입니다.

GCC는 어떻게 ELF(Linux)용으로 구현합니까?

STB_LOCAL바인드

컴파일 할 경우:

int f() { return 0; }
static int sf() { return 0; }

기호 테이블을 분해합니다.

readelf -s main.o

출력은 다음과 같습니다.

Num:    Value          Size Type    Bind   Vis      Ndx Name
  5: 000000000000000b    11 FUNC    LOCAL  DEFAULT    1 sf
  9: 0000000000000000    11 FUNC    GLOBAL DEFAULT    1 f

그래서 결합이 그들 사이에 유일하게 중요한 차이점입니다. Value단지 그 오프셋에 불과합니다..bss츠키다

STB_LOCAL에 대해서는, http://www.sco.com/developers/gabi/2003-12-17/ch4.symtab.html 에 있는 ELF 사양에 기재되어 있습니다.

STB_LOCAL 정의가 포함된 개체 파일 외부에는 로컬 기호가 표시되지 않습니다.같은 이름의 로컬 기호는 서로 간섭하지 않고 여러 파일에 존재할 수 있습니다.

하기 딱 입니다.static.

는 " " 입니다.STB_GLOBAL사양에는 다음과 같이 기재되어 있습니다.

링크 에디터는 재배치 가능한 여러 객체파일을 조합할 때 같은 이름의 STB_GLOBAL 기호를 여러 개 정의할 수 없습니다.

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

upization with with with withization로 최적화를 -O3 , . . . . . . . .sf기호는 기호 테이블에서 완전히 제거됩니다. 외부에서는 사용할 수 없습니다.TODO 최적화가 없을 때 정적 기능을 기호 테이블에 유지하는 이유는 무엇입니까?그것들은 어떤 용도로도 사용될 수 있나요?

「 」를 참조해 주세요.

C++ 익명 네임스페이스

C++ 에서는, 스태틱 대신에 익명 네임스페이스를 사용할 수 있습니다.이것에 의해, 같은 효과를 얻을 수 있습니다만, 타입 정의는 한층 더 숨겨집니다.이름 없음/익명 네임스페이스 대 정적 함수

C의 "static함수" 뭐죠?

처음부터 시작합시다.

이 모든 것은 "Linkage"라고 불리는 것을 기반으로 합니다.

다른 범위 또는 같은 범위내에서 복수의 식별자가 선언되면, 링크라고 불리는 프로세스에 의해서 같은 오브젝트 또는 함수를 참조하도록 할 수 있다.29)외부 링크, 내부 링크, 없음 링크의 3가지 종류가 있습니다.

출처: C18, 6.2.2/1


프로그램 전체를 구성하는 번역 유닛과 라이브러리의 집합에서 외부 링크를 가진 특정 식별자의 각 선언은 동일한 객체 또는 함수를 나타냅니다.하나의 변환 유닛 내에서 내부 링크를 가진 식별자의 각 선언은 동일한 객체 또는 함수를 나타낸다.링크가 없는 식별자의 각 선언은 고유한 실체를 나타냅니다."

출처: C18, 6.2.2/2


클래스 함수가 , 함수는 「」를 가집니다.extern알링크

함수의 식별자 선언에 스토리지 클래스 지정자가 없는 경우, 그 링크는 스토리지 클래스 지정자 exter에서 선언된 것처럼 정확하게 결정된다.

출처: C18, 6.2.2/5

, 이 여러 번역 파일 「」/「」)로 되어 있는 .c ★★★★★★★★★★★★★★★★★」.cpp) - 프로그램이 가지고 있는 모든 변환 유닛/소스 파일에 함수가 표시됩니다.

이것은 경우에 따라서는 문제가 될 수 있습니다.예를 들어, 두 개의 다른 함수(정의)를 사용하지만 두 개의 다른 컨텍스트(실제로 파일 컨텍스트)에서 동일한 함수 이름을 사용하려는 경우에는 어떻게 해야 합니까?

C 및 C++에서는static파일 범위의 함수에 적용되는 스토리지 클래스 한정자(C++ 클래스의 정적 멤버 함수나 다른 블록 내의 함수는 아님)는 도움이 되며, 각 함수는 다른 TLU/파일이 아닌 변환 유닛/소스 파일 내에서만 볼 수 있음을 나타냅니다.

객체 또는 함수의 파일 범위 식별자 선언에 스토리지 클래스 지정자 static이 포함되어 있는 경우 식별자는 내부 링크를 가집니다.30).


  1. 함수 선언은 파일 범위에 있는 경우에만 스토리지 클래스 지정자 static을 포함할 수 있습니다(6.7.1 참조).

출처: C18, 6.2.2/3


A a 、 A 、 A thusstatic함수는 다음과 같은 경우에만 의미가 있습니다.

  1. 은 여러 ('/'/'/'/'/'/')로 구성되어 있습니다..c ★★★★★★★★★★★★★★★★★」.cpp를 참조해 주세요.

그리고.

  1. 함수의 범위를 특정 함수가 정의되어 있는 파일로 제한하려고 합니다.

이 두 가지 요건이 모두 일치하지 않는 경우 기능 검증에 대해 지나치게 고민할 필요는 없습니다.static.


사이드 노트:

  • 말한 바와 같이 A는 A입니다.static이 기능은 C에서 상속된 C++ 기능이기 때문에 C와 C++ 사이에는 전혀 차이가 없습니다.

에서 C++로 의 감가상각에 것은 .staticC++03 표준의 잘못된 단락에 의해 처음 시작된 이름 없는 네임스페이스의 사용과 비교하여 정적 기능의 사용은 곧 위원회 자체에서 수정되어 C++11에서 삭제되었다.

여기에는 다양한 SO 질문이 적용되었습니다.

이름 없음/익명 네임스페이스 대 정적 함수

이름 없는 네임스페이스가 정적보다 우수합니까?

이름 없는 네임스페이스가 스태틱의 "우수한" 대안인 이유는 무엇입니까?

static 키워드 폐지...더 이상 없어요?

실제로 C++ 표준에서는 아직 권장되지 않습니다. 해서 따,의 ,static함수는 아직 유효합니다.이름 없는 네임스페이스에 장점이 있다고 해도 C++에서 정적 기능을 사용하는지 여부에 대한 논의는 한 사람의 생각(의견 기반)에 따라 다르며, 이 웹 사이트에는 적합하지 않습니다.

정적 기능은 이 파일에서만 볼 수 있기 때문입니다.실제로 컴파일러는 어떤 함수에 대해 "static"을 선언하면 최적화를 수행할 수 있습니다.

여기 간단한 예가 있습니다.

메인

#include <stdio.h>

static void test() 
{
    ghost(); // This is an unexist function.
}

int main()
{
    int ret = 0;

#ifdef TEST
#else
    test();
#endif
    return (ret);
} 

컴파일은 다음과 같습니다.

gcc -o main main.c

실패했음을 알 수 있습니다.ghost() 함수도 구현하지 않기 때문입니다.

하지만 다음 명령을 사용하면 어떨까요?

gcc -DTEST -O2 -o main main.c

성공하고, 이 프로그램은 정상적으로 실행될 수 있습니다.

왜요? 세 가지 포인트가 있어요.

  1. - O2 : 컴파일러 최적화 레벨 2 이상.
  2. - DTEST : test()가 호출되지 않도록 TEST를 정의합니다.
  3. 테스트()에 "static"이 정의되어 있습니다.

이 3가지 조건이 모두 충족되어야 컴파일을 통과할 수 있습니다.이 "static" 선언 때문에 컴파일러는 test()가 다른 파일에서는 호출되지 않음을 확인할 수 있습니다.컴파일러는 컴파일 시 test()를 삭제할 수 있습니다.test()가 필요 없기 때문에 ghost()가 정의되어 있는지 실장되어 있는지 여부는 중요하지 않습니다.

정적 함수 정의에서는 이 기호를 내부로 표시합니다.따라서 외부 링크에는 표시되지 않고 동일한 컴파일 유닛(일반적으로 동일한 파일) 내의 기능에만 표시됩니다.

다음은 플레인 C 함수에 대한 설명입니다. C++ 클래스에서 수식어 'static'은 다른 의미를 가집니다.

파일이 1개뿐인 경우 이 수식자는 전혀 차이가 없습니다.여러 개의 파일이 있는 대규모 프로젝트에서는 다음과 같은 차이가 있습니다.

C에서는 모든 "module"(sample.c와 sample.h의 조합)이 독립적으로 컴파일되고 그 후에 컴파일된 오브젝트 파일(sample.o)이 모두 링커에 의해 실행 파일에 링크됩니다.

를 들어 메인 에 여러 그 중 두 의 파일이 를 위해 합니다.add(int a, b)컴파일러는 이 두 모듈의 객체 파일을 쉽게 만들 수 있지만 링커는 오류를 발생시킵니다.왜냐하면 같은 이름의 함수를 2개 찾았고 어떤 함수를 사용해야 할지 모르기 때문입니다(링크할 것이 없더라도 다른 곳에서 사용되는 것이 아니라 자체 파일에서 사용되기 때문입니다).

그래서 내부에서만 사용되는 이 함수를 정적 함수로 만드는 것입니다.이 경우 컴파일러는 일반적인 링커용 플래그를 작성하지 않습니다.따라서 링커는 이 함수를 인식하지 않고 에러를 생성하지 않습니다.

정적 함수는 클래스의 인스턴스가 아니라 클래스 자체에 대해 호출할 수 있는 함수입니다.

예를 들어, 비정적인 경우는 다음과 같습니다.

Person* tom = new Person();
tom->setName("Tom");

이 메서드는 클래스 자체가 아닌 클래스의 인스턴스에서 작동합니다.그러나 인스턴스가 없어도 사용할 수 있는 정적 메서드를 사용할 수 있습니다.이것은 공장 출하시 패턴으로 사용되는 경우가 있습니다.

Person* tom = Person::createNewPerson();

첫 번째: 일반적으로는 다음 항목을 포함하는 것이 좋지 않습니다..cpp파일을 다른 파일에 저장하면 다음과 같은 문제가 발생합니다.일반적인 방법은 별도의 컴파일 유닛을 생성하여 포함된 파일의 헤더 파일을 추가하는 것입니다.

두 번째:

C++는 여기에 몇 가지 혼란스러운 용어가 있습니다.-댓글에 지적될 때까지 몰랐습니다.

a)static functions- C로부터 물려받은 것, 그리고 여기서 말하는 것.수업시간 외에요.정적 함수는 현재 컴파일 유닛 외부에서 볼 수 없음을 의미합니다.따라서 a.obj에는 복사본이 있고 다른 코드에는 독립적인 복사본이 있습니다. (코드의 여러 복사본으로 최종 실행 파일을 블러딩합니다.)

b) - 객체 방향이란 정적 방법을 말합니다.학급 내에서 산다.오브젝트 인스턴스가 아닌 클래스에서 호출합니다.

이 두 가지 다른 정적 함수 정의는 완전히 다릅니다.조심해. 여기 용이 있어.

마이너 니트: 정적 함수는 변환 유닛에 표시되며, 대부분의 경우 해당 함수가 정의되어 있는 파일입니다.일반적으로 발생하는 오류는 단일 정의 규칙 위반이라고 합니다.

표준에는 다음과 같이 기술되어 있습니다.

"모든 프로그램은 해당 프로그램에서 사용되는 모든 비인라인 함수 또는 객체에 대해 정확히 하나의 정의를 포함해야 합니다. 진단은 필요하지 않습니다."

이것이 정적 함수를 보는 C의 방법입니다.단, 이것은 C++에서는 권장되지 않습니다.

C++ 에서는, 멤버 함수의 스태틱을 선언할 수도 있습니다.이러한 기능들은 대부분 메타 기능입니다. 즉, 특정 객체의 동작/상태를 설명/수정하는 것이 아니라 클래스 전체에 작용합니다.또, 스태틱멤버 함수를 호출하기 위해서 오브젝트를 작성할 필요도 없습니다.또한 이는 이러한 함수 내에서만 스태틱멤버 변수에 액세스할 수 있음을 의미합니다.

Parrow의 예에 싱글톤 패턴을 추가해 보겠습니다.이것은 프로그램의 라이프 타임에 걸쳐 하나의 오브젝트를 취득/사용하기 위한 스태틱멤버 함수의 일종입니다.

정적 기능에 대한 답은 언어에 따라 달라집니다.

1) C와 같이 OOPS가 없는 언어에서는 함수가 정의된 파일 내에서만 액세스할 수 있음을 의미합니다.

2) OPS를 사용하는 C++와 같은 언어에서는 함수를 인스턴스를 만들지 않고 클래스에서 직접 호출할 수 있습니다.

언급URL : https://stackoverflow.com/questions/558122/what-is-a-static-function-in-c

반응형