C언어 포인터 기본에 대해서 배워보자

 

C언어를 처음 접하신 분들은 포인터에 대해서 어려워 하시는 분들이 있는데 어려워 할 필요 없습니다.

 

C언어 포인터 에 대해서 조금만 이해하신다면 예제보고 테스트 소스를 코딩해보고 그러다 보면 언젠가 이게 뭐가 어렵지? 라는 생각을 하게 될 것입니다.

 

포인터에 대해서 조금 더 깊게 파고 들어가면 포인터연산, 함수포인터, 이중포인터 등등 여러가지가 나오는데 이 부분은 일단 포인터에 대해서 공부를 한다음 진도를 나가 봅시다.

 

C언어 를 테스트 할려면 컴파일러가 필요한데 아래 Dev-C++ 무료 컴파일러 입니다. 사용하시는 컴파일러가 있다면 굳이 다운로드 안하셔도 됩니다.

 

C언어 무료 컴파일러인 Dev-c++ 다운로드 방법 입니다.

http://seonissi.tistory.com/admin/entry/post/?id=25

 

 

Dev-c++ 간략한 사용법

http://seonissi.tistory.com/admin/entry/post/?id=26

 

 

C언어 포인터는 단순히 주소라고 생각하면 됩니다.

 

서울시 구로구 구로동 XXXX아파트 101동 1101호

우리가 사는 집엔 모두 주소가 붙듯이 변수를 선언하면 주소가 붙게 됩니다.


 

 

 

 

char 형태의 p라는 변수를 선언 했습니다.

 

 


선언된 변수를 printf문으로 출력해볼 경우 주소가 나타납니다..

 

 

 

 

 

 

 

이렇게 사용하면 변수의 주소를 공유하게 되 포인터로도 변수의 값을 사용 및 수정이 가능합니다. 예를 들어서 우리가 사는 주소에 A라는 사람이 들어가면 그 주소안에는 A라는 사람이 있는거고 B라는 사람이 들어가게 되면 그 주소안에는 B라는 사람이 있는것과 동일한 것입니다..

 

 

변수와 포인터의 주소값을 출력해볼 경우 동일하다라는걸 확인이 가능합니다.

 

 

  

 

포인터 p에 변수를 할당 하지 않을 경우 경우 각각 주소가 다릅니다.

 

위의 결과처럼 주소값이 1만 증가할수 있지만 경우에 따라서 주소값이 다른곳을 가르킬수 있습니다. 포인터가 가르키는 주소값은 메모리 어느 부분을 가르키고 있는데 주소를 할당하지 않은채 사용하다가는 언젠가는 프로

그램이 죽는 현상이 발생하니 주의해야 합니다.

 

 

C언어 포인터 예제 1

 

int main(int argc, char *argv[])

{
    char ch;
    char *p;

 

ch = 'a';
 
printf("ch = %c\n", ch);


    p = &ch;
 
    printf("*p = %c\n", *p);
    printf("ch = %c\n", ch);

}

 

위 예제를 보게 되면 char 형태의 ch를 선언하고 포인터 p를 선언했습니다.

char 형태의 변수값에 'a'라는 값을 넣고 포인터 p에 변수 ch 주소를 할당 했습니다.

그리고 포인터p 가 어떻게 변했느가를 살펴보는 예제 입니다.

 

 

 

 

 결과값을 보면 ch와 포인터p와 값이 동일하다는게 확인이 됩니다.

 

 

 


C언어 포인터 예제 2

int main(int argc, char *argv[])
{
 char ch1;
 char ch2;
 char *p;

 

 ch1 = 'a';
 ch2 = 'b';
 
 printf("ch1 = %c\n", ch1);
 printf("ch2 = %c\n", ch2);
 
 p = &ch1;
 printf("*p1 = %c\n", *p);
 
 p = &ch2;
 printf("*p2 = %c\n", *p);
}

 

 

 

결과값을 보면 할당된 포인터 값에 따라 포인터p의 값이 변환되는 것을 알수 있습니다.

이처럼 포인터는 주소값을 가지고 움직인다는것을 확인했습니다.

 

 

 

C언어 포인터 예제 3

void test1 (char *p)
{
 printf("test1 *p = %c\n", *p);
 *p = '1';
}

 

void test2 (char *p)

{

 printf("test2 *p = %c\n", *p);
 *p = 'a';
}

 

int main(int argc, char *argv[])
{
 char ch1 = 'z';

char *p;

 

 p = &ch1;

 

printf("*p = %c\n", *p);

 test1(p);
 printf("ch1 = %c\n", ch1);

 test2(p);
 printf("ch1 = %c\n", ch1);
}

 

위 예제를 보면 함수에 포인터를 대입해서 함수를 호출 했을때 인자값으로 전송 받았던 포인터 값에 대해 값이 변함이 없는지를 확인할 수 있는 예제 입니다.


거기에 인자값으로 받은 포인터에 다른 값을 대입했을 시 변수로 선언한 ch값이 변화가 있는지 없는지도 확인이 가능합니다.


