C언어에서는 키워드 외에는 모든것이 식별자로 처리됩니다.

식별자는 변수, 상수, 함수 및 사용자 정의 데이터(구조체, 클래스 등)에 지정된 이름이 될 수 있습니다.


변수 이름은 영문(대문자, 소문자), 숫자(0~9) 및 특수문자(밑줄 _)로 구성될 수 있습니다.

(일부 컴파일러는 한글을 지원합니다.)


그러나 어떤 변수의 이름도 숫자로 시작할 수 없다고 배웠습니다.

왜일까요?

그 이유를 알아보도록 하겠습니다.


컴파일러에는 다음과 같은 7가지 단계가 존재합니다.


1. Lexical Analysis (어휘 분석)

2. Syntax Analysis (구문 분석)

3. Semantic Analysis (시맨틱 분석)

4. Intermediate Code Generation (중간 코드 생성)

5. Code Optimization (코드 최적화)

6. Code Generation (코드 생성)

7. Symbol Table (심볼 테이블)


각 단계의 자세한 설명은 추후에 하도록 하겠습니다.


컴파일러는 코드 조각을 컴파일하면서 1. 어휘분석 단계에서 역 추적을 피할 수 있습니다.

예를들어 Yeolco라는 변수를 컴파일 1. 어휘분석 단계에서 문자 'Y'를 만날때 컴파일러는 즉시 식별자를 알 수 있습니다.

그러나, 142Yeolco12 같은 변수를 컴파일러는 숫자 또는 식별자가 'Y'에 도달할때 까지 결정할 수 없으며

1. 어휘분석 단계에서 변수임을 식별하기위해 역 추적이 필요합니다.

그러나 이는 컴파일러에서 지원되지 않습니다.




질문 사항은 모두 커뮤니티에서 받습니다. -> 커뮤니티 바로가기

메인 페이지로 이동하시면 더 많은 자료를 볼 수 있습니다.

'C, C++' 카테고리의 다른 글

C 정적(static) 변수  (0) 2018.10.29
C 변수 선언 및 키워드  (0) 2018.10.25
C 표준 입력 함수 scanf  (0) 2018.10.23
C 표준 출력 함수 printf()  (0) 2018.10.22
C++ 가상 함수(Virtual Function)  (8) 2018.10.19
C++ 연산자 오버로딩  (2) 2018.10.12
C++ 함수 오버로딩  (0) 2018.10.11
C/C++ 메모리 동적할당  (0) 2018.10.11

C 정적(static) 변수




안녕하세요 열코입니다.

이번시간에는 C언어에서의 정적(static) 변수(variable)에 대해 알아보도록 하겠습니다.


C언어에서 기본적인 변수는 동적(dynamic)변수로써 변수 선언과 동시에 메모리에 할당되며

변수 사용이 모두 끝남(변수 선언의 범위가 끝남, 지역변수의 사용종료 시)과 동시에 메모리가 해제됩니다.

하지만 정적 변수는 컴파일시(전역변수와 동일) 메모리에 할당되며, 프로그램 종료시 메모리가 해제됩니다.

따라서 정적 변수는 전역변수처럼 변수의 범위를 벗어나는 경우에도 값을 유지하는 속성을 가지고 있습니다.


다음 예제를 통해 좀 더 이해를 쉽게 돕겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
 
int test(void)
{
    int count = 0;
    count++;
 
    return count;
}
 
int main(void)
{
    printf("%d\n", test());
    printf("%d\n", test());
 
    return 0;
}
cs


위 프로그램의 실행 결과


1

1


test() 라는 함수안에 count라는 int형 지역변수가 존재하며,

이는 main() 함수에서 printf() 함수로 호출할 때, 비로소 메모리에 할당되며 초기화가 됩니다.

첫번째 printf() 함수에서 test() 함수를 호출할 때 count라는 지역변수가 할당되고 0으로 초기화 됩니다.

그리고 count++;문을 통해 count는 1이되며 그 값이 반환되며 1을 출력합니다.




이때, count라는 지역변수는 사라지게되며 메모리 또한 해제됩니다.

두번째 printf() 함수에서 test() 함수를 호출하면 또 다시 count라는 이름의 지역변수가 할당됩니다.

(첫번째 호출된 test() 함수의 count와는 다른 메모리, 이름만 count로 같을 뿐)

따라서 또 다시 1을 출력하게 됩니다.


