연산자 우선순위만 잘 알아도 C 배열과 포인터 이해 난이도가 낮아지네요
C isn't that hard
라는 밈이 있을 정도로 포인터와 배열이 엉켜 있는 변수를 해석하는 게 굉장히 어려웠는데
결국 간단하게 몇 가지만 기억하면 수월해지더라구요. (하지만 여전히 헷갈리긴 합니다)
기본 자료형은 그대로 해석하면 되니까 어렵지 않고
함수, 배열, 포인터는 식별자 뒤에 뭐가 자꾸 붙으니까 헷갈리는 것 같습니다.
일단 식별자가 함수일 때, 배열일 때, 주소(포인터)일 때 각각 알아둬야 할 점은
함수 : 매개변수의 개수와 각각의 자료형, 반환값의 자료형
배열 : 원소 개수, 원소 자료형 (여기서는 원소 개수가 그렇게 중요하지는 않은 것 같습니다)
주소 : 그 주소에 있는 값의 자료형
그리고 연산자 우선순위는 일단 큰 틀로 볼 때 이렇게 나눕니다.
순위 | 연산자 |
---|---|
1 | 단항 후위 연산자 |
2 | 단항 전위 연산자 |
3 | 이항 연산자 |
4 | 삼항 연산자 |
5 | 대입 연산자 |
6 | 콤마 |
그리고 둥근 괄호로 감싸서 우선순위를 바꿀 수 있습니다.
함수는 식별자 뒤에 둥근 괄호 (단항 후위 연산자)
배열은 식별자 뒤에 네모난 괄호 (단항 후위 연산자)
주소는 식별자 앞에 별 (단항 전위 연산자)
int *foo[5];
식별자를 시작으로 [5]가 * 보다 연산자 우선순위에 앞섭니다.
식별자 foo는 배열
__ 배열의 길이는 5
__ 배열 원소는 주소
_____ 그 주소에 있는 건 int
int meeh[3][7];
식별자 meeh는 배열
__ 배열의 원소 개수는 3
__ 배열의 원소는 배열
_____ 그 배열의 원소 개수는 7
_____ 그 배열의 원소는 int
void (*(*bar[3]) ()) (); /* bar[3] *bar[3] (*bar[3]) () *(*bar[3]) () (*(*bar[3]) ()) () void (*(*bar[3]) ()) () // */
C isn't that hard 밈에 하나를 더 넣었습니다.
이쯤 되면 typedef를 쓰는 게 좋고, 실제로 이렇게 쓰는 경우도 많이 없을 것 같습니다.
식별자 bar는 배열
__ 배열의 원소 개수는 3
__ 배열의 원소는 주소
_____ 그 주소에 있는 건 함수
________ 그 함수의 매개변수는 없음
________ 그 함수가 반환하는 것은 주소
___________ 그 주소에 있는 건 함수
______________ 그 함수의 매개변수는 없음
______________ 그 함수가 반환하는 것은 없음
char (*(*(*a)[6][2]) (int *, float))[5]; /* *a (*a)[6] (*a)[6][2] *(*a)[6][2] (*(*a)[6][2]) (int *, float) *(*(*a)[6][2]) (int *, float) (*(*(*a)[6][2]) (int *, float))[5] char (*(*(*a)[6][2]) (int *, float))[5] // */
더 복잡하게 섞어 봤습니다. 데니스 리치도 이렇게는 안 할 것 같습니다.
식별자 a는 주소
__ 주소에 있는 건 배열
_____ 그 배열의 원소 개수는 6
_____ 그 배열의 원소는 배열
________ 그 배열의 원소 개수는 2
________ 그 배열의 원소는 주소
___________ 그 주소에 있는 건 함수
______________ 그 함수의 매개변수 개수는 2
_________________ 매개변수 1은 주소
____________________ 그 주소에 있는 건 int
_________________ 매개변수 2는 float
______________ 그 함수가 반환하는 것은 주소
_________________ 그 주소에 있는 건 배열
____________________ 그 배열의 원소 개수는 5
____________________ 그 배열의 원소는 char
결론
배울수록 재밌는 C의 세계
근데 < <= > >= == != 가 & ^ | 보다 우선순위 높은 건 좀 ...
익명사용자께서 강좌를 올리셨군요.
익명사용자께서 강좌를 올리셨군요.
그냥 질문도 아니고 강좌인데...
회원가입 후 로그인 해서 올리면 더욱 좋을 거 같네요.
세벌 https://sebuls.blogspot.kr/
계정을 만들었습니다.
계정을 만들었습니다.
원래 이거 하나만 쓸 생각이었는데, 계정 만든 김에 몇 개 더 써야겠네요.
// endmsg
감사합니다
배열 포인터나 함수 포인터를 어떻게 이해해야 할 지 궁금했는데, 알고 보면 쉽게 해석할 수 있는 내용이었네요.
좋은 설명 감사합니다.
다시 보니 오류가 좀 있네요.
다시 보니 오류가 좀 있네요.
"단항 후위 연산자"가 아니고 "후위 연산자" 입니다.
// endmsg
댓글 달기