BLOG ARTICLE bit | 1 ARTICLE FOUND

  1. 2007.06.12 4. 변수 (2)

C에서 변수는 말 그대로 변할 수 있는 값을 의미하며, 변수는 메모리에서 값을 저장할 수 있는 저장소 입니다.  "[변수타입] [변수명];"와 같이 변수를 선언하고 사용할 수 있습니다.

int a;

위에는 a라는 int(정수)형 변수를 선언한 예 입니다.  int가 변수타입 ,  a가 변수 명입니다.

4.1 변수 타입
변수 타입은 문자, 정수, 부동소수점 등 변수에서 저장할 값의 종류를 의미합니다.  C에서는 아래와 같은 변수타입을 제공합니다.
사용자 삽입 이미지

1) char

char 는 1바이트 크기를 가지고 있으며, ASCII 코드의 한 문자 또는 0~255(-128~127)의 숫자를 저장할 수 있습니다. C에서 char의 한 문자는 홑따움표(')를 사용하여 표현하고, 문자열은 쌍따움표(")를 사용하여 표현합니다.


2) short, int , long

일반적인 정수를 표현하기 위한 변수형입니다. 흔히 int는 해당 시스템이 가장 빠르게 처리할 수 있는 크기라고 하며, 일반적으로 2 또는 4Byte의 크기를 가집니다.


3) float, double

float과 double은 부동소수점을 표현하는데 사용됩니다. 모든 데이터를 2진수로 인식하는 컴퓨터에서는 부동소수점을 처리할 때, 약간의 문제가 있습니다. 이 부분에 대해서는 후에 기회가 되면 다시 언급하겠습니다.


4) signed/unsigned

각 변수 타입 앞에는 signed 또는 unsigned 를 선언할 수 있습니다. 생략된 경우에는 signed로 간주합니다. signed와 unsigned는 음수를 포함할 지, 포함하지 않을지를 결정합니다.

1byte인  char를 예로 들면 256가지 경우의 수를 표현할 수 있습니다. 이는 양수만 사용할 경우에는 0~255까지 표현할 수 있지만, 음수도 포함할 경우에는 -128~127까지 표현할 수 있습니다.

4바이트인 int형일 경우에는 비트로 환산하면 4X8=32Bit, 즉 232 까지 표현할 수 있습니다.

참고로 기계가 인식할 수 있는 단위를 비트(bit)라고 합니다. 1bit는 0과 1 (On/Off)의 두가지 경우의 값을 나타낼 수 있습니다. 1 Byte는 8개의 bit로 이루어져 있습니다. 그러므로 2에 8승, 즉 256가지 값을 표현할 수 있습니다.

소스에서 char c = 9; 라는 코드는 실행 시 메모리에 변수 c를 위해 1Byte(8bit)를 할당하고 값은 9로 저장되는데 , 이 9는 컴퓨터에서는 이진수 00001001로 아래와 같이 메모리에 저장됩니다.
사용자 삽입 이미지
위의 2진수는 아래와 같이 10진수로 변환할 수 있습니다.
(0 X 27) + (0 X 26) + (0 X 25) + (0 X 24) + (1 X 23) + (0 X 22) + (0 X 21) + (1 X 20)

첫번째와 네번째만 1이므로 우측으로 부터 첫번째와 두번째 연산인 (1 X 23) + (1 X 20)만 유효하므로 9로 표현됩니다. 2진수를 이해하고 있어야 C에서 사용하는 쉬프트 나 비트 연산을 이해할 수 있습니다.


5) 변수 타입 크기

각 변수타입들의 크기는 일반적으로 아래의 출력내용과 비슷하나, 시스템에 따라서 약간 틀릴 경우도 있습니다. 아래의 코드로 사용하는 시스템에서 변수 타입별로 크기를 확인하실 수 있습니다.

#include <stdio.h>

int main(int argc, char* argv[])
{
    char c;
    short s;
    int n; 
    long l;
    float f;
    double d;

    printf("char: %d\nshort: %d\nint: %d\nlong: %d\nfloat: %d\ndouble: %d\n",      sizeof(c), sizeof(s), sizeof(n), sizeof(l), sizeof(f), sizeof(d));
   
return 0;
}

위의 소스를 컴파일 하고 실행보면, 아래와 같이 각 변수타입 별 바이트 수를 확인하 실 수 있습니다. 아래는 제 맥의 터미널에서 실행해 본 화면 입니다.
사용자 삽입 이미지


4.2 변수명

1) 작성 규칙

변수명은 용도에 따라서 아래의 규칙에 따라 개발자의 마음대로 정할 수 있습니다.
  • 알파벳 대소문자([A-Z][a-z]), 숫자([0-9]), 언더바(_)를 사용할 수 있습니다.
  • 첫 글자에 숫자가 올 수 없습니다.
  • 대소문자를 구별합니다.

>> 아래는 유효한 변수명의 예 입니다.
int myData; int my_data; int mydata_1;

>> 아래는 사용할 수 없는 변수명의 예 입니다.
int my data; int 3mydata;

>> 아래의 temp와 Temp는 서로 다른 변수로 인식 합니다.
int temp; int Temp;


2) 명명법

함수도 마찬가지지만 변수명은 소스를 이해하기 쉽게 만드는데 많은 영향을 줍니다.

윈도우 API 함수와 MFC에서 주로 사용되는 헝가리안 표기법이 있습니다. 변수의 타입과 용도를 알기쉽게 만들어 주는 표기법입니다. 간단하게 예를 들면 아래와 같습니다.

