C언어 보충3 - 13, 14장

2018. 2. 2. 03:59

13장. 변수의 영역과 데이터 공유

 

※ 예약어란: 예약어란 컴파일러가 사용하는 특정 의미가 있는 단어로서, 각 예약어가 갖고 있는 기능 이외의 목적으로 사용 불가능

  - 예: boolean, char, byte, short, int, long, float, double...

    ※ 참조: https://aventure.tistory.com/58


1. auto 예약어

 - 지역변수의 default값은 auto이다. 즉, auto예약어는 생략이 가능하다.

 - 블록 내부에서 선언한다.

 - 블록 내부에서만 존재한다

 - 블록 내부에서만 사용할 수 있다

 

2. 지역변수 특징

 - 장점

    메모리를 효율적으로 사용

    디버깅에 유리(한정된 곳만 디버깅하면 된다)

 - 단점

    함수간 데이터 공유가 쉽지 않음

 * 함수의 매개변수는 지역변수이다(선언하는 위치만 특별할 뿐이다)

 - 지역변수 적용범위

    {

      int a; //a적용 시작

      {

        int b; //b적용시작

        ...

      } //b 적용끝

      ...

    } //a적용끝

 

   ex)

   

 

3. 전역변수

 - 전역변수는 함수 외부에서 선언한다.

 - 전역변수는 초기화 하지 않아도 0으로 초기화되어 있다.

 - 전역변수는 코드전체에 적용되지만 동일한 변수명의 지역변수가 있는 블록내부에는 적용되지 않는다.

 - 전역변수는 프로그램이 실행될때 메모리에 할당되며 프로그램이 끝날때 까지 존재한다.

 

 - 전역변수 특징

    장점: 코드전체에서 자유롭게 접근가능

    단점: 전역변수 명을 바꿀시 그변수를 코드 전체에서 찾아 수정해야 된다

 ※ 전역변수는 추가적으로 extern과 정적전역변수(static을 전역으로 사용할때)가 있다. 이 내용은 19장 분할컴파일에서 언급된다

    (extern과 정적전역변수는 함수 외부에서 선언하며, 분할 컴파일을 위해 사용하는 예약어이다.)

 

 

4. 정적 지역변수(=static 지역변수)

 - 블록 내부에서 선언한다.(지역변수에 static예약어를 사용)

 - 사용범위는 일반 지역변수와 같다(블록내부)

 - 대신 변수의 저장공간이 스택에 존재하지 않기 때문에 함수가 반환되더라도 저장공간을 유지한다(생존기간이 전역변수와 같다)

    (따라서, 동일한 함수가 여러번 호출되더라도 변수의 이전 데이터가 남아 있기 때문에 변수를 공유하는 것이 가능하다)

 - 지역변수에 static예약어를 사용하면 프로그램이 실행될때 메모리에 할당되며 프로그램이 끝날때 까지 존재한다.

 - 또한 변수 처음 선언할 때 자동으로 0으로 초기화 한다(따라서 static 변수의(저장공간의) 할당과 회수는 함수의 호출과 관계없다)

 

5. 레지스터 변수

 - 레지스터 변수는 cpu안에 있는 저장공간인 레지스터를 사용하는 변수이다

 - 블록 내부에서 선언한다.(지역변수에 register예약어를 사용)

 - 사용범위는 일반 지역변수와 같다(블록내부)

 - 블록 내부에서만 존재한다

 

 - 특징

    반복문 같이 많은 사용이 있는 변수를 레지스터에 할당시 처리시간이 빨라진다

    변수가 메모리에 있지 않으니 포인터를 사용할 수 없다

 - 주의점

    register 예약어를 쓴다고 반드시 레지스터에 변수가 할당 되는 것은 아니다. 단지 컴파일러가 변수를 레지스터에 넣을지 고려

    (즉, 우리가 컴파일러에게 권유하는 것이다)

 

6. 함수의 데이터 공유방법

 - 값 혹은 주소를 넘겨주거나 반환받는다.

 - 주소를 넘겨주거나 반환받을때는 포인터를 사용한다

 - 주소를 함수에 전달하는 경우 함수 내부에서 주소가 가리키는 변수의 값을 바꿀 수 있다.

 - 함수 내부에서 static변수를 선언하고 이 변수의 주소를 반환하는 경우, 함수를 호출하는 블록에서도 사용이 가능하다

 

※ c언어에서 call by value와 call by reference에 대한 논란: 403.p 하단참조

 

 

 

 

14장. 다차원 배열과 포인터배열

 

1. 2차배열

 - 형태: int ary[3][4]

 - 개념상으로는 행렬을 구분하지만, 실제적 메모리 할당에서는 연속적으로 할당된다

 - 초기화

    int ary[3][4]={{1,2,3,4},{5,6},{3}};

    int ary[3][4]={1,2,3,4,5,6,3};

    int ary[3][4]={1,2,3,4}; =>이런경우 남은 저장공간은 0으로 초기화된다

 

2. 2차원 char배열

 - 형태: char ary[3][20] => 19글자짜리 문자열을 3개 저장가능한 배열(맨마지막은 널문자)

 - 일반적 출력함수(예를들어 printf)들은 널문자를 문장의 끝으로 인식한다.

 - 따라서 char배열에 저장가능한 문자수는 배열 요소 수-1 이다

 

 - 입력받기

    scanf("%s", ary[0]);

 - 행의 수 구하기

    n= sizeof(ary)/sizeof(ary[0]); => 행의 수=전체크기/1행크기

 - 초기화

    char ary[1][20]={'c','a','t','\0'};

    char ary[1][20]={"cat"};

    => 남은 저장공간은 '\0'(널문자)으로 초기화된다

 

3. 포인터배열

 - 형태: int *ary[3]  char *ary[3]

 - 포인터형 변수 5개를 요소로 갖는 배열을 의미한다.(위의 경우에는 포인터가 3개를 요소로 갖는 배열을 의미한다)

 

 - 특징

    1차원 배열로 여러 문자열 저장가능

     - ex) char ary[3][20]={"cat","horse","tiger"}; -> char *ary[3]={"cat","horse","tiger"};

    포인터 배열은 요소가 포인터이기 때문에 원래 배열의 전체 크기와는 다르다.

    포인터 배열을 이용해 다른 배열을 서로 엮을 수 있다.

     - ex)

        int ary1[4]={1,2,3,4};

        int ary2[4]={11,12,13,14};

        int ary3[4]={21,22,23,24};

        int *pary[3]={ary1,ary2,ary3}; => 각 배열명은 배열의 시작주소이다(예를 들어 ary1 == &ary1[0] )

     - 포인터 배열로 연결한 하위 배열에 접근하는 방법

        위의 배열에서 ary3[2](즉 값이 23인 요소)에 접근하려면 pary[2][2] 혹은 *(pary[2]+2)를 사용하면된다

        (10장 2.의 주소+정수==주소+(정수*자료형)참조)

 

'Study > 프로그래밍_언어' 카테고리의 다른 글

C언어 보충6 - 18, 19장, 추가사항  (0) 2018.02.03
C언어 보충5 - 16, 17장  (0) 2018.02.03
C언어 보충4 - 15장  (0) 2018.02.03
C언어 보충2 - 11, 12장  (0) 2017.12.06
C언어 보충1 - 10장  (0) 2017.12.02

+ Recent posts