IT이야기

복잡한 선언문을 읽기 쉬운 규칙?

cyworld 2022. 4. 23. 10:27
반응형

복잡한 선언문을 읽기 쉬운 규칙?

복잡한 포인터 선언문을 읽는 경우 오른쪽-왼쪽 규칙이 있다.

그러나 이 규칙은 읽는 법을 언급하지 않는다.const수식어

예를 들어, 간단한 포인터 선언에서,const다음과 같은 여러 가지 방법으로 적용할 수 있다.

char *buffer; // non-const pointer to non-const memory
const char *buffer; // non-const pointer to const memory
char const *buffer; // equivalent to previous declartion
char * const buffer = {0}; // const pointer to non-const memory
char * buffer const = {0}; // error
const char * const buffer = {0}; // const pointer to const memory

이제 의 사용은 어떨까.const포인터 선언으로?

char **x; // no const;
const char **x;
char * const *x;
char * * const x;
const char * const * x;
const char * * const x;
const char * const * const x;

그리고 그 선언문을 읽기 쉬운 규칙은 무엇인가?어떤 선언이 이치에 맞는가?

시계방향/완화 방향 규칙을 적용할 수 있는가?

두 가지 실제 세계 사례

그 방법은 다음과 같다.const char **명령행 인수를 제공하려면(llvm clang 소스).

의 인수 벡터 매개변수는 다음과 같이 선언된다.

int getopt(int argc, char * const argv[], const char *optstring);

어디에char * const argv[]와 같다char * const * argv그런 맥락에서

두 함수는 동일한 개념(논쟁을 제공하기 위한 문자열의 포인터 벡터)을 사용하고 선언이 다르므로 분명한 질문은 다음과 같다.그들은 왜 다른가?하나가 다른 하나보다 더 말이 되는가?

목적은 다음과 같아야 한다.const수정자는 함수가 이 벡터의 문자열을 조작하지 않으며 벡터의 구조를 변경하지 않음을 명시해야 한다.

const수식어는 사소한 것이다. 수식어는 수식어가 아닌 다른 수식어가 없는 한 수식어가 앞에 오는 것을 수정한다.자:

char const* buffer;  // const modifies char
char* const buffer;  // const modifies *

, 등. 일반적으로는 앞이 보이지 않는 형태는 피하는 것이 좋다.const, 그러나 실제로는, 당신은 그들을 보게 될 것이기 때문에, 당신은 어떤 타입도 그 앞에 있지 않을 때 기억해야 한다.const첫 번째 타입의 뒤에서 논리적으로 움직여야 한다.자:

const char** buffer;

사실:

char const** buffer;

, 즉, const char에 대한 포인터.

마지막으로 함수 선언에서 a[]…으로 읽은 후에.*(또한, 이런 오해의 소지가 있는 표기법은 피하는 것이 좋을 것 같지만, 곧 보게 되므로 반드시 대처해야 한다.)자:

char * const argv[],  //  As function argument

다음과 같은 경우:

char *const * argv,

철자를 가리키는 항성 포인터

(질문의 다른 측면에 초점을 맞추려고 시도 중)

법관선언에 대한 엄지의 법칙은 그것을 오른쪽에서 왼쪽으로 읽고, 그리고 왼쪽에서 읽는 것이다.const다음 토큰을 수정하다예외:선언의 시작에const이전 토큰을 수정하다

이 예외에는 근거가 있다 - 기본 선언에 대한const char c보다 더 자연스러운 사람을 찾는다.char const c- 그리고 의 전구적인 형태인 것으로 보고되고 있다.const char c최후의 심판 규칙보다 앞서다

선택권을 얻다

int getopt(int argc, char * const argv[], const char *optstring);

또는

int getopt(int argc, char * const * argv, const char *optstring);

은... 그 말은...argv일정하지 않은 문자열의 포인터의 등축 벡터에 대한 포인터.

그러나 누군가는 다음과 같은 선언을 예상할 것이다.

int getopt(int argc, char const * const * argv, const char *optstring);

(경구 벡터에 대해 등구 문자열로 표시)

왜냐하면getopt()argv를 통해 참조되는 문자열을 변경해서는 안 된다.

적어도char **(에 사용된 바와 같이)main())은(는) 다음으로 자동 변환됨char * const * argv.

클랑

ASTUnit::LoadFromCommandLine(...,  const char **argv, ...);

은... 그 말은...argv항상 문자열에 대한 포인터의 일정하지 않은 배열의 포인터.

다시 한 번 예상할 수 있을 것이다.const char * const *argv위와 같은 이유로

하지만 이것이 더 눈에 띄는 이유는char ** 로 변환되지 않음const char **예)

int main(int argc, char **argv) {
  const char **x = argv; // Compile error!
  return 0;
}

컴파일 오류를 산출한다.

int main(int argc, char **argv) {
  char * const *x = argv;
  return 0;
}

그리고

int main(int argc, char **argv) {
  const char * const *x = argv;
  return 0;
}

하지마

참조URL: https://stackoverflow.com/questions/7526152/easy-rule-to-read-complicated-const-declarations

반응형