본문 바로가기
프로그래밍/C

[C 언어] 포인터와 배열 응용 / 문자와 문자열 포인터( 문자열 사용하기 ) / 배열 형태로 문자열 선언 / 입력 값을 문자열에 저장

by B T Y 2017. 10. 16.
반응형

포인터와 배열 응용 / 문자와 문자열 포인터( 문자열 사용하기 ) / 배열 형태로 문자열 선언 / 입력 값을 문자열에 저장에 대해서 정리한다.




포인터와 배열 응용


  - 프로그램 실행 중에 원하는 크기만큼 배열을 생성하는 기능

    ( 가변 길이 배열(Variable-Length Array, VLA) )


  - visual studio 2015에서는 해당 방법을 지원하지 않기 때문에

    포인터에 메모리를 할당해서 메모리를 배열처럼 사용하는 방법을 이용한다.


  - 자료형 *포인터 = malloc(sizeof(자료형) * 크기) 형식을 사용한다.

  - '*포인터'처럼 포인터를 역참조한 것과 '포인터[0]'처럼 인덱스 0에 접근하는것은 같은 값을 가져온다.

    또한 '포인터[1]'과 *(포인터 + 1)도 서로 같은 값을 가져온다.

    ( 여기서 사용한 '*(포인터 + 1)'은 포인터에 값을 더하는 방식으로 포인터 연산이라고 한다 )




  - 포인터를 2차원 배열처럼 사용하려면 아래 형식처럼 사용한다.


    * 세로공간 메모리 할당: 자료형 **포인터 = malloc(sizeof(자료형 *) * 세로크기)

    * 가로공간 메모리 할당: 포인터[i] = malloc(sizeof(자료형) * 가로크기) 형식을 이용해서

                                  반복문으로 i를 증가시키면서 메모리를 할당 한다.


    * 메모리에 사용이 끝난다음에는 'free(포인터[i])'를 이용해서 가로공간 메모리부터 해제를 해준다.

      그 이후에는 'free(포인터)'를 이용해서 세로공간 메모리를 해제 해준다.


      !! 메모리를 할당할때 세로공간 메모리부터 할당하고 가로공간 메모리를 할당했기 때문에

         메모리를 해제할때는 그와 반대로 가로 공간 메모리부터 해제한뒤 세로공간 메모리를 해제해준다.


      !! 64bit에서는 int의 크기가 4바이트, int *의 크기가 8바이트이므로 세로 공간 메모리를 할당 할때

         이 부분을 명확하게 구분해줘야한다.




( 2차원 배열처럼 포인터 사용 메모리 할당 그림 )



( 3차원 배열처럼 포인터 사용 메모리 할당 그림 )









문자와 문자열 포인터( 문자열 사용하기 )


  - 문자열을 입력할때는 char *포인터 = "문자열" 형식을 사용한다.

  - 문자열은 1바이트가 넘어가기 때문에 char에 저장 할수 없다.

    그렇기 때문에 포인터를 이용해서 메모리에 저장한다.

    ( 저장 되는 메모리 주소는 운영체제가 알아서 처리해준다 )


  - 문자열을 출력할때는 %s를 이용한다.


  - 문자열은 마지막에 항상 널 문자(NULL)가 붙는다.

    ( NULL은 문자열의 끝을 나타낸다 )


  - 문자열은 메모리의 낮은 주소부터 시작해서 높은 주소까지 저장된다.


  - 문자열 리터럴이 있는 메모리는 읽기 전용이기 때문에 선언할때 이외에는 문자나 문자열을 할당 할 수 없다.

    ( 인덱스로 접근하는 방식 또한 불가능하다 )




( 문자와 문자열 저장 방식 )




( 문자열과 널 문자 )




( 메모리 주소 방향 )







배열 형태로 문자열 선언


  - char 배열이름[크기] = "문자열" 형식을 사용한다.

    ( 문자열 선언시 문자열을 바로 할당할때는 크기를 생략할 수 있다 )


  - 배열로 문자열을 사용할때는 처음 선언할때 배열을 초기화 해주는게 좋다.

    ( 인덱스로 접근해서 넣는 방식이 있긴 하지만 문자열이 길어지면 불편한 방식이다 )

       * 배열 선언이후에 문자열을 넣는 방식으로 각각의 인덱스로 접근해서 넣는 방법 외에도

         복사를 이용해서 넣는 방법이 있다.


  - 배열을 이용해 문자열을 사용할때 배열의 크기는 마지막에 NULL문자를 고려해서 정해줘야 한다.

    ( 예를 들어서 "Hello" 문자열을 배열에 할당한다면 배열의 크기는 최소 6이 되어야 한다 )


  - 문자열 포인터와는 다르게 인덱스로 접근해서 값을 할당하거나 수정 할 수 있다.

    ( 배열을 이용해서 문자열을 할당했을때는 문자열이 모두 배열에 복사되기 때문 )





( 문자열을 배열에 저장하는 방식 )







입력 값을 문자열에 저장하기


  - 문자열을 저장할때는 배열, 포인터를 이용해서 저장이 가능하다.


  - scanf("%s", 배열) 형식을 사용한다.

    ( scanf()를 이용해서 문자열을 입력 받을때 배열 앞에는 &를 붙이지 않는다 )


  - scanf()를 이용해서 문자열을 입력 받을때 입력된 문자열에 공백이 있다면

    공백 직전까지만 저장된다.

    ( 공백까지 포함해서 입력 받으려면 서식 지정자로 %[^\n]s를 사용하면 된다 )


  - 포인터에 scanf()를 이용해서 문자열을 입력 받으려면 malloc() 함수를 이용해서

    문자열 포인터에 메모리를 동적할당 해줘야 한다.

    ( 사용후에는 항상 free() 함수를 이용해서 메모리를 꼭 해제 해줘야한다!!! )  


     * 문자열 포인터에 문자열 값을 할당하고 scanf()를 이용해서 입력을 받으려고 한다면

       해당 포인터에 저장된 메모리 주소는 읽기만 가능하기 때문에 에러가 발생한다.

        ( 문자열 리터럴이 포함된 포인터에는 읽기만 가능하고 쓰기를 할 수가 없다 )


  - 문자열을 여러개 입력받기 위해서는 서식 지정자는 공백으로 구분하고 배열이나 문자열 포인터는 ,를 이용해서

    구분해준다.








반응형

댓글