[c] 왜 타입이 아닌 변수 이름 앞에 별표가 나타나는가?
왜 대부분의 C 프로그래머가 다음과 같이 변수 이름을 지정합니까?
int *myVariable;
이보다는
int* myVariable;
둘 다 유효합니다. 별표는 변수 이름의 일부가 아닌 유형의 일부인 것 같습니다. 누구든지이 논리를 설명 할 수 있습니까?
답변
그것들은 정확히 동등합니다. 그러나
int *myVariable, myVariable2;
myVariable의 유형은 int * 이지만 myVariable2의 유형은 int 입니다. 에
int* myVariable, myVariable2;
그것은 모두가 형의 것을 분명 보일 수 INT의 * 하지만, 같은 그것은 정확하지 않은 myVariable2
타입이 INT를 .
따라서 첫 번째 프로그래밍 스타일이 더 직관적입니다.
답변
다른 방법으로 살펴보면 *myVariable
유형이 int
있습니다.
답변
해당 행의 *는 유형보다 변수에 더 가깝게 바인딩되므로
int* varA, varB; // This is misleading
@Lundin이 아래에서 지적한 것처럼 const는 더 많은 미묘함을 추가합니다. 한 줄에 하나의 변수를 선언하여이를 완전히 회피 할 수 있습니다.
int* varA;
int varB;
명확한 코드와 간결한 코드 사이의 균형은 깨지기 어렵습니다. 12 줄의 중복 된 줄도 int a;
좋지 않습니다. 여전히, 나는 한 줄에 하나의 선언을 기본으로하고 나중에 코드를 결합하는 것에 대해 걱정합니다.
답변
지금까지 아무도 언급하지 않은 것은이 별표가 실제로 C에서 ” 역 참조 연산자 “라는 것입니다.
*a = 10;
선 위의 I 할당 할 것을 의미하지 않는다 10
에 a
, 내가 할당 할 뜻 10
대로 메모리 위치를 a
가리 킵니다. 그리고 나는 글을 쓰는 사람을 본 적이 없다
* a = 10;
당신은? 따라서 역 참조 연산자 는 항상 공백없이 작성됩니다. 이것은 아마 여러 줄에 걸쳐 곱셈과 구별되는 것일 것입니다.
x = a * b * c * d
* e * f * g;
여기 *e
그것은하지 않을 오해의 소지가 될 것이다?
이제 다음 줄은 실제로 무엇을 의미합니까?
int *a;
대부분의 사람들은 다음과 같이 말합니다.
이는 값에 a
대한 포인터 임을 의미합니다 int
.
이것은 기술적으로 정확하며 대부분의 사람들은 그것을 그렇게 읽거나 읽는 것을 좋아하며 이것이 현대 C 표준이 그것을 정의하는 방식입니다 (언어 C 자체는 모든 ANSI 및 ISO 표준보다 우선합니다). 그러나 그것을 보는 유일한 방법은 아닙니다. 이 줄을 다음과 같이 읽을 수도 있습니다.
의 역 참조 된 값은 a
유형 int
입니다.
따라서 실제로이 선언에서 별표는 역 참조 연산자로 표시 될 수 있으며이 연산자는 배치를 설명합니다. 그리고 그것은 a
포인터가 실제로 선언되지 않았으며, 실제로 당신이 실제로 역 참조 할 수있는 유일한 것은 포인터라는 사실에 의해 암시 적입니다.
C 표준은 *
운영자 에게 두 가지 의미 만 정의합니다 .
- 간접 연산자
- 곱셈 연산자
그리고 간접는 단지 하나의 의미는 별도의 의미는 포인터를 선언하는가이다, 참조 취소 조작이하는 일,이 같은 문 이내에 또한, 간접적 인 접근을 수행 다만 간접,이 int *a;
이 간접적 인 액세스 ( *
수단 간접 액세스) 따라서 위의 두 번째 진술은 첫 번째 진술보다 표준에 훨씬 가깝습니다.
답변
여기에서 사지로 나가서 변수 선언과 매개 변수 및 반환 유형 모두에 대해이 질문에 대한 정답이 있다고 말합니다. 즉 별표가 이름 옆에 있어야합니다 int *myVariable;
. 이유를 이해하려면 C에서 다른 유형의 기호를 선언하는 방법을 살펴보십시오.
int my_function(int arg);
기능을 위해;
float my_array[3]
배열.
선언은 use 다음에 나오는 일반적인 패턴으로, 심볼의 유형은 이름 앞 부분과 이름 주위 부분으로 나뉘며 이름 주위 의 이러한 부분은 왼쪽에있는 유형의 값 :
int a_return_value = my_function(729);
float an_element = my_array[2];
그리고 : int copy_of_value = *myVariable;
.
참조를 사용하는 지점의 구문이 값 유형의 구문과 동일하므로 C ++은 참조 작업에 스패너를 던지므로 C ++이 C에 대해 다른 접근 방식을 취한다고 주장 할 수 있습니다. 반면에 C ++은 동일하게 유지됩니다. 포인터의 경우 C의 동작이므로 참조는 실제로이 점에서 이상한 것입니다.
답변
그것은 단지 선호의 문제입니다.
코드를 읽을 때 두 번째 경우 변수와 포인터를 구분하는 것이 더 쉽지만, 공통 유형의 변수와 포인터를 한 줄에 넣을 때 혼동을 일으킬 수 있습니다. 가독성이 떨어지기 때문에).
유형 이름 옆에 해당 기호로 포인터를 선언하는 것을 선호합니다.
int* pMyPointer;
답변
한 위대한 전문가는 “컴파일러의 방식을 읽으십시오.”라고 말했습니다.
http://www.drdobbs.com/conversationsa-midsummer-nights-madness/184403835
이것이 const 배치에 관한 것이 었음에도 동일한 규칙이 적용됩니다.
컴파일러는 다음과 같이 읽습니다.
int (*a);
로 :
(int*) a;
변수 옆에 별을 배치하는 습관을 들이게되면 선언을보다 쉽게 읽을 수 있습니다. 또한 다음과 같은 눈가리개를 피합니다.
int* a[10];
— 편집하다 —
나는로서 해석 말할 때 무슨 뜻인지 정확히 설명하는 int (*a)
수단 있다는 것을, *
보다 긴밀하게 결합 a
은보다가 int
, 매우 방식으로 발현에 있음을 4 + 3 * 7
3
보다 긴밀하게 결합 7
이보다 할 4
의 높은 우선 순위로 인해 *
.
ascii art에 대한 사과와 함께 파싱을위한 AST의 개요 int *a
는 대략 다음과 같습니다.
Declaration
/ \
/ \
Declaration- Init-
Secifiers Declarator-
| List
| |
| ...
"int" |
Declarator
/ \
/ ...
Pointer \
| Identifier
| |
"*" |
"a"
명확하게 보여지는 바와 같이, 그들의 공통 조상이 있기 때문에 *
더 밀접하게 묶는 반면, 당신은 나무를 올라가서 공통 조상을 찾아야합니다 .a
Declarator
Declaration
int