일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- Tips프로그래밍강좌
- 이지스퍼블리싱
- 김성엽
- 포인터
- CS
- 티스토리
- 알고리즘
- Direct2D
- Tips강좌
- 지식나눔강좌
- c#
- 리뷰
- Visual Studio
- 백준
- 함수
- 배열
- doit코틀린프로그래밍
- 연산자
- Windows
- 문법
- c++
- c
- Win32
- tipssoft
- VS ERROR
- 프로그래밍
- Desktop
- Programming
- Kotlin
- Javascript
- Yesterday
- Today
- Total
F.R.I.D.A.Y.
포인터와 배열 본문

배열 변수의 이름이 0번 인덱스의 시작 주소인 이유
이번 포스트는 제목 그대로 배열 변수의 이름이 어째서 해당 배열의 0번 인덱스의 주소가 되는지 알아봅니다. 간단해요! int arr[10]; &arr[0]; // 처음 배울 때 주로 사용하는 0번 인덱스의 주소를 가져오는 법..
pang2h.tistory.com
위 글에서는 배열의 첫 요소의 주소는 해당 배열의 이름임을 간단히 설명하고 있습니다. 어째서 이런 결론이 나오게 되는지, 어떤 배경이 있었는지 알아보겠습니다.
# 여기에서 (정적)배열은 소스코드에 직접 배열 문법으로 선언된 자료형을 말합니다.
Index
- 태초에 포인터가 있었다
- 배열의 사용
- 포인터 스타일과 배열 스타일 번갈아 쓰기
- 주소 연산자, 간접 참조 연산자
- 이해하지 못해도 괜찮아요
- 더 알아보기
태초에 포인터가 있었다copy^
신께서 세계를 만들 때 법칙을 몇 가지 만들었으니, 그중 하나가 指 법칙이라.
이 법칙은 널리 사용되어야 했으며 충분히 많은 곳에서 이로울 법칙 이리다.
또한, 법칙은 이해하기 어려워 소수만이 법칙의 진리를 깨닫고 제 힘으로 사용할 수 있음이다.
이 모습을 가여워 한 신께서 대리자를 내려 보내나니, 세상이 이로워지더라.
우스갯소리로 지어본 말입니다. 그래도 포인터와 배열의 상관관계를 설명하고자 했던 취지는 잘 반영되어있다 생각합니다.
말 그대로, 포인터는 어린 개발자들에게는 어려운 문법입니다. 그래서 데니스 리치는 생각했습니다.
"조금 더 쉽게 포인터의 기능을 사용하게 할 수는 없을까?"
고심 끝에 나온 문법이 바로 배열입니다.
배열은 포인터처럼 유용하게 사용할 수 있습니다. 그러나 포인터 문법을 보다 쉽게 사용하기 위해 나온 문법이다 보니 기능의 제약이 들어가고 그만큼 자유도가 떨어지는 문법입니다.
배열의 사용copy^
배열이 포인터의 기능을 약화시켜 나온 문법이니만큼, 포인터의 일부 표현을 사용할 수 있게 됩니다. 포인터가 가리키는 대상의 값을 가져오려고 하면 우리는 아래와 같이 코드를 작성해야 한다고 했습니다.
Problem. M(2,4)[1]의 위치에 존재하는 값 가져오기
// pointer style
*(*(p + 4) + 2);
모르는 사람이 보면 어떤 걸 의미하는지 잘 모를 것입니다. 그러나 배열의 표현 방식을 보면 얘기가 달라집니다.
// array style
arr[4][2];
프로그래밍을 모르는 사람이 보더라도 배열 스타일은 어느 정도 유추해 이해할 수 있을 것입니다.
이 과정에서 가장 중요한 것은 연산자의 문제였습니다. 연산자 자체가 어렵고, 우선순위에서도 뒤쪽으로 밀려있기에 연산 과정을 알기가 어려웠습니다. 그래서 대괄호 연산자를 개발하게 되었습니다.
대괄호 연산자는 아래와 같이 사용할 수 있습니다. 이미 알고 계시겠지만요.
arr[4][2];
대괄호 연산자 앞에 변수의 이름을 작성하고 대괄호 안에는 접근하고자 하는 인덱스를 작성해줍니다. 그러면 위 포인터 스타일과 같이 동작하도록 합니다.
1차원 배열을 기준으로 하면 아래와 같겠죠.
Problem. 1차원 배열의 세 번째 요소에 접근하기.
// pointer style
*(arr + 2);
// array style
arr[2];
언어 개발자들은 사람들이 기존에 통용해 사용하던 문법을 지키려고 합니다. 그래야 자신이 개발한 언어가 부흥하고 생태계에서 살아남을 수 있을 테니까요.
포인터 스타일과 배열 스타일 번갈아 쓰기copy^
배열 자체가 포인터에서 나온 문법이다 보니 포인터 스타일을 배열에 적용할 수 있습니다. 또한, 배열 스타일은 편리하기에 포인터에서도 배열 스타일을 이용할 수 있습니다.
그렇다면 본론으로 돌아와서, 배열의 첫 번째 요소 주소가 어째서 배열 변수의 이름인지를 알아보겠습니다.
주소 연산자, 간접 참조 연산자copy^
일반 변수의 주소가 궁금할 때는 변수 이름 앞에 주소 연산자 &를 붙여 알아봅니다. 또한, 특정 주소를 가진 메모리의 값을 보고 싶다면 간접 참조 연산자 *를 붙여 알아봅니다.