그렇다면 아래 소스코드의 실행결과는 어떻게 될까요?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
 
int test(void)
{
    static int count = 0;
    count++;
 
    return count;
}
 
int main(void)
{
    printf("%d\n", test());
    printf("%d\n", test());
 
    return 0;
}
cs


바뀐점이 없다구요??

잘보세요. 5번째 줄의 count 변수 맨 앞에 static이라는 키워드가 붙었습니다.

static 키워드가 붙으면 변수는 정적 변수로 선언되며, 이는 컴파일 시간에 메모리에 할당됩니다.

count라는 변수는 프로그램 종료시까지 메모리가 유지됩니다.


실행 결과는 아래와 같습니다.


1

2


첫번째 printf() 함수에서 test()함수를 호출하면 count라는 이미 선언되어 메모리에 할당되어있는 변수에 1을 더해

1을 반환하며, 두번째 printf() 함수에서 test() 함수를 호출하면 똑같은 변수인 count 함수에 1이 더해져,

결과적으로 2를 반환하게 됩니다.


static int count = 0; 이라고 되어있어서 다시 0으로 초기화되는거 아니냐고 물으시는 분도 계시는데,

위 구문 자체가 컴파일 시간에 메모리에 할당되며 최초 1회 초기화가 실행됩니다.

따라서 두번째 test() 함수 호출 시 0으로 다시 초기화 되지 않고 1에 1을 더한 2를 출력하게됩니다.




정적 변수는 또한 다음과 같은 특징들이 존재합니다.


나중에 따로 언급하겠지만, 메모리 구조상 정적 변수는 일반 지역 변수가 할당되는 스택(stack) 부분이 아닌

데이터(data) 부분에 메모리가 할당됩니다. 이는 추후 메모리 구조 시간에 자세히 설명하겠습니다.


전역 변수와 같이 정적 변수는 명시적으로 초기화하지 않을 때 0으로 자동 초기화 됩니다.

지역 변수는 초기화하지 않으면 쓰레기 값(의미없는 값)으로 초기화 되는것 다 알고계시죠??


C에서는 정적 변수 초기화를 리터럴 상수로만 초기화 가능합니다.

다음과 같은 예제문은 컴파일 오류를 발생시킵니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
 
int test(void)
{
    return 10;
}
 
int main(void)
{
    static int a = test();
 
    printf("%d\n", a);
 
    return 0;
}
cs


하지만 이는 C++ 프로그램에서는 컴파일 오류를 발생시키지 않습니다.




이상 'C언어 정적 변수'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

메인 페이지로 이동하시면 더 많은 자료를 볼 수 있습니다.



'C, C++' 카테고리의 다른 글

C언어 변수 이름이 숫자로 시작할 수 없는 이유  (0) 2018.11.13
C 변수 선언 및 키워드  (0) 2018.10.25
C 표준 입력 함수 scanf  (0) 2018.10.23
C 표준 출력 함수 printf()  (0) 2018.10.22
C++ 가상 함수(Virtual Function)  (8) 2018.10.19
C++ 연산자 오버로딩  (2) 2018.10.12
C++ 함수 오버로딩  (0) 2018.10.11
C/C++ 메모리 동적할당  (0) 2018.10.11



안녕하세요 열코입니다.

이번 시간에는 C언어 변수 선언 및 키워드에 대해 알아보겠습니다.

변수(variable)란 메모리에 할당된 기억장소를 일컫는말이며 기본적으로 어떤 형태의

데이터를 저장하는데 사용됩니다. 또한 변수의 종류마다 다른 크기의 메모리가 필요합니다.


변수 선언 방법

일반적인 변수 선언의 형식은 다음과 같습니다.


타입 변수이름;

타입 변수이름1, 변수이름2, 변수이름3;


타입은 변수의 자료형을 말하며, 기본자료형 및 사용자 정의 자료형이 올 수 있습니다.

사용자 정의 자료형은 C언어에서 대표적으로 구조체를 떠올릴 수 있겠네요.


C언어의 대표적인 기본 자료형은 다음과 같습니다.


char (1byte) : 문자 (-128 ~ 127)

short (2byte) : 정수 (-32768 ~ 32767)

int (4byte) : 정수 (-2147483648 ~ 2147483647)

long (4byte) : 정수 (-2147483648 ~ 2147483647)

