상수(컴퓨터 프로그래밍)

Constant (computer programming)

컴퓨터 프로그래밍에서 상수는 정상 실행 중에 프로그램에 의해 변경되어서는 안 되는 이다. 즉,[a] 값이 일정하다."상수"와 "상수"라는 용어가 종종 상호 호환되게 사용되지만, 식별자와 관련될 때 상수는 "이름 지정"이라고 한다.이것은 변수와 대조됩니다.변수는 통상적인 실행 중에 변경할 수 있는 값을 가진 식별자입니다.즉, 값은 변수입니다.상수는 프로그래머와 컴파일러 모두에 도움이 됩니다.프로그래머에게는 자기 문서화 코드의 한 형태이며 정확성에 대한 추론을 허용하는 반면 컴파일러의 경우에는 항상성 가정이 위반되지 않았음을 확인하는 컴파일 시간과 런타임 체크를 허용하고 일부 컴파일러 최적화를 허용하거나 단순화합니다.

상수의 일반적인 개념에는 다양한 구체적인 깨달음이 있으며, 종종 간과되는 미묘한 차이도 있습니다.가장 중요한 것은 컴파일 시간(정적 값) 상수, 런타임(동적 값) 상수, 불변의 객체 및 상수 유형(정적 값)입니다.

컴파일 시간 상수의 일반적인 예에는 다음과 같은 수학 상수, 표준으로부터의 값(여기서는 최대 전송 단위), 또는 내부 설정 값(여기서는 행당 문자)이 있습니다.

컨스턴트 흘러가다 PI = 3.1415927;  // 최대 단일 플로트 정밀도 컨스턴트 서명되어 있지 않다 인트 MTU = 1500;  // 이더넷v2, RFC 894 컨스턴트 서명되어 있지 않다 인트  = 80; 

런타임 상수의 일반적인 예는 다음과 같이 함수에 대한 입력에 따라 계산된 값입니다.

무효 f(표준::스트링 s) {   컨스턴트 size_t l = s.길이();   // ... } 

사용하다

일부 프로그래밍 언어는 상수 기호와 변수 기호를 명확하게 구분합니다. 예를 들어, 상수에 대한 할당을 구문 오류로 간주하는 반면, 다른 언어에서는 구문적으로 동일한 것으로 간주되며(둘 다 단순한 식별자), 처리의 차이는 의미적이다(식별자에 대한 할당은 s).정확히는 유효하지만, 식별자가 상수일 경우 의미상 무효입니다).

상수 값은 한 번 정의되며 프로그램 전체에서 여러 번 참조할 수 있습니다.같은 값을 여러 번 지정하는 대신 상수를 사용하면 코드 유지보수를 단순화할 수 있습니다(반복하지 마십시오).또, 예를 들면, 값의 의미 있는 이름을 지정하는 것으로, 스스로 문서화할 수 있습니다.PI3.1415926이 아닌

리터럴 및 매크로와의 비교

다양한 프로그래밍 언어 간에 일관된 프로그램 실행 중에 변경되지 않는 데이터 값을 표현하는 방법은 여러 가지가 있습니다.가장 기본적인 방법 중 하나는 C, C++ 및 유사한 언어로 간단한 프로그램 코드에 리터럴 번호, 문자 또는 문자열을 쓰는 방법은 다음과 같습니다.

어셈블리 언어에서 문자 그대로의 숫자와 문자는 대부분의 마이크로프로세서에서 사용 가능한 "즉시 모드" 명령을 사용하여 수행됩니다."immediate"라는 이름은 메모리 [1]주소를 찾아 간접적으로 로드하는 이 아니라 명령 스트림에서 즉시 사용할 수 있는 값에서 유래합니다.한편, 문자열이나 어레이 등 마이크로프로세서의 워드 길이보다 긴 값은 간접적으로 처리되며, 어셈블러는 일반적으로 이러한 데이터 테이블을 프로그램에 포함시키기 위한 "데이터" 의사 연산을 제공한다.

