치다:
int testfunc1 (const int a)
{
return a;
}
int testfunc2 (int const a)
{
return a;
}
이 두 기능은 모든 측면에서 동일합니까 아니면 차이점이 있습니까?
C 언어에 대한 답변에 관심이 있지만 C ++ 언어에 흥미로운 점이 있다면 저도 알고 싶습니다.
치다:
int testfunc1 (const int a)
{
return a;
}
int testfunc2 (int const a)
{
return a;
}
이 두 기능은 모든 측면에서 동일합니까 아니면 차이점이 있습니까?
C 언어에 대한 답변에 관심이 있지만 C ++ 언어에 흥미로운 점이 있다면 저도 알고 싶습니다.
답변:
const T
과 T const
동일하다. 포인터 유형을 사용하면 더 복잡해집니다.
const char*
상수에 대한 포인터 char
char const*
상수에 대한 포인터 char
char* const
(변경 가능)에 대한 상수 포인터입니다. char
즉, (1)과 (2)는 동일합니다. 포인터를 만드는 유일한 방법은 (pointee가 아닌) 접미사 const
를 사용하는 것 const
입니다.
이것이 많은 사람들이 항상 const
유형의 오른쪽에 배치하는 것을 선호하는 이유입니다 ( "East const"스타일). 유형에 상대적인 위치를 일관되고 기억하기 쉽게 만듭니다 (일화 적으로도 초보자에게 가르치기 쉽게 만드는 것 같습니다. ).
트릭은 선언을 거꾸로 읽는 것입니다 (오른쪽에서 왼쪽으로) :
const int a = 1; // read as "a is an integer which is constant"
int const a = 1; // read as "a is a constant integer"
둘 다 같은 것입니다. 따라서:
a = 2; // Can't do because a is constant
역방향 읽기 트릭은 다음과 같은 더 복잡한 선언을 다룰 때 특히 유용합니다.
const char *s; // read as "s is a pointer to a char that is constant"
char c;
char *const t = &c; // read as "t is a constant pointer to a char"
*s = 'A'; // Can't do because the char is constant
s++; // Can do because the pointer isn't constant
*t = 'A'; // Can do because the char isn't constant
t++; // Can't do because the pointer is constant
char const *
, 왼쪽에서 오른쪽으로 읽는 것은 "pointer, const, char"입니다. const char에 대한 포인터입니다. "상수 포인터"라고 말하면 "상수"형용사가 포인터 위에 있습니다. 따라서이 경우 형용사 목록은 실제로 "const, pointer, char"이어야합니다. 하지만 당신 말이 맞습니다.이 트릭에는 모호성이 있습니다. 그것은 결정적인 "규칙"이 아닌 "속임수"입니다.
다른 점이 없다. 둘 다 "a"를 변경할 수없는 정수로 선언합니다.
차이점이 나타나기 시작하는 곳은 포인터를 사용할 때입니다.
둘 다 :
const int *a
int const *a
"a"를 변경되지 않는 정수에 대한 포인터로 선언하십시오. "a"는 할당 할 수 있지만 "* a"는 할당 할 수 없습니다.
int * const a
"a"를 정수에 대한 상수 포인터로 선언합니다. "* a"는 할당 할 수 있지만 "a"는 할당 할 수 없습니다.
const int * const a
"a"를 상수 정수에 대한 상수 포인터로 선언합니다. "a"또는 "* a"는 할당 할 수 없습니다.
static int one = 1;
int testfunc3 (const int *a)
{
*a = 1; /* Error */
a = &one;
return *a;
}
int testfunc4 (int * const a)
{
*a = 1;
a = &one; /* Error */
return *a;
}
int testfunc5 (const int * const a)
{
*a = 1; /* Error */
a = &one; /* Error */
return *a;
}
Prakash는 포인터 케이스에 대한 약간의 설명이 순서가있을 수 있지만 선언이 동일하다는 사실이 정확합니다.
"const int * p"는 해당 포인터를 통해 int가 변경되는 것을 허용하지 않는 int에 대한 포인터입니다. "int * const p"는 다른 int를 가리 키도록 변경할 수없는 int에 대한 포인터입니다.
https://isocpp.org/wiki/faq/const-correctness#const-ptr-vs-ptr-const를 참조 하세요 .
이것은 직접적인 대답이 아니라 관련 팁입니다. 일을 똑바로 유지하기 위해 저는 항상 " const
외부에 놓기"대류를 사용합니다 . 여기서 "외부"는 맨 왼쪽 또는 맨 오른쪽을 의미합니다. 이렇게하면 혼동이 없습니다. const는 가장 가까운 것 (유형 또는 *
)에 적용됩니다. 예 :
int * const foo = ...; // Pointer cannot change, pointed to value can change
const int * bar = ...; // Pointer can change, pointed to value cannot change
int * baz = ...; // Pointer can change, pointed to value can change
const int * const qux = ...; // Pointer cannot change, pointed to value cannot change
그것들은 동일하지만 C ++에서는 항상 오른쪽에 const를 사용해야하는 좋은 이유가 있습니다. const 멤버 함수 는 다음과 같이 선언 해야 하므로 모든 곳에서 일관성 이 있습니다.
int getInt() const;
그것은 변화 this
에서 함수 포인터 Foo * const
로 Foo const * const
. 여기를 보아라.
예, 그들은 단지 동일합니다 int
그리고 다른 int*
이 경우에는 동일하다고 생각하지만 다음은 순서가 중요한 예입니다.
const int* cantChangeTheData;
int* const cantChangeTheAddress;