char*  g_pszAppName;
g_ 는 전역변수를 의미하며, p는 포인터, sz은 NULL로 끝나는 문자를 의미 합니다. 그뒤의 이름은 의미별로 대문자로 구별합니다. 이런식의 표기법은 소스 중간에서 g_pszAppName을 보더라도 쉽게 타입과 용도를 추측할 수 있습니다.

하지만 일반적으로 unix C 프로그래머들은 대문자를 define, 전역변수나 특수한 용도가 아니면, 많이 사용하지 않았습니다. 대소문자 구분 대신 "_"를 주로 사용하였습니다. 위의 예를 들면 아래와 같습니다.
char* app_name;

그외 java나 objective-c에선 아래와 같은 명명법을 선호합니다.
char* appName;

어떤 것이 좋은지는 저도 알 수 없고,  윈도우 프로그래머라고 해서 꼭 헝가리안 표기법을 사용하거나 unix 나 java 프로그래머라고 해서 꼭 위와 같이 하지는 않습니다.

하지만 한가지 확실한 점은 일관된 규칙으로 의미있는 변수명을 사용해야 소스의 이해 및 관리가 쉽습니다. 간단히 예를 들면 만약 남녀의 수를 합산하는 코드가 있다면, 1)의 소스 보다 2)의 소스가 이해하기가 더욱 쉽습니다.

1) a = b + c;
2) total_count = man_count + woman_count;


4.3 변수 선언 위치
C에서 변수는 함수의 처음 위치에서 선언되어야 합니다. 하지만 C++ 부터 변수를 함수내에 사용하는 곳에서 자유롭게 선언할 수 있게 되었습니다.

오래된 C 컴파일러는 아래의 좌측 이미지와 같이 함수에서 사용하는 모든 변수들은 함수가 시작되면서 선언되어야 합니다.  하지만 C++의 장점을 포용한 현재의 C 컴파일러들은 아래의 우측과 같이 실행코드 중간에 int j; 와 같이 변수를 선언하는 것을 허용합니다.
사용자 삽입 이미지사용자 삽입 이미지


4.4 변수 유효 범위
변수는 선언되는 위치에 따라서 전역(global)변수와 지역(local)변수로 나누어 집니다.

#include <stdio.h>

int temp = 5;

int main(int argc, char* argv[])
{
    int temp = 3;

    printf("%d", temp);

    return 0;
}

위에서 int temp = 10; 으로 함수 밖에서 선언된 변수는 전역변수이며, 어느 곳에서나 사용될 수 있습니다.

main 함수 내의 int temp = 3; 으로 선언된 변수는 지역변수이며, main 함수 내에서만 사용할 수 있습니다. 

함수 내에서는 지역변수가 우선됨으로 위의 소스를 실행하면, 지역변수 temp의 3이 출력됩니다. main함수 내의 int temp =3; 라인을 삭제 후 컴파일 하면 전역변수 temp의 5가 출력됩니다.

전역변수와 지역변수의 큰 차이점은 전역변수는 어플리케이션 메모리 에서 힙(heap)이라 불리우는 곳에, 지역변수는 지역변수와 더불어 함수인자 등에 사용되는 스택(stack)에 위치 합니다.

스택은 시스템에 따라 제한된 일정한 크기를 가지고 있습니다. 그렇기 때문에 큰 배열 등의 대용량의 메모리가 필요한 경우에는 전역변수나 malloc등을 이용하여 힙영역에 위치 시키거나, 인자로 전달할 때는 포인터를 사용하여야 합니다.


4.5 static 변수
변수타입 앞에 static 이란 키워드를 사용할 수 있습니다. static 변수는 함수내에 지역변수로 선언 되더라도 스택이 아닌 힙 영역에 위치합니다. 그래서 한번 사용하고 값이 사라지는 일반 지역변수와는 달리 계속 그 값을 유지하고 있습니다.

#include <stdio.h>

void test1()
{
    int n = 0;
    printf("test1: %d\n", n);

    n = n + 1;
}

void test2()
{
    static int n = 0;
    printf("test2: %d\n", n);
   
    n = n + 1;
}

int main(int argc, char* argv[])
{
    test1();
    test1();
    test1();

    test2();
    test2();
    test2();

    return 0;
}

위의 소스코드를 컴파일하고 실행하면, 아래와 같은 결과를 확인할 수 있습니다.
사용자 삽입 이미지
test1 함수의 지역변수 n은 함수가 호출될 때마다 스택에 새로 생성되며, 0으로 초기화 됩니다. 그래서 함수 마지막에 1을 더 해주어도 항상 0으로 출력됩니다.

test2 함수의 static 변수 n은  어플리케이션 실행 시에 0으로 초기화되어 힙영역에 위치하기 때문에, 함수가 재호출되어도 항상 그 값을 유지하고 있습니다.

이상 변수에 관해서 알아 보았는데, 몇 가지 언급 되지 않은 내용이 있습니다. 전역 변수에서 static 사용, extern 키워드 등이 있습니다. 이는 여러 소스 파일을 사용할 경우에 사용되며, 추후에 다시 언급하겠습니다.

'프로그래밍 강좌 > C 언어 기초' 카테고리의 다른 글

6. 제어문  (0) 2007.06.14
5. 연산자  (0) 2007.06.13
4. 변수  (2) 2007.06.12
3. C 기초문법  (0) 2007.06.05
2. 소스코드, 컴파일, 링크  (6) 2007.06.04
1. C언어 공부를 위한 준비  (9) 2007.06.03