또 다른 방법은 심볼 매크로를 정의하는 것입니다.많은 고급 프로그래밍 언어 및 많은 어셈블러는 프로그래머가 일반적으로 소스 파일의 시작 부분이나 별도의 정의 파일에서 서로 다른 값의 이름을 정의할 수 있는 매크로 기능을 제공합니다.그 후 프리프로세서는 컴파일 전에 이러한 이름을 적절한 값으로 대체하여 기능적으로 리터럴을 사용하는 것과 동일한 결과를 가져오고 즉시 모드의 속도 이점을 제공합니다.모든 값이 문자 그대로 기록되는 코드를 유지하는 것은 어려울 수 있기 때문에 값이 반복되거나 명확하지 않은 방식으로 사용되는 경우 매크로로 실행되는 경우가 많습니다.

세 번째 방법은 변수를 "정수"로 선언하고 정의하는 것입니다.글로벌 변수 또는 정적 변수는 다음과 같은 키워드 한정자를 사용하여 선언할 수 있습니다(또는 어셈블리에서 정의된 기호).const,constant, 또는final값은 컴파일 시 설정되며 실행 시 변경할 수 없습니다.컴파일러는 일반적으로 코드 자체와 함께 오브젝트 파일의 텍스트 섹션에 정적 상수를 넣습니다.데이터 섹션은 일정하지 않은 초기화 데이터가 보관됩니다.일부 컴파일러는 상수 전용 섹션을 생성할 수 있습니다.메모리 보호를 이 영역에 적용하여 잘못된 포인터에 의해 이러한 상수가 덮어쓰이지 않도록 할 수 있습니다.

이러한 상수는 여러 가지 면에서 리터럴과 다릅니다.컴파일러는 일반적으로 매크로와 같이 실행 파일 전체에 퍼지는 것이 아니라 기호로 식별되는 단일 메모리 위치에 상수를 배치합니다.이로 인해 즉시 모드의 속도상의 이점이 배제되지만 메모리 효율에는 이점이 있으며 디버거는 런타임에 이러한 상수를 사용할 수 있습니다.또한 C와 C++의 헤더파일이 충돌하여 매크로가 잘못 정의될 수 있지만 충돌하는 상수는 컴파일 시에 검출됩니다.

언어에 따라 상수를 입력 해제하거나 입력할 수 있습니다.C 및 C++에서는 매크로가 전자를 제공하지만,const는 후자를 제공합니다.

#정의 PI 3.1415926535  컨스턴트 흘러가다 pi2 = 3.1415926535; 

Ada에서는 원하는 경우 사용할 수 있는 범용 숫자 유형이 있습니다.

파이 : 일정한 := 3.1415926535;  pi2 : 일정한 흘러가다 := 3.1415926535; 

사용할 때마다 [2]암묵적으로 적절한 유형으로 변환됩니다.

동적 값 상수

위에서 설명한 정적 상수 외에도 Ada 및 C++와 같은 많은 절차적 언어는 일정성의 개념을 초기화 시 생성되는 글로벌 변수, 스택 또는 레지스터의 런타임에 자동으로 생성되는 로컬 변수, 포인터로 액세스되는 동적으로 할당된 메모리로 확장합니다.함수 헤더의 rarameter 목록.