float (4byte) : 실수 (부동소수점, ±3.4x10^-37 ~ ±3.4x10^38)

double (8byte) : 실수 (부동소수점, ±1.7x10^-307 ~ ±1.7x10^308)


맨 앞은 변수의 자료형 이름이며, 괄호안은 자료형의 크기입니다.(32bit 운영체제 기준)

마지막 괄호는 변수의 범위입니다.



변수 명명 규칙(Naming Rule)

변수의 이름을 정하는것은 개발자에게 아주 고민스러운 일입니다.

마치 어릴적 메이플스토리에서 캐릭터 생성화면에서 멈춘것처럼 말이죠.

잘 지은 변수이름하나가 프로그램 전체의 가독성과 이해에 영향을 미칠정도로 변수의 이름은 중요합니다.


C언어에서는 변수 이름으로 다음과 같은 제약사항이 있습니다.


1. 영문자, 숫자, 밑줄( _ )만이 사용가능하다. (최신 컴파일러에서는 한글도 가능합니다.)

2. 숫자를 변수 이름의 처음으로 사용 할 수 없다. (예. int 2d; → 오류)

3. 변수 이름에서 대소문자는 구분된다. (예. int X와 int x는 별개의 변수)

4. 키워드는 변수이름으로 사용할 수 없다. (아래 세부설명 참고)

5. 하나 또는 두개의 밑줄로 시작하는 이름은 미리 식별된 문자로 예약되어있다. (_ 또는 __)

6. 변수 이름의 길이는 제한이 없다.





또한 개발자 마다 변수이름을 붙이는 스타일이 다르기 때문에 변수 명명법에 대한 코딩 표준법이 존재합니다.

대표적으로 파스칼케이싱(PascalCasing)과 카멜케이싱(CamelCasing)에 대해 알아보겠습니다.


- Pascal Casing

클래스(C++,Java), 열거형(enum), 이벤트, 함수 등의 이름을 만들 때 사용하며 대문자로 시작합니다.

복합어인 경우 중간에 새로 시작하는 단어를 대문자로 사용합니다.

예) GetName, PrintString, MyStruct, NumOfPeople 등


- Camel Casing

함수의 매개변수의 이름에 적용되며 첫번째 문자는 소문자로 시작하며

복합어일 경우 새로 시작하는 단어를 대문자로 사용합니다.

예) getName, printString, myStruct, numOfPeople 등



C언어 키워드

키워드(keywords)는 C언어의 특정 예약어로 기능을 사용하는데 도움이 되는 목록입니다.

C언어에서는 총 32개(이상)의 키워드가 있습니다.


auto, break, case, char, const, continue, default, do, double, else, enum, extern, float, for, goto, if, int, long, register, return, short, signed, static, struct, switch, typedef, union, unsigned, void, volatile, while


위 키워드들은 코드 작성시 파란색으로 변경되며 변수이름으로는 사용할 수 없습니다.


특수한 변수들

const : 상수를 선언하는데 사용할 수 있습니다.

C언어 상수는 반드시 선언시 초기화해야하며 포인터와 함께 사용될 수 있습니다.

상수는 프로그램 실행 도중 더이상 값을 수정할 수 없습니다.


const type(자료형) name(변수이름) = value(값);


extern : 변수가 사용된 블록이 아닌 다른곳에서 정의됬다고 명시합니다.

기본적으로 C언어에서 헤더파일이나 다른 .c 파일에서 선언된 변수를 사용하기 위해 사용됩니다.


extern type(자료형) name(변수이름) = value(값);


static : 프로그램에 정적 변수를 선언하는데 사용됩니다.

기본적으로 C언어 변수는 동적(dynamic) 변수로써 사용시 메모리가 할당되며 사용되고 해제됩니다.

정적 변수로 선언되면 프로그램 종료시까지 메모리가 유지됩니다.

static 변수 역시 const와 같이 사용될 수 있으며 오직 한번만 초기화됩니다.


static type(자료형) name(변수이름) = value(값);


void : 빈 데이터 유형입니다.

함수의 반환값이 없을때 사용하거나 포인터가 자료형과 관계없이 가리킬 때 사용됩니다.


typedef : 이미 존재하거나 사용자 정의 자료형(구조체 등)에 새 이름을 제공할 때 사용합니다.

구조체 이름이 너무 길거나 기존 자료형 이름을 간단하게 표기할 때 사용합니다.


