언어 자료구조 알고리즘/C 언어 문법

6.메커니즘 형식 - 배열, 포인터

언제나휴일 2009. 8. 19. 05:47
반응형
6.메커니즘 형식 - 배열, 포인터 

 

type에 대한 번역을 형식으로 표현하고 있으니 혼돈하지 마시기 바랍니다.

이와 같이 쓰는 이유는 MSDN에 한글 메뉴얼에서 형식이라는 용어를 사용을 하고 있어 익숙해 지는 것이 Visaul Studio 환경에서 학습을 하는데 도움이 될 것이라는 소견에서 쓰는 것입니다.

 

다루는 내용

    - 배열 형식

    - 포인터 형식

    - value 형식 vs reference 형식

 

 이 책에서 배열과 포인터를 메커니즘 형식이라고 분류한 이유는 기본 형식은 형식 예약어와 변수명만을 가지고 변수 선언을 할 수 있는데 메커니즘 형식은 이 외에 배열 지시 연산자와 원소의 개수가 필요로 하고 이는 사용자가 정하게 되어 실제 할당하는 크기가 다르게 된다.  또한, 포인터는 포인터 지시 연산자와 변수명을 정하게 된다.

 

지시 연산자

 지시 연산자는 사용자가 명명한 것이 어떠한 것이지를 지시하는 연산자를 말한다.

 지시 연산자로는 배열 지시 연산자, 포인터 지시 연산자, 함수 지시 연산자가 있다.

 사용자가 명명한 명칭 뒤에 []이 오면 해당 명칭은 배열이며 []안은 원소의 개수임을 지시한다.

 사용자가 명명한 명칭 뒤에 ()이 오면 해당 명칭은 함수이면 ()안은 입력 매개 변수 리스트가 온다.

 사용자가 명명한 명칭 뒤에 []나 ()이 오지 않고 명칭 앞에 *이 오면 해당 명칭은 포인터임을 지시한다. 

 

 

 지시 연산자는 선언문과 정의문에서만 사용을 하는 연산자로 다른 구문에서 사용하는 같은 모양의 연산자는 지시 연산자가 아니다.

 

위의 소스 4, 5, 18 은 각각 배열과 포인터 , 함수를 지시하는 지시 연산자 들이다.

하지만 8번 라인의 *은 우항에 있는 표현(메모리 주소를 값으로 지녀야 한다.)이 가르키는 곳을 의미하는 간접 연산자이다. 

 

10번 라인의 []는 두 개의 피 연산자를 갖는 데 하나는 메모리 주소를 값으로 지니는 표현, 다른 하나는 정수가 오게 된다.  이 때 [] 연산은 해당 메모리 주소에서 정수 개의 원소 사이즈 만큼의 주소가 가르키는 곳을 의미한다.  arr[2]라고 할 때 arr에서 원소 2개 의 사이즈 만큼의 주소가 가르키는 곳, arr에서 3번째 원소가 있는 곳을 의미한다.

 

13번 라인의 ()는 함수 호출 연산자이다.   

 

 

1. C언어에서 제공하는 배열 형식

 배열은 같은 형태의 데이터(레코드)를 연속적인 메모리(논리적인 메모리)에 할당하여 관리하는 자료구조를 말한다.

프로그래밍 언어들에서는 일반적으로 형식으로 배열을 정의를 하고 있고 C언어에도 정적인 배열 형식의 변수를 선언할 수 있는 매커니즘을 제공하고 있다.  C언어에서는 동적인 배열은 동적 메모리 할당에 관련된 함수 호출을 통해 사용할 수 있게 제공을 하고 있으며 형식으로는 제공하고 있지 않다.

 

정적 배열과 동적 배열

 배열은 자료를 보관하는 컨테이너이다.  배열은 데이터를 보관하는 버퍼가 연속적인 메모리에 할당되어 하나의 관리명으로 관리할 수 있는데 해당 버퍼의 크기(즉, 보관할 수 있는 원소의 개수)가 변할 수 있는가에 따라 정적 배열과 동적 배열로 나눌 수 있다.

 

C언어에서 대부분의 변수명은 할당된 메모리에 있는 값을 의미한다.

하지만, 배열명과 함수명은 할당된 메모리 주소를 값으로 의미한다.

배열명의 경우 여러 개를 관리하기 위한 관리명이기 때문에 특정 원소의 값을 의미할 수는 없다.

이에 배열명은 모든 원소를 관리할 수 있게 하기 위해 할당된 첫번째 주소 즉, 첫 번째 원소의 주소를 값으로 지니고 있다.

 

 2. 포인터

 포인터는 메모리 주소를 값으로 갖는 형식을 말한다. 

 프로그램의 논리적인 메모리 크기는 32bit Windows O/S의 경우 4G바이트이다. 또한, 프로그램의 메모리 주소는 1바이트 단위로 부여를 하기고 있고 따라서 포인터는 4바이트의 크기를 갖는다.

 

 포인터에 있어서 원소 형식은 굉장히 중요한 의미를 갖고 있다.  그 이유는 다음과 같다. 

 

 원소가 char일 경우에 간접 연산자로 값을 대입(assign)을 하면 1바이트에 저장이 된다.

 원소가 int일 경우에 간접 연산자로 값을 대입하면 4바이트에 저장이 된다.

 '포인터 + 정수'의 의미는 해당 포인터가 갖는 메모리 주소에서 원소가 정수개 떨어진 곳의 메모리 주소를 의미한다.

 

 앞서 배열명은 첫번째 원소의 메모리 주소를 갖는다고 얘기를 했는데 배열명은 포인터 상수로 취급이 되며 배열의 경우에도 원소 형식은 굉장히 중요한 의미를 지니게 되는 것이다.

 

value 형식 vs reference 형식

 특정 형식의 변수명은 할당된 메모리 주소에 있는 값을 의미할 수도 있고 혹은 값고 할당된 공간 모두를 의미할 수도 있다.

전자와 같은 특성을 갖는 형식을 value 형식이라 하며 후자의 경우 reference 형식이라고 얘기를 한다.

C언어의 경우 value형식만 제공을 하고 reference 형식은 제공하지 않는다.  

이러한 이유로 할당된 메모리 주소를 값으로 갖는 포인터를 제공하고 있다고 보아도 크게 틀린 얘기가 아닐 것이다.

 

참고로, 대입(assign) 연산자의 좌항은 reference를 지향을 한다. 즉, 대입 연산자의 좌항에 있지 않은 변수명이 어떠한 의미를 갖고 있느냐에 따라 value형식이냐 reference형식이냐를 논할 수 있을 것이다.

 

반응형