동적으로 값이 매겨진 상수는 변수를 메모리의 특정 영역에 상주하도록 지정하지 않으며 컴파일 시 설정되는 값도 아닙니다.C++ 코드(예:

흘러가다 기능하다(컨스턴트 흘러가다 아무거나) {     컨스턴트 흘러가다 XYZ = some Global Variable(일부 글로벌 변수)*기타 기능(아무거나);     ... } 

상수가 초기화되는 표현 자체가 일정하지 않습니다.여기서 프로그램의 합법성이나 의미적 정확성을 위해 항상성을 사용할 필요는 없지만, 다음과 같은 세 가지 장점이 있습니다.

  1. 한 번 설정하면 오브젝트가 더 이상 수정되지 않는다는 것을 독자는 분명히 알 수 있습니다.
  2. 오브젝트 값을 변경하려는 시도(프로그램 로직을 완전히 이해하지 못한 나중의 프로그래머에 의해)는 컴파일러에 의해 거부됩니다.
  3. 컴파일러는 오브젝트의 값이 일단 [3]생성되면 변경되지 않는다는 것을 알고 코드 최적화를 실행할 수 있습니다.

동적으로 값이 매겨진 [3]상수는 ALGOL 68에서 언어 기능으로 생성되었습니다.Ada 및 C++ 코드에 대한 연구는 동적으로 값이 매겨진 상수는 일반적으로 1% 이하의 객체에 대해 드물게 사용되는데, 이는 로컬 비클래스 객체의 40~50%가 실제로 생성되면 [3][4]불변하기 때문이다.반면 이러한 "불변의 변수"는 부작용이 없는 프로그래밍 스타일(예: 재귀)을 선호하거나 ML과 같이 기본적으로 불변의 선언을 하기 때문에 함수 언어에서는 기본값이 되는 경향이 있습니다. 순수 함수 언어에서는 부작용까지 모두 금지합니다.

오브젝트가 참조에 의해 전달되었을 때 호출된 함수가 오브젝트를 변경하지 않는다는 약속으로 상수성은 함수 선언에서 자주 사용됩니다.구문에 따라 포인터 또는 오브젝트가 일정할 수 있지만 일반적으로 포인터는 일정합니다.특히 C++와 C에서는 프로그램 전체에서 적절한 데이터 구조가 일정하게 유지되도록 하는 것을 const-correctness라고 합니다.

상수 함수 매개 변수

C/C++에서는 함수 또는 메서드의 파라미터를 일정하게 선언할 수 있습니다.이는 첫 번째 할당 후(비상용적으로) 이 파라미터를 변경할 수 없음을 보증합니다.매개 변수가 미리 정의된(내장) 유형인 경우 값으로 호출되므로 수정할 수 없습니다.사용자 정의 유형인 경우 변수는 포인터 주소이며 이 주소도 수정할 수 없습니다.그러나 개체의 내용은 제한 없이 수정할 수 있습니다.파라미터를 상수로 선언하는 것은 이 이 변경되어서는 안 된다는 신호를 보내는 방법일 수 있지만, 프로그래머는 오브젝트 수정에 대한 체크가 컴파일러에 의해 수행될 수 없다는 것을 명심해야 합니다.

이 기능 외에 C++에서는 함수 또는 메서드를 다음과 같이 선언할 수도 있습니다.const따라서 이러한 함수 또는 메서드가 로컬 변수 이외의 다른 변수를 수정하지 않습니다.

C#에서 키워드는const는 존재하지만 C/C++의 경우와 같이 함수 파라미터에 동일한 영향을 미치지 않습니다.다만,[5] 컴파일러가 검사를 실시하도록 「스튜어」하는 방법이 있습니다.단, 조금 까다롭습니다.

같은 효과를 얻기 위해 먼저 2개의 인터페이스를 정의합니다.

일반의 인터페이스 읽기 어렵다 {     IValue 인터페이스 a값 { 얻다; } }  일반의 인터페이스 할 수 없다 : 읽기 어렵다 {     IValue 인터페이스 a값 { 세트; } }  일반의 학급 오브젝트 : 할 수 없다 {     사적인 구체적인 가치 _a값;      일반의 IValue 인터페이스 a값     {         얻다 { 돌아가다 _a값; }         세트 { _a값 = 가치 ~하듯이 구체적인 가치; }     } } 

그런 다음 정의된 메서드가 읽기 전용 또는 읽기/쓰기 기능을 가진 올바른 인터페이스를 선택합니다.

일반의 무효 어떻게 좀 해봐.(읽기 어렵다 a변수) {     // aVariable을 수정할 수 없습니다! }  일반의 무효 다른 것을 해라.(할 수 없다 a변수) {     // aVariable을 수정할 수 있으므로 주의하십시오! } 

객체 지향 상수

일정한 데이터 구조 또는 개체를 객체 지향 용어로 "불변"이라고 합니다.불변의 객체는 프로그램 설계에 몇 가지 장점을 부여합니다.예를 들어, 포인터나 참조를 복사하는 것만으로 「복사」할 수 있기 때문에, 시간이 걸리는 카피 조작을 회피해, 메모리를 절약할 수 있습니다.

C++와 같은 객체 지향 언어는 일관성을 더욱 확장합니다.구조체 또는 클래스의 개별 구성원은 클래스가 일정하지 않더라도 일정하게 할 수 있습니다.반대로,mutable키워드를 사용하면 오브젝트가 인스턴스화된 경우에도 클래스 멤버를 변경할 수 있습니다.const.

함수도 C++로 설정할 수 있습니다.여기서의 의미는 const 함수는 const로 인스턴스화된 객체에 대해서만 호출할 수 있다는 것입니다. const 함수는 비변환 데이터를 변경하지 않습니다.

C#에는 양쪽이 있습니다.const및 areadonly한정자. 이 const는 컴파일 시간 상수 전용이며, read only는 컨스트럭터 및 기타 런타임 응용 프로그램에서 사용할 수 있습니다.

자바

Java에는 다음과 같은 수식자가 있습니다.final참조 변경을 방지하고 참조가 다른 개체를 가리키지 않도록 합니다.이렇게 해도 참조된 개체 자체에 대한 변경은 방지되지 않습니다.자바어final기본적으로는 와 동등합니다.const C++의 포인터.다른 기능은 제공하지 않습니다.const.

자바에서는 수식자final는 다음과 같이 영향을 받는 데이터 멤버 또는 변수를 할당할 수 없음을 나타냅니다.

최종 인트 i = 3; i = 4; // 오류!"최종" 개체를 수정할 수 없습니다. 

컴파일러에 의해 결정될 필요가 있습니다.final마커가 초기화되어 한 번만 수행되어야 합니다. 그렇지 않으면 클래스가 컴파일되지 않습니다.자바어final및 C++의const키워드는 원시 변수를 적용했을 때 동일한 의미를 가집니다.

컨스턴트 인트 i = 3; // C++ 선언 i = 4; // 오류! 

포인터를 생각하면finalJava에서 참조란 다음과 같은 것을 의미합니다.constC++의 포인터.C++ 에서는, 「정수 포인터 타입」을 선언할 수 있습니다.

푸우 *컨스턴트 막대기 = mem_location; // const 포인터 유형 

여기서,bar는 선언 시 초기화해야 하며 다시 변경할 수 없지만 포인트는 수정할 수 있습니다.예.*bar = value유효합니다.다른 곳을 가리킬 수가 없어요Java의 최종 참조는 초기화되지 않은 것으로 선언될 수 있다는 점을 제외하고 동일한 방식으로 작동합니다.

최종 푸우 i; // Java 선언 

참고: Java는 [6]포인터를 지원하지 않습니다.이는 (제한이 있는) 포인터가 Java에서 오브젝트에 액세스하는 기본 방법이고 Java는 오브젝트를 나타내기 위해 별을 사용하지 않기 때문입니다.예를들면,마지막 예의 i는 포인터이며 인스턴스에 액세스하는 데 사용할 수 있습니다.

또, C++ 로 「읽기 전용」데이터에의 포인터를 선언할 수도 있습니다.

컨스턴트 푸우 *막대기; 

여기서bar언제든지 어떤 포인트로든 변경할 수 있습니다.단, 그 포인트의 값은 변경할 수 없습니다. bar포인터

Java에는 동등한 메커니즘이 없습니다.그러므로 또한 없다.const방법들.Java에서는 const-correctness를 강제할 수 없습니다.단, 인터페이스를 사용하여 클래스에 읽기 전용 인터페이스를 정의하고 이를 전달함으로써 오브젝트를 변경할 수 없는 방법으로 시스템에 전달할 수 있습니다.

Java 컬렉션 프레임워크는 의 불변의 래퍼를 작성하는 방법을 제공합니다.Collection경유로Collections.unmodifiableCollection()및 유사한 방법을 사용합니다.

Java의 메서드는 "final"로 선언할 수 있으며, 이는 하위 클래스에서 재정의할 수 없음을 의미합니다.

C#

C#에서는 수식자readonly데이터 멤버에게 미치는 영향은 다음과 같습니다.final자바 및constC++로 한다; 수식자const(아직 유형화되어 클래스 스코프와 같은) 효과가 있다.#defineC++로 표시됩니다.다른 하나는 Java의 상속 금지 효과입니다.final메서드 및 클래스에 적용되는 경우 키워드를 사용하여 C#으로 유도됩니다.sealed.

C++와 달리 C#에서는 메서드 및 파라미터의 마킹이 허용되지 않습니다.const단, 읽기 전용 서브클래스와 를 전달할 수도 있습니다.NET Framework는 가변 컬렉션을 읽기 전용 래퍼로 전달할 수 있는 불변의 컬렉션으로 변환하기 위한 몇 가지 지원을 제공합니다.

패러다임별

상수의 처리는 프로그래밍 패러다임에 따라 크게 다릅니다.const-correctness는 C++와 같은 필수 언어에서 문제가 됩니다.기본적으로 이름 바인딩은 변수들을 생성하기 때문에 이름에서 알 수 있듯이 변수를 생성할 수 있으며, 따라서 바인딩을 상수로 마크하려면 [b]추가 표시가 필요합니다.다른 프로그래밍 언어 패러다임에서는 관련 문제가 발생하며, 상수 정확성에 대한 일부 유사점이 발견됩니다.

기능 프로그래밍에서는 데이터가 기본적으로 변수가 아니라 기본적으로 일정합니다.변수(이름과 잠재적으로 가변적인 값을 가진 스토리지 공간)에 값을 할당하는 대신 다음과 같이 이름에 대한 바인딩을 만듭니다.let리스프의 많은 방언으로 구성하다.일부 기능 언어, 특히 공통 리스프와 같은 다중 문자 변환 언어에서는 데이터를 수정하는 것이 일반적이지만, 다른 기능 언어에서는 데이터를 수정하는 것이 회피되거나 예외적인 것으로 간주됩니다; 이것은 스킴(다른 리스프 방언)의 경우입니다.set!!!!!!!!를 사용하여 데이터를 수정하도록 설정합니다.이러한 언어는 기본적으로 항상성-정확성 목표를 달성하여 일관성이 아닌 수정에 관심을 끈다.

많은 객체 지향 언어에는 특히 문자열과 같은 기본 유형에 사용되는 불변의 객체의 개념이 있습니다. 주목할 만한 예로는 Java, JavaScript, Python 및 C#이 있습니다.이러한 언어는 사용자 정의 유형을 불변으로 표시할 수 있는지 여부에 따라 다르며 개체 또는 유형의 특정 필드(속성)를 불변으로 표시할 수 있습니다.

객체 지향 및 기능 스타일을 모두 허용하는 일부 다중 문자 언어에서는 이러한 두 가지 특징이 결합될 수 있습니다.예를 들어 OCaml 객체필드는 기본적으로는 불변이며 키워드로 명시적으로 마킹해야 합니다.mutablescala에서 바인딩은 명시적으로 불변합니다.val"값"에 대한 정의와 함께 명시적으로 변경 가능var"displicate"를 선택합니다.

명명 규칙

상수에 대한 명명 규칙은 다양합니다.다른 변수와 마찬가지로 이름을 붙이는 사람도 있습니다.다른 사람들은 다음과 같은 기호 매크로에 대한 전통적인 사용법과 유사한 방식으로 상수에 대문자 및 밑줄을 사용합니다.SOME_CONSTANT헝가리 표기법에서 "k" 접두사는 상수, 매크로열거된 유형을 나타냅니다.[7]

강제된 규칙 중 하나는 Ruby에서 대문자로 시작하는 모든 변수는 클래스 이름을 포함하여 상수로 간주됩니다.

「 」를 참조해 주세요.

메모들

  1. ^ 예를 들어 자기 수정 코드를 사용하거나 값이 저장되는 메모리 위치를 덮어쓰면서 항상성의 예상을 회피할 수 있다.
  2. ^ 예를 들어 Ada의 입력 파라미터와 루프 파라미터는 암묵적으로 일정하지 않습니다.

레퍼런스

  1. ^ 예: IBM 시스템 정보.명령 집합 - PowerPC용 어셈블리 언어 참조.
  2. ^ Booch, Grady (1983). Software Engineering with Ada. Benjamin Cummings. pp. 116–117. ISBN 0-8053-0600-5.
  3. ^ a b c Schilling, Jonathan L. (April 1995). "Dynamically-Valued Constants: An Underused Language Feature". SIGPLAN Notices. 30 (4): 13–20. doi:10.1145/202176.202177.
  4. ^ Perkins, J. A. Programming Practices: Analysis of Ada Source Developed for the Air Force, Army, and Navy. Proceedings TRI-Ada '89. pp. 342–354. doi:10.1145/74261.74287.
  5. ^ Timwi (2010-09-09). "Read-only ("const"-like) function parameters of C#". Stack Overflow. Retrieved 2012-05-06. [...] Then you can declare methods whose parameter type “tells” whether it plans on changing the variable or not:. [...] This mimics compile-time checks similar to constness in C++. As Eric Lippert correctly pointed out, this is not the same as immutability. But as a C++ programmer I think you know that.
  6. ^ "Oracle Technology Network for Java Developers Oracle Technology Network Oracle". Java.sun.com. 2013-08-14. Retrieved 2013-08-18.
  7. ^ Microsoft Office XP 개발자:상수 이름