typedef type(자료형) name(새로 정의한 자료형 이름);

예) typedef long long int LL; (long long int를 LL로 사용하겠다.)





이상 'C언어 변수선언 및 키워드'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

메인 페이지로 이동하시면 더 많은 자료를 볼 수 있습니다.



'C, C++' 카테고리의 다른 글

C언어 변수 이름이 숫자로 시작할 수 없는 이유  (0) 2018.11.13
C 정적(static) 변수  (0) 2018.10.29
C 표준 입력 함수 scanf  (0) 2018.10.23
C 표준 출력 함수 printf()  (0) 2018.10.22
C++ 가상 함수(Virtual Function)  (8) 2018.10.19
C++ 연산자 오버로딩  (2) 2018.10.12
C++ 함수 오버로딩  (0) 2018.10.11
C/C++ 메모리 동적할당  (0) 2018.10.11

C 표준 입력 함수 scanf




안녕하세요 열코입니다.

저번 시간에 C언어 표준 출력 함수인 printf() 함수에 대해 알아봤는데요.

이번 시간에는 C언어 표준 입력 함수인 scanf() 함수에 대해 알아보겠습니다.

scanf() 함수 역시 printf()와 같이 표준 입출력 헤더파일인 stdio.h에 포함되어 있으므로

사용시,


1
#include <stdio.h>

cs


를 추가해줍니다.


scanf() 함수의 프로토타입입니다.


1
2
3
4
int scanf(  
   const char *format [,  
   argument]...   
);  
cs


printf() 함수와 동일하게 형식 필드 문자 format과 선택 인수들이 있습니다.

형식 필드 문자는 printf() 함수의 형식 필드 문자를 참고해주세요. (단 a 문자는 사용할 수 없습니다.)

반환 값 역시 printf() 함수와 동일한 int 형이며, 지정된 필드 수를 반환합니다.


다음은 scanf() 함수의 기본 예제 소스 코드입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
 
int main() {
    int i;
    
    printf("숫자를 입력해 주세요 : ");
 
    scanf("%d"&i);
 
    printf("입력받은 숫자는 %d입니다.\n", i);    
 
    return 0;
}
cs


scanf() 함수의 두번째 인자들은 저장 할 변수의 주소이며, 변수 이름 앞에 & 기호를 꼭 붙여주어야 합니다.

이는 주소값을 의미하며, 해당 자료는 포인터강좌를 참고하세요.




또한 여러 데이터를 한번에 입력받을 수 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
 
int main() {
    int i;
    float f;
    char c;
    char s[100];
 
    printf("정수, 실수, 문자, 문자열 순으로 입력해주세요 : ");
    if(scanf("%d %f %c %s"&i, &f, &c, s) != 4) {
        printf("잘못된 입력입니다.");
    }
    else {
        printf("정수 : %d\n", i);
        printf("실수 : %f\n", f);
        printf("문자 : %c\n", c);
        printf("문자열 : %s\n", s);
    }    
 
    return 0;
}
cs


4개를 입력 받기 때문에 scanf() 함수의 반환값으로 4가 반환되며,

이가 아니 경우(적거나 많은 경우) 잘못된 입력을 출력합니다.

위 설명에서 scanf() 함수의 두번째 인수들의 이름 앞에 & 기호를 붙이라고 했는데요.


하지만 %s에 해당하는 인수는 &s가 아닌 그냥 s네요.

이는 char 배열(문자열)의 이름과 관계가 있는데요.

배열의 이름은 배열의 첫번째 원소의 주소와 같습니다.

이에 대한 설명은 배열강좌에 설명되어 있으며, C언어 초급자 분이시면

그냥 문자열 입력받을때는 &기호를 생략한다. 라고 알고 계시면 되겠습니다.


필요에 따라 * 기호를 추가하여 일부 입력을 무시할 수도 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
 
int main() {
    int i;
    
    printf("숫자를 입력해 주세요 : ");
 
    scanf("%*s %d"&i);
 
    printf("입력받은 숫자는 %d입니다.\n", i);    
 
    return 0;
}
cs


첫번째 인수인 %s의 입력을 무시합니다.

이 경우 공백이나 새로운 줄 입력까지의 입력을 무시합니다.




이상 'C 표준 입력함수'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

메인 페이지로 이동하시면 더 많은 자료를 볼 수 있습니다.



'C, C++' 카테고리의 다른 글

