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

[C언어] 중첩 반복문 / goto 제어문 / FizzBuzz 문제 / 포인터 / 메모리 사용

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

중첩 반복문 / goto 제어문 / FizzBuzz 문제 / 포인터 / 메모리 사용하기에 대해서 정리한다.



중첩 반복문


  - 중첩 반복문을 이용하면 2차원 형태의 값을 제어할 수 있다.











goto 제어문


  goto 레이블;


  레이블:


  - 프로그램의 흐름을 원하는대로 바꿀때 사용한다.

    ( 중간의 코드는 무시하고 원하는곳으로 건너뛰게 된다 )


  - 위아래 방향 상관없이 사용할 수 있다.

  - 에러처리를 할때 유용하게 사용할 수 있다.

  - goto를 너무 남발하면 유지보수와 가독성이 떨어지는 스파게티 코드가 될 수 있다.

  - 실행되는 레이블이 연속적으로 위치해있다면 switch문을 사용할때 case안에 break가 없으면 

    아래 case에 있는 실행코드들도 실행하는 것처럼 해당 레이블 실행이후에 종료 시키는 코드가 없다면

    아래 레이블에 코드들도 실행 시키는 동작을 하게 된다.


  








FizzBuzz 문제


  - 규칙

    * 1에서 100까지 출력

    * 3의 배수는 Fizz 출력

    * 5의 배수는 Buzz 출력

    * 3과 5의 공배수는 FizzBuzz 출력






포인터


  자료형 *포인터이름;    // 포인터를 선언


  포인터 = &변수;    // 포인터에 변수의 주소를 할당


  *포인터    // 포인터 역참조





  - 변수의 메모리 주소를 구할때는 '&변수'를 이용한다.

    ( printf()로 출력할때 서식지정자는 %p를 이용한다 )


  - 포인터 변수를 선언할때는 '자료형 *포인터이름' 형식으로 선언한다.

    ( *의 위치는 '자료형* 포인터이름', '자료형 * 포인터이름', '자료형 *포인터이름' 모두 사용이 가능하다 )


  - 포인터 변수를 선언하고 해당 포인터 변수에 다른 변수의 주소 값을 넣을때는 '포인터 = &변수' 형식을 사용한다.



  - '*포인터' 형식을 이용해서 역참조를 할 수있다.

    ( 역참조를 이용해서 해당 포인터가 가르키는 변수주소에 저장된 값을 가져올 수 있다 )


  - 역참조 연산자는 값을 가져올수도 있고 값을 저장할 수도 있다.

    ( 역참조를 이용해서 저장할때 해당 포인터가 다른 변수의 주소를 가르키고 있다면 그 변수도 값의 변화가 일어난다 )



  - 선언하는 자료형에 따라 메모리에 접근하는 방법이 달라진다.

    ( long long의 경우 값을 역참조해서 가져올때 8바이트를 가져오고 float의 경우에는 4바이트 char의 경우에는 1바이트를 가져오게 된다 )


  - void 포인터의 경우 어떤 자료형으로 된 포인터든 모두 저장이 가능하고

    다양한 자료형으로 된 포인터에도 void 포인터 저장이 가능하다.  ( 범용 포인터 )

    ( 'void *포인터이름' 형식으로 사용 )


    * 자료형을 변환하지 않아도 암시적으로 자료형이 변환되는 방식이다.

    * 단, 자료형의 크기가 정해져있지 않기 때문에 void 포인터는 역참조가 불가능하다.

    * void 포인터는 함수에서 다양한 자료형을 받아들일 때, 함수의 반환 포인터를 다양한 자료형응로 된 포인터에 저장할 때,

      자료형을 숨기고 싶을때 등에서 사용한다.





  - '자료형 **포인터이름' 형식을 이용해서 포인터의 주소를 구할수 있다.

    ( 역참조를 할때는 '**포인터이름'을 이용해서 가져온다 )


   int **numPtr2;

   int *numPtr1;

   int num1;


   *numPtr1 = &num1;

   **numPtr2 = *numPtr1;




    * 포인터를 사용할때 * 갯수에 따라서 이중, 삼중, 사중 포인터과 같이 다중 포인터를 만들수 있다.

      ( 단, 역참조를 할때도 마찬가지로 * 갯수를 맞춰줘야 한다 )


  ! 포인터는 메모리 주소를 저장하는 용도이기 때문에 값을 직접 저장하면 안된다.

     ( 다만, 실제 존재하는 메모리 주소는 포인터에 직접 담을수 있다 )



















메모리 사용하기


  - 포인터에는 malloc 함수로 원하는 만큼 메모리를 할당이 가능하다.

  - malloc 함수는 <stdlib.h> 헤더 파일 정의 되있다.

  - 동적 메모리 할당

  - malloc 함수는 heap 부분에 메모리를 사용한다.

    ( 변수의 경우에는 stack 부분의 메모리를 사용 )



    * stack에서 사용한 메모리는 따로 메모리 해제를 해주지 않아도 되지만 heap 영역에서 사용한 메모리는 항상 free 함수를 이용해서 

      메모리를 해제해줘야 한다.

         ( 메모리를 해제 해주지 않는다면 메모리 사용량이 계속 증가하는 메모리 누수(memory leak) 현상이 일어난다 )


  - '포인터 = malloc(크기);' 형식으로 메모리를 할당


    * malloc 함수에 크기를 음수로 설정해주게 되면 NULL이 반환된다.

        ( 크기는 양수만 가능하다 )



  - 필요한 메모리 크기의 단위는 byte 사용

  - 사용이 끝난 메모리는 항상 free 함수로 메모리를 해제해줘야 한다.

  - malloc 함수를 이용해서 메모리를 할당한 포인터에 값을 할당할때는 마찬가지로 역참조를 이용해서 할당한다.

    ( printf()로 출력할때도 일반 포인터를 이용할때와 같은 방법인 역참조를 이용한다 )






  - memset 함수를 이용하면 메모리의 내용을 원하는 크기만큼 특정값으로 설정이 가능하다.

    * memset(포인터, 설정할값, 크기) 형식으로 사용한다.

    * <string.h> 혹은 <memory.h> 헤더 파일에 정의되어 있다.

    * 설정할 값을 0으로해서 메모리의 내용을 모두 0으로 만들때 자주 사용한다.






  - NULL을 이용해서 널 포인터를 만들수 있고 아무것도(메모리 주소) 가르키고 있지 않는 상태이다.

    ( 역참조는 불가능하고 널 포인터를 이용해서 해당 메모리에 주소가 있는지를 필터링할때도 사용 가능하다 )





반응형

댓글