◆ C언어 변수와 배열과 포인터 ◆
처음 프로그래밍 언어로 C언어를 선택하게 되면 다양한부문에서 막히게 된다. 일반적으로 막히는 부분은..
1. 비전공자 일 때.. main과 printf, scanf 항목
2. 연산자와 제어구조
3. 함수와 포인터
1부터 2까지는 꾸역꾸역 어떻게든 학습을 해나가는 반면, 3에 들어서면 그냥 C언어를 포기하게 되고 마는 사태가 발생한다.
C언어를 학습해야 하는 이유는 다들 공감하겠지만 메모리를 다룰수 있기 때문이다. 또한 어셈블리어와의 조합도 가능하므로 하드웨어, OS, 애플리케이션 등 다양한 부문에서 활용이 가능하다.
사실 주관적인 것이지만 프로그래밍에서 가장 습득이 어려운 부문은 알고리즘이다. 문법의 경우 알고리즘에 해당되는 것은 데이터 타입과 변수, 연산자, 제어문이며, 나머지는 데이터타입의 다른 표현인 배열과 포인터, 알고리즘을 모듈화하게되는 함수, 데이터 타입을 직접정의하는 구조체/공용체이다.
물론, 컴파일, 링커옵션, 매크로 등 알아두면 강력한 힘을 발휘하는 요소들도 많지만, 흔히 이야기 하는 기초문법은 위에서 언급한 것이 전부다.
이 곳에서 이야기 하고자 하는 것은 변수와, 배열, 포인터의 관계이다. 이 사항을 주제로 삼은 것은 결국 프로그래밍에서 가장 어려운 것중 하나가 데이터 타입이기 때문이다.(주관적 의견임)
일단 핵심부터 이야기하자면 결국 변수와 배열, 포인터는 같은 것이며, 표현방법의 차이만 있을 뿐이라는 것이다.
변수 선언 및 사용을 보면..
일반 변수 선언 및 사용
라고 하게 된다.
우리가 사용하는, 변수 x는 배열과 포인터의 다른 표현일 뿐이라는 것이다. 왜? 결국 x라는 변수는 데이터가 저장되는 메모리의 시작위치를 그저 사람이 편하게 보고자 붙여놓은 이름일뿐이기 때문이다.(언어 쪽에서는 이 이름을 심볼이라 한다.). 이 이름은 컴파일이 완료되면 사라진다. 시스템에게는 메모리 위치가 중요한 것이지 이름은 중요하지 않기 때문이다.
소스 어셈블 코드
위의 어셈블된 코드를 보게 되면 x라는 변수를 표현할 때 dword ptr [x], 0Ah라고 표현했다. 어셈블된 문법은 몰라도 된다. 단, 변수 x를 표현한 것이 dword ptr [x]라는 것만 잠깐 기억해두자..(참고로 dword는 4바이트를 의미한다.)
만약 변수를 배열처럼 표기한다면 어떨까? 상기 핵심으로 정리한 곳(변수, 배열, 포인터가 같은 것)을 따르자면, 변수는 우리가 아는 배열표기식처럼 되어야 한다. 그렇다면 배열 표기는 어떻게 하는가?
배열 선언과 사용
다들 잘 아는 것처럼 위의 형태로 표시한다. 변수를 배열처럼 표기하려면 다음의 규칙을 맞춰주면 된다.
시작주소(=배열이름)[인덱스]
즉, 배열의 요소값을 액세스하는 것은 배열의 시작위치(배열이름 자체가 배열의 메모리 시작주소이다.)에서 인덱스만큼 떨어진 곳의 값([ ])이라는 뜻이다. [ ]연산자는 실제 어셈블리언어에서 메모리 위치의 값이라는 뜻으로 사용된다.. C언어도 마찬가지..
그러므로 변수를 배열처럼 표현하고자 한다면 변수의 시작주소를 지정하고 인덱스를 정한다음, [ ]연산자를 사용하여 값을 표기하도록 해주면된다.
그럼 변수의 주소는 어떻게 표기하는가? 잘 아는 것처럼 주소연산자(&)를 사용하면 OK이다.
변수 x의 주소는 &x이다. 그렇다면 인덱스와 연산자만 표기하면 될 것이다.
따라서
변수를 배열형태로 표현
어셈블 코드
이렇게 하면 변수를 배열처럼 표기하는 것이된다. 또한, 어셈블된 코드를 확인해보면 (&x)[0]가 dword ptr x[ecx]로 표현한 것을 확인할 수 있다. 이것은 우리가 알고 있는 배열의 표현방법이다.
그렇다면 변수로 포인터를 표현할 수 있을까? 포인터는 잘 알다시피 주소를 저장하는 변수고, 출력하면 당연히 주소가 출력되어야 한다. 값을 출력하고자 한다면 참조연산자를 추가하면 된다.
포인터 표현
포인터 어셈블 코드
어셈블된 코드를 보면, 포인터에 저장된 x의 값을 액세스 할 때 dword ptr [ptr] 부분을 확인할 수 있다. 이것은 상기 내용에서 일반 변수 액세스와 배열 액세스와 동일한 표현이라는 것을 알려준다.
그렇다면, 변수를 당연히 주소로 표현해야 하고, 주소표현은 앞서 언급한 것처럼 &연산자를 이용하여 &x라고 표기하면된다.
포인터는 참조연산자를 사용하여 저장된 값을 확인할 수 있기 때문에 &x에 참조연산자를 사용하여 값을 표시했다.
일반 변수를 포인터식으로 표현했다
이런식으로 변수도 포인터표현 처럼 표현 할 수가 있다.
하지만, 변수에 주소를 저장할 수는 있을까? 물론 가능하다.. 단, 그냥 주소를 저장하면 컴파일러는 일반 값으로 인식하기 때문에, 주소라는 것을 알려주기 위한 캐스팅이 필요하다.
일반 변수를 포인터변수로 변신시켰다.
상기 어셈블 코드
상기 어셈블된 코드를 보면 변수 x, y가 dword ptr [x], dword ptr [y]로 표현한 것을 볼 수 있다. 이쯤되면 일반 변수든, 배열이든, 포인터든 거기가 거기라고 밖에 볼 수 없다.
실제 API(Application Programming Interface)를 보면 이런 형태의 주소표현을 하고 있는 경우를 볼 수 있다
그렇다면 배열은 어떨까? 배열도 일반 변수처럼 표현할 수 있을까? 물론 가능하다. 우리가 쓰는 배열 표현식이 결국은 변수 표현식과 같은 표현이다. 단 배열은 인덱스를 가지고 있고, 배열명 자체가 주소를 표현하기 때문에 [ ] 연산자를 사용할 수 밖에 없다.
다음은 배열을 주소기반, 즉 포인터처럼 표기하는 방법은 잘 알고 있는 형태의 표현이다.
주소기반의 배열 표현
주소기반 배열 표현 어셈블
어셈블된 코드에서 *(arr+0)항목을 보면 역시 dword ptr [arr]로 값을 액세스하는 것을 확인 할 수 있다.
포인터도 마찬가지다.
일반변수와 배열과 포인터
상기 소스 어셈블
상기 예에서 포인터와 배열이 표기방법을 공유하고 있다는 것을 확인할 수 있다.
물론, 어셈블된 코드에서 dword ptr [ptr]이라고 표현한 것은 당연하다.
마지막으로 포인터에 일반 값을 저장할 수 있을까? 당연히 가능하다.
포인터에 일반 변수 값 저장 및 액세스
결과를 출력하면 20이라는 값이 출력되는 걸 알 수 있다. 단, 포인터는 주소이므로 덧셈 연산을 하게되면 데이터타입만큼 계산되기 때문에 타입을 unsigned char로 했다. 또한, 주소 연산에는 피연산자 하나가 정수계열 값이 와야 하므로 unsigned char 타입으로 캐스팅 하였다.
물론, 실제 프로그래밍에서는 이렇게 해야할 이유가 없다. 상기 코드는 참조연산자를 붙이게 되면 의도하지 않은 주소에 있는 값을 참조하게 되므로 에러가 발생할 것이다.
하지만, int타입으로 주소를 받는다던가, 일반 타입을 포인터처럼 액세스 하는 것은 종종 존재한다.
실제 이런 주제의 팁을 이야기 하는 것은 일반 데이터타입을 갖는 변수도, 배열도, 포인터도 결국은 다 뭔가를 저장하는 메모리 공간이라는 것을 이해하는 것이 중요하다. 단지 의미가 변수는 단일 값을 저장하고, 배열은 여러 값을 저장하고, 포인터는 주소값을 저장한다는 것이다.
이처럼 변수와 배열, 포인터는 표기법만 서로 다를뿐, 내포하는 의미는 데이터를 저장한다는 측면에서 같으며, 표현법을 서로 공유하고 있음을 알 수 있다.
포인터가 어려운 사람은 함수 선언 및 정의시 다음처럼 매개변수를 작성해도 된다.
void tf(int *ptr); //주소를 전달받는다.
void tf(int parr[]); //주소를 전달받는다.
단, 대다수의 라이브러리가 주소를 매개변수로 받을 때에는 포인터로 선언하고 있다는 것을 생각할 필요가 있다.
궁금한 것은 댓글이나 전화주시면됩니다~
'학습관련Tip , 미니강좌 > IT.SW' 카테고리의 다른 글
[바이트에서 전하는] Java(자바)의 클래스패스 (0) | 2020.04.09 |
---|---|
JAVA Tomcat Eclipse oracle 설치 및 설정(4) - oracle 11g 다운로드 및 설치/계정 등 설정 (0) | 2020.03.27 |
JAVA Tomcat Eclipse oracle 설치 및 설정(3) - Tomcat 다운로드 및 설정 (1) | 2020.03.26 |
JAVA Tomcat Eclipse oracle 설치 및 설정(2) - Eclipse(이클립스) 다운로드 및 설정 (0) | 2020.03.23 |
JAVA Tomcat Eclipse oracle 설치 및 설정(1) - JAVA 다운로드 및 설치 [대전 바이트 컴퓨터학원] (0) | 2020.03.20 |
댓글