그렇다면 생각해보겠습니다. 위와 같이 변수 이름 var[2]로 명명된 공간이 존재합니다. 이 공간의 주소는 0x100입니다. 이 공간의 값을 가져오려면 어떻게 해야 할까요?
printf("%d", var);
이렇게 생각할 수 있습니다. 그러나 위에서 말한 것처럼 주소를 알고 있다면 간접 참조 연산자를 이용해도 됩니다.
printf("%d", *0x100);
우리는 이 둘을 섞어볼 수도 있습니다.
printf("%d", *(&var));
var에 주소 연산자를 붙여 var로 명명된 공간의 주소를 가져왔고, 해당 주소에 간접 참조 연산자를 사용해 값을 가져왔습니다.
그리고 0을 더해봅시다. 0은 더해도 빼도, 원래 값이 변하지 않지만요.
printf("%d", *(&var + 0));
어디서 많이 본모습 아닌가요? 바로 위에서 설명한 포인터 스타일입니다.
// pointer style
*(arr + 2);
var 앞에 붙는 주소 연산자는 var가 일반 변수이기 때문입니다.
각 변수는 대응되는 하나의 공간을 가리켜야 합니다. 그러나 배열의 경우 하나의 이름으로 여러 공간에 접근할 수 있습니다. 어느 요소를 선택 해야하는지 모호할 수 있습니다. arr 자체는 요소의 시작을 가리키고 뒤에 대괄호 연산자를 통해 offset을 지정해주는 것입니다.
무엇보다 배열 변수의 이름이 첫 요소의 주소를 반환하는 것은 언어가 그렇게 지정했기 때문입니다. 앞서 설명한 내용들은 조금이라도 더 쉽게 이해할 수 있기를 바라며 작성했습니다.
이해하지 못해도 괜찮아요copy^
C에서 배열 변수의 경우에는 그 변수의 이름이 첫 요소의 주소를 반환한다는 것만 기억하기 바랍니다.
더 알아보기copy^
다차원 배열의 요소 값 교환하기
배열을 만들게 되면 다차원 배열을 만들기도 합니다. 종종 각 요소의 값을 변경해야 하는 경우도 존재합니다. 배열 연산자로 만든 정적 배열과, 포인터와 동적 할당을 이용해 만든 동적 배열을 비교해봅니다. 다..
pang2h.tistory.com
'DEV > C C++' 카테고리의 다른 글
포인터 배열? 배열 포인터? (0) | 2020.01.26 |
---|---|
다차원 배열의 요소 값 교환하기 (0) | 2020.01.25 |
Designated Initializer (0) | 2020.01.21 |
배열(array) part2. 다차원 배열 (0) | 2020.01.20 |
배열(array) part1. default (1) | 2020.01.19 |