English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
C ++의 각 변수는 두 가지 특성을 가집니다: 타입과 스토리지 클래스.
타입 지정은 변수에 저장할 수 있는 데이터 타입을 지정합니다. 예를 들어: int, float, char 등.
또한, 스토리지 클래스는 변수의 두 가지 다른 속성을 제어합니다: 생명주기(변수가 얼마나 오래 존재할 수 있는지 결정)와 범위(프로그램의 어떤 부분이 접근할 수 있는지 결정).
스토리지 클래스 정의 C++ 프로그램에서 변수/함수의 범위(可见性)와 생명주기. 이 설명자는 그가 수정하는 타입 앞에 배치됩니다. 다음은 C++ 프로그램에서 사용할 수 있는 스토리지 클래스:
auto
register
static
extern
mutable
thread_local (C++11)
C에서++ 17 시작, auto 키워드는 더 이상 C가 아니라++ 저장 클래스 식별자이며, register 키워드는 더 이상 사용되지 않습니다.
C++ 11 이후로auto 키워드은 두 가지 경우에 사용됩니다: 초기화 표현식을 통해 변수의 타입을 자동으로 추론하는 변수 선언, 함수 선언에서 함수 반환 값을 대신하는 占位符.
C++98C 표준에서 auto 키워드는 자동 변수의 선언에 사용되지만, 사용이 드물고 불필요하여 C++11에서 이 사용법이 제거되었습니다.
초기화 표현식을 통해 선언된 변수의 타입을 자동으로 추론합니다. 예를 들어:
auto f=3.14; //double auto s("hello"); //const char* auto z = new auto(9); // int* auto x1 = 5, x2 = 5.0, x3='r';//오류, 동일한 타입으로 초기화되어야 합니다
register 저장 클래스는 레지스터에 저장되지 않고 RAM에 저장된 로컬 변수를 정의하는 데 사용됩니다. 이는 변수의 최대 크기가 레지스터 크기(일반적으로 단어)와 같으며, 이 변수에 대해 원시 '&' 연산자를 적용할 수 없다는 것을 의미합니다(기억 위치가 없기 때문입니다).
{ register int miles; }
레지스터는 빠르게 접근할 필요가 있는 변수(예: 카운터)에만 사용됩니다. 또한 'register'를 정의하는 것은 변수가 레지스터에 저장될 것이라는 의미가 아니라, 하드웨어와 구현 제한에 따라 레지스터에 저장될 수 있다는 의미입니다.
static 저장 클래스는 컴파일러가 프로그램의 라이프 사이클 동안 로컬 변수의 존재를 유지하도록 지시합니다. 그래서 각 번호에 따라 함수를 호출할 때마다 생성하고 소멸하지 않도록 할 수 있습니다. 따라서 static 접지자를 로컬 변수에 사용하면 함수 호출 사이에 로컬 변수의 값을 유지할 수 있습니다.
static 접지자는 글로벌 변수에도 적용될 수 있습니다. static 접지자를 글로벌 변수에 사용할 때, 변수의 범위는 그를 선언한 파일 내로 제한됩니다.
C++ 중에서 static 을 클래스 데이터 멤버에 사용할 때, 모든 객체가 공유하는 동일한 멤버 복사본이 생성됩니다.
#include <iostream> // 함수 선언 void func(void); static int count = 25; /* 글로벌 변수 */ int main() { while(count--) { func(); } return 0; } // 함수 정의 void func(void) { static int i = 8; // 로컬 스태틱 변수 i++; std::cout << "변수 i 는 " << i; std::cout << " , 변수 count 는 " << count << std::endl; }
위의 코드가 컴파일 및 실행되면 다음과 같은 결과가 생성됩니다:
, 변수 i는 9 , 변수 count는 24 , 변수 i는 10 , 변수 count는 23 , 변수 i는 11 , 변수 count는 22 , 변수 i는 12 , 변수 count는 21 , 변수 i는 13 , 변수 count는 20 , 변수 i는 14 , 변수 count는 19 , 변수 i는 15 , 변수 count는 18 , 변수 i는 16 , 변수 count는 17 , 변수 i는 17 , 변수 count는 16 , 변수 i는 18 , 변수 count는 15 , 변수 i는 19 , 변수 count는 14 , 변수 i는 20, 변수 count는 13 , 변수 i는 21 , 변수 count는 12 , 변수 i는 22 , 변수 count는 11 , 변수 i는 23 , 변수 count는 10 , 변수 i는 24 , 변수 count는 9 , 변수 i는 25 , 변수 count는 8 , 변수 i는 26 , 변수 count는 7 , 변수 i는 27 , 변수 count는 6 , 변수 i는 28 , 변수 count는 5 , 변수 i는 29 , 변수 count는 4 , 변수 i는 30, 변수 count는 3 , 변수 i는 31 , 변수 count는 2 , 변수 i는 32 , 변수 count는 1 , 변수 i는 33 , 변수 count는 0입니다
extern 스토리지 클래스는 전역 변수의 참조를 제공하며, 전역 변수는 모든 프로그램 파일에 대해可见합니다. 'extern'을 사용할 때, 초기화할 수 없는 변수에 대해, 변수 이름은 이전에 정의된 저장 위치를 가리키게 됩니다.
여러 파일이 있고, 다른 파일에서 사용할 수 있는 전역 변수나 함수를 정의했을 때, 다른 파일에서 사용할 수 있습니다. extern 는 이미 정의된 변수나 함수의 참조를 얻기 위해 사용됩니다. 이를 이해하기 위해 다음과 같이 생각할 수 있습니다.extern 은 다른 파일에서 전역 변수나 함수를 선언하는 데 사용됩니다.
extern 지시자는 두 개 이상의 파일이 동일한 전역 변수나 함수를 공유할 때 일반적으로 사용됩니다. 다음과 같이 사용됩니다:
첫 번째 파일: main.cpp
#include <iostream> int count ; extern void write_extern(); int main() { count = 5; write_extern(); }
두 번째 파일: support.cpp
#include <iostream> extern int count; void write_extern(void) { std::cout << "Count is " << count << std::endl; }
여기서, 두 번째 파일에서 extern 키워드는 첫 번째 파일 main.cpp에서 정의된 count를 선언하는 데 사용됩니다. 지금, 두 파일을 다음과 같이 컴파일합니다:
$ g++ main.cpp support.cpp -o write
이는 생성합니다 write 실행 파일을 시도하여 실행 write이는 다음과 같은 결과를 생성합니다:
$ ./write Count is 5
mutable 지시자는 클래스의 객체에만 적용됩니다. 이는 이 튜토리얼의 마지막에서 설명할 것입니다. 이는 객체의 멤버가 상수 대신 사용되도록 허용합니다. 즉, mutable 멤버는 const 멤버 함수를 통해 수정될 수 있습니다.
thread_local 지시자로 선언된 변수는 그것이 생성된 스레드에서만 접근할 수 있습니다. 변수는 스레드 생성 시 생성되고, 스레드가 소멸될 때 소멸됩니다. 각 스레드는 자신의 변수 복사본을 가집니다.
thread_local 지시자는 static 또는 extern 을 병합할 수 있습니다.
thread_local 을 데이터 선언 및 정의에만 적용할 수 있습니다. thread_local 은 함수 선언 또는 정의에 사용할 수 없습니다.
thread_local로 선언될 수 있는 변수의 예제를 보여줍니다:
thread_local int x; // 네임스페이스의 전역 변수 class X { static thread_local std::string s; // 클래스의 static 멤버 변수 }; static thread_local std::string X::s; // X::s는 정의되어야 합니다 void foo() { thread_local std::vector<int> v; // 로컬 변수 }