C언어 변수 이름이 숫자로 시작할 수 없는 이유  (0) 2018.11.13
C 정적(static) 변수  (0) 2018.10.29
C 변수 선언 및 키워드  (0) 2018.10.25
C 표준 출력 함수 printf()  (0) 2018.10.22
C++ 가상 함수(Virtual Function)  (8) 2018.10.19
C++ 연산자 오버로딩  (2) 2018.10.12
C++ 함수 오버로딩  (0) 2018.10.11
C/C++ 메모리 동적할당  (0) 2018.10.11



안녕하세요 열코입니다.

이번 시간에는 C언어 표준 출력 함수인 printf() 함수에 대해 알아보겠습니다.

printf() 함수는 stdio.h 헤더파일에 정의되어 있으며,

사용하기 위해서는

1
#include <stdio.h>
cs

코드를 추가하여 사용할 수 있습니다.


☞ 함수 프로토타입

printf() 함수의 프로토타입은 다음과 같습니다.

1
int printfconst char *format, [argument]... );
cs

반환값은 int형이며, 출력하는 문자의 개수를 반환합니다.


첫번째 인수값으로 형식 필드 문자를 넘겨줍니다.

형식 필드 문자는 다음과 같습니다.


 형식

 인수

 출력

 %c

 문자

 단일 바이트 문자

 %d

 정수

 부호 있는 10진수 정수

 %o

 정수

 부호 없는 8진수 정수

 %u

 정수

 부호 없는 10진수 정수

 %x

 정수

 부호 없는 16진수 정수

 %e

 부동 소수점

 부호 있는 부동 소수점

 %f

 부동 소수점

 부호 있는 부동 소수점

 %a

 부동 소수점

 부호 있는 16진수 부동 소수점
 %p 포인터 유형

 16진수 주소

 %s

 문자열

 문자열

 %lf

 부동 소수점

 부호 있는 (long) double


예제 코드입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
 
int main() {
    int a = 123;
    int *= &a;
    long c = 456;
    double d = 10.123;
 
    printf("%c\n"'y'); // y 
    printf("%d\n", a); // 123 
    printf("%o\n", a); // 173
    printf("%u\n", a); // 123
    printf("%x\n", a); // 7b
    printf("%e\n", d); // 1.012300e+01
    printf("%f\n", d); // 10.123000
    printf("%a\n", d); // 0x1.43ef9bd22d0e5p+3
    printf("%p\n", p); // 001FF8FC
    printf("%s\n""yeolco"); // yeolco
    printf("%lf\n", d); // 10.123000
 
    return 0;
}
cs


첫번째 인수인 형식 필드 문자는 생략 가능하며,

만약 첫번째 인수를 생략하지 않으면 두번째 인수는 반드시 형식에 맞는 인수를 사용해야 합니다.

\n은 개행(줄바꿈)을 의미합니다.


또한 첫번째 인수인 형식 필드 문자를 다양한 조합을 통해 사용할 수 있습니다.


% (공백) : 음수인 경우 - 부호를 출력

%+ : 양수일 경우 + 부호, 음수일 경우 - 부호 출력

%.(숫자) : 지정한 숫자만큼 소숫점 자리 출력

%(숫자) : 지정한 숫자만큼 폭을 지정하여 출력



예제 코드

1
2
3
4
5
6
7
#include <stdio.h>
 
int main() {
    double d = 3.14159;
 
    printf("%10.2lf", d);
}
cs


위 코드의 출력 결과는 다음과 같습니다.


      3.14 (왼쪽 공백 6칸)


%뒤 숫자 10은 왼쪽으로 부터 공백 10칸을 의미하며,

.2의 의미는 소수점 2자리 수까지(반올림하여) 출력한다는 의미입니다.


이상 'C 표준 출력 함수'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.





'C, C++' 카테고리의 다른 글

C언어 변수 이름이 숫자로 시작할 수 없는 이유  (0) 2018.11.13
C 정적(static) 변수  (0) 2018.10.29
C 변수 선언 및 키워드  (0) 2018.10.25
C 표준 입력 함수 scanf  (0) 2018.10.23
C++ 가상 함수(Virtual Function)  (8) 2018.10.19
C++ 연산자 오버로딩  (2) 2018.10.12
C++ 함수 오버로딩  (0) 2018.10.11
C/C++ 메모리 동적할당  (0) 2018.10.11

to Top