C언어

11) 배열과 포인터 표기법

SleeveStar 2021. 3. 5. 18:05
반응형

배열 표기법과 포인터 표기법의 관계

 

배열은 [ ]연산자를 사용하여 표현하고 포인터는 *연산자를 사용하여 나타낸다. 변수를 선언할 때 변수의 역할이나 특성이 결정되기 때문에 표현 방식의 선택은 매우 중요하다. 포인터는 포인터 변수가 가리키는 메모리의 시작 주소를 기준으로 삼고, 배열도 해당 배열이 사용하는 메모리 그룹의 시작 주소를 기준으로 삼는다. 

 

따라서 두 문법은 표기만 다를 뿐 문법 구조는 비슷하다. 그래서 다음과 같이 두 문법의 표기법을 바꿔서 사용할 수도 있다.

배열 포인터
char data[5];
data[1] = 5;
// *(data+1) = 5;는 data[1] = 5;와 같음
*(data+1) = 5;
char data;
char *p = &data; //data 변수의 주소를 p에 저장함
*p = 3;  //p가 가리키는 data 변수에 3을 대입함
p[0] = 3;  //*p = 3; 과 같음

*(data+0) = *data 와 같다.

 

배열 표기법의 한계

 

'data[2]'라고 적는 것과 '*(data+2)'라고 적는 것중에 어떤 것이 더 간단해 보이는가?

data[2]가 포인터 표기에 비해 간단해 보일수 있다. 하지만 어떤 문법이든 표기가 간단하다는 뜻은 표현에 제약이 있다는 뜻 과 같다.

 

어떤 표현의 제약이 있는지 예를 들어보자. 다음과 같이 data라는 1차원 배열을 선언하고 각 요소를 값0x12345678로 초기화했다.

 

int data[2] = {0x12345678, 0x12345678};

 

  0x78 0x56 0x34 0x12 0x78 0x56 0x34 0x12  

 

회색구간 = data[0]

청색구간 = data[1]

 

위와 같이 선언한 data 배열에서 data[0] 요소는 총 4바이트로 구성되어 있다. 그런데 첫번째 바이트에 있는 값 0x78을 0x22로 변경하고 싶어서 배열 표기법으로 data[0]에 0x22를 대입하면 어떻게 될까?

 

data[0] = 0x22; //data 배열 항목의 크기가 4바이트이기 때문에 값 0x00000022가 대입됨.

 

배열 표기법으로 'data[0]'이라고 적으면 4바이트 크기의 메모리를 의미하기 때문에 0x22를 대입한다고 해서 data[0]의 일부 값만 변경되는 것이 아니다.  위의 표의 data[0]에 0x00000022의 값을 대입한것과 같게 된다.

 

 

 

배열표기법 대신 포인터 표기법을 사용하면?

 

포인터 표기법으로 값 0x22를 대입해보자.

 

*(data+1) = 0x22; // data[1] = 0x22;를 포인터 표기법으로 나타냄

 

이렇게 변경하면 * 연산자와 (data+1) 사이에 형 변환 문법을 사용할 수 있다.

 

*(char*)(data + 1) = 0x22; //일시적으로 int * 형을 char * 형으로 변환

 

data 배열을 int형으로 선언했기 때문에 포인터로 표기법을 변경하면 일시적으로 char*형으로 변경하겠다는 뜻이다.

즉 포인터가 가리키는 대상의 크기가 4바이트에서 1바이트로 변경된다는 의미이다.

 

즉 data[1]영역의 첫 1바이트만 0x22 값으로 변경되는 것이다.

 

이처럼 배열 표기법을 사용하면 명령문 자체가 단순해서 보기는 좋지만 좀 더 세밀한 표현을 하는 데는 한계가 있기 때문에 포인터 표기법을 사용하는 것이다.

 

반응형

'C언어' 카테고리의 다른 글

12) 프로세스와 메모리 할당  (0) 2021.04.10
11-2) 배열 시작 주소  (0) 2021.03.14
10-2) 표준입력함수 - scanf  (0) 2021.03.03
10) 표준 입력 함수 - getchar, gets  (0) 2021.02.25
9-1) 포인터 변수의 주소 연산  (0) 2021.02.08