함수안에서 값을 변경해도 main에서 선언된 ch1이라는 변수에도 영향을 미칩니다.


위의 예제와 같이 함수를 호출할때 함수에 포인터 변수나 주소를 전달하는 것을 call by reference라고 합니다..


ch값을 받고 할당 받은 포인터를 함수로 전달받고 그 값을 printf값으로 출력 하는 예제입니다.

 

 

 


결과값에서 봤듯이 인자값으로 받은 포인터가 ch값과 동일하다는것을 확인할 수 있습니다.


함수안에서 포인터 값을 변경해도 변수로 선언된 ch값 까지 변환되는 부분까지 확인이 가능합니다.


함수의 인자값으로 포인터를 사용해서 그 값을 공유할수 있다는 것입니다.
위와 같이 많이 사용하게 될텐데 포인터를 잘 사용해야 프로그램을 개발할때 모듈화를 하기가 쉽습니다.


이 부분은 더 공부를 해야 될 것입니다.

 


C언어 포인터 예제 4

int main(int argc, char *argv[])

{
 char ch1[10];
 char ch2[20];
 char *p;

 

 ch1[0] = '1';
 ch1[1] = '2';

 ch2[0] = 'a';
 ch2[1] = 'b';
 
 p = ch1;
 printf("ch1 p[0] = %c\n", p[0]);
 printf("ch1 p[1] = %c\n", p[1]);

 

 p = ch2;
 printf("ch2 p[0] = %c"\n, p[0]);
 printf("ch2 p[1] = %c\n", p[1]);
}

 

위 예제는 포인터와 배열에 대한 부분인데 ch1은 10개의 박스를 다 소유하고 있다고 생각하면 됩니다.

 

 

10개의 박스의 안에는 박스 사이즈에 맞게 물건을 넣을수 있는데 사이즈는 "char"형 이라고 보면 되고 물건은 "char"로 선언된 변수라고 보시면 됩니다.

 

포인터로 선언된 p로 ch1을 가르키게 되면 ch1의 데이타를 쓰기 및 읽어올수가 있습니다.


배열을 선언하고 그 배열을 포인터로 할당한 다음 간단하게 포인터로 제어를 하는 식으로 많이 사용합니다.


위의 예제를 보면 포인터 p에 ch1을 할당해서 ch1에 설정된 a, b값을 포인터 p로도 확인을 할수가 있습니다.


다시 포인터 p에 ch2를 할당하면 ch2와 동일하게 사용이 가능합니다.

 

 



결과값을 보시면 ch1과 ch2의 값을 포인터 p로 할당한 다음 printf문으로 출력했을 경우 동일하게 출력 된다는 것을 확인할 수 있습니다.

 

 

C언어 포인터 예제5

 

int main(int argc, char *argv[])

{
 char ch1 = '1';
 char *p1;
 char *p2;

 p1 = &ch1;
 p2 = &ch1;
 
 printf("*p1 = %c\n", *p1);
 printf("*p2 = %c\n", *p2);
 
*p1 = 'a';
 
 printf("*p2 = %c\n", *p2);
}

 

위의 예제를 보면 ch1의 값을 포인터p1과 포인터p2를 동시에 할당을 했습니다. 이럴경우 p1과 p2가 동일하다고 생각하면 되는데 같은 ch1의 변수를 할당받았고 p1을 수정했을 경우 p2의 값도 변한다는 것을 확인할 수 있습니다.


이렇게 포인터를 여러개 선언해서 같이 수정도 가능하다. ch1이 아니라 "p1 = p2"이렇게 선언해도 상관없습니다.
p1도 포인터고 p2도 포인터기 때문에 언제든 주소를 다시 할당할수 있습니다.

 

 

 

 

 

결과값을 보면 p1과 p2는 동일하게 변수 ch1의 값을 동일하게 printf문으로 출력을 하고 있음이 확인 가능합니다.

 

위의 예제처럼 포인터의 경우 다양한 사용이 가능합니다. 구조체를 선언해서 포인터로 할당해서 사용이 가능하고 여러가지 사용이 가능합니다. 위에는 간단하게 C언어 포인터 기본에 대해서만 예제를 설명했습니다.

 

C언어에서 포인터를 사용하지 않아도 프로그램 코딩은 가능하나 포인터를 사용하지 않고 프로그램 코딩을 하는 개발자는 없을 것입니다.

 

실제로 프로그램을 개발하게 되면 이렇게 간단하게 포인터를 사용하지 않고 포인터 연산도 들어가고 포인터 구조체도 쓰고 배열도 들어가고 복잡하게 진행이 됩니다.

 

포인터를 잘못사용할 시 메모리가 뒤죽박죽이 되버릴 수 있습니다. 그리고 포인터를 잘못 정의해도 컴파일러가 체크를 못하는 경우가 종종 발생하기 때문에 개발 완료 후 문제가 발생할 가능성이 있습니다. 그래서 좀더 세세한 코딩이 필요합니다.

도요타 급발진 문제처럼 버그가 발생할 수 있기 때문에 주의해서 개발을 해야 합니다.

 

Posted by 서땡글
,