Today
Total
Recent Posts
Link
반응형
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
관리 메뉴

아임'준

[C언어 기초] 자료형, 아스키코드, 상수, 변수, printf와 scanf 본문

[C]/[C : 개념]

[C언어 기초] 자료형, 아스키코드, 상수, 변수, printf와 scanf

아임'준 2020. 12. 19. 03:30
반응형

C언어 / 자료형 / 기본입출력

 

지난 시간에는 C언어를 시작하기 위한 기본 설정에 대해서 공부해보았다.

 

오늘은 본격적으로 소스파일을 작성하고 실행해보는 작업을 할 것이다.

 

우선 들어가기 전에 필수적으로 알아야 할 것이 있다.

#include <stdio.h>

int main() {
	
    printf("Hello World!\n");
    return 0;

}

코딩을 배우기로 마음먹은 사람이면 누구나 위와 같은 짧은 코드를 본 적이 있을 것이다.

이 소스 코드를 보면서 우리가 앞으로 크게 기억해야 할 것은 두 가지가 있다.

첫째는 바로 최상단의 #include <stdio.h>이며 두번째는 3번째 줄의 main이다.

 


#include <stdio.h>는 C언어를 사용할 때 거의 99% 사용하게 되는 문장이다.

#include는 include라는 영어 뜻에서 알 수 있듯이 어떤것을 포함하라는 뜻이고 <> 안에 들어있는 stdio.h 는 포함이 되는 대상이다.

 

그럼 stdio.h는 무엇일까? 

stdio를 잘못 외워서 studio라고 외우는 사람들이 있는데 stdio를 더 잘 외우기 위해서 stdio의 뜻을 살펴보면 이는 'standard input output'이라는 뜻이다 이 뜻을 알고 외우려고 한다면 더 잘 외울 수 있을 것이다. 뒤에 붙어있는 .h는 헤더 파일의 확장자를 의미한다.

 

헤더 파일을 설명하기 위해서는 함수라는 것을 먼저 설명해야 할 것 같다. 우리가 일반적으로 아는 함수란 수학에서 f(x) 등으로 표현되는 함수이다. 프로그램에서 함수는 프로그램을 구성하는 요소들이라고 할 수 있다. 어떤 기능을 수행하는 함수에 대해서 이 함수들이 모여 우리가 사용하는 하나의 프로그램이 완성되는 것이다. 여기서 말하는 어떤 기능이란 예를 들어 어떤 문장을 출력하거나 어떤 단어가 같은지 다른지 등을 비교할 수 있는 등의 무수히 많은 기능들을 말한다. 우리 또한 이 프로그램을 구성하는 함수를 만들 것이고 여기에 또 여러 함수들이 쓰일 것이다.

 

그럼 이제 돌아와서 헤더파일을 포함한다는 것은 무슨 뜻일까?

C언어에는 많은 내장 함수들이 존재한다. 간단히 말해서 이 헤더 파일 안에는 그러한 함수들이 존재한다. 자주 쓰이는 함수들을 포함하는 이 헤더 파일을 포함시킴(include)을 통해서 그 함수를 사용할 수 있게끔 하는 것이다. stdio.h 외에도 stdlib(standard library), time 등을 사용하는 모습을 종종 볼 수 있을 것이며 우리가 만든 함수들을 포함하는 헤더 파일을 만들 수도 있다.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

 

stdio.h 의 경우 표준 입출력과 관련된 함수들을 포함하는 헤더 파일이며 입력을 받거나 눈에 보이는 어떤 출력을 위해서 우리는 이 stdio.h를 필수로 포함시켜줘야 한다. 그래서 #include <stido.h>는 앞으로 우리가 작성할 코드에 대해서 거의 100% 맨 앞에 적혀있을 것이다.

 

 

다음은 main 이 무엇을 의미하는지 알아야한다. main 또한 앞서 말한 함수이다.

main 이라는 단어에서 알 수 있듯이 가장 주된 함수인데 컴퓨터는 이 main 함수에서 모든 것을 시작한다. 우리가 컴퓨터에게 시키고 싶은 내용을 main 함수에 집어넣으면 main 함수를 읽은 컴퓨터가 그에 맞게 명령을 수행하는 것이다. main 함수는 모든 함수의 시작점이며 그렇기에 main 함수는 두 개일 수 없다. 또 함수의 몸체를 감싸줄 때는 중괄호 {}를 사용해야 하며 int로 시작되는 main에는 return 0;를 내부에 적어줘야 한다. 또한 이는 앞으로도 가장 중요한 내용 중 하나일 것인데 한 구문이 끝날 때 ; (세미콜론)을 꼭 붙여줘야 한다. 세미콜론을 붙이지 않을 경우 컴파일 에러가 나게 된다.

 

대충 뭐 이런거...

 

지금은 이정도만 알아두면 된다. 일단 코드를 작성한다면 아래와 같은 코드는 기본적으로 꼭 있어야 한다고만 인지하면 된다. 이후 줄 그은건 지금은 무시해도 된다. 그렇다면 앞에 붙어있는 int는 무슨 뜻일까? int는 이 함수가 반환해야 할 값을 정수형이라고 알려주는 것이며 main 옆 ()는 매개 인자를 넣는 자리이다. main 안 return 0;는 함수가 0이라는 정수를 반환한다는 뜻이다.

 

#include <stdio.h>

int main() {
	return 0;
}

얘는 꼭 외워두고 쓰자.

 

 

 

그럼 이제 자료형에 대해서 설명하겠다

 

자료형이란 이 데이터가 어떤 형식의 데이터인지 그 종류를 알려주는 것이다.  정수 자료형, 실수 자료형, 문자 자료형이 있으며 정말 많은 자료형이 있지만 간단하게 가장 많이 쓰는 대표적인 것들만 설명하고 넘어갈 것이다.

 

아래는 정수 자료형을 표로 나타낸 것이다. 참고로 1바이트는 8비트이다.

각 자료형마다 크기가 다르기 때문에 나타내는 범위가 모두 다르며 unsigned와 signed라는 것이 눈에 보일텐데 unsigned는 부호 비트인 sign 비트를 가지지 못하기 때문에 양수밖에 값이 존재하지 않는다. 아래의 표를 절대 모두 외울 필요 없으며 나중에 필요할 때 다시 보면 된다. 본인이 쓰는 것은 4바이트 짜리 int형이며 가끔 아주 긴 숫자에 대해서 처리를 해야 할 때는 long long int를 사용하곤 했다. 시작한 지 얼마 안 됐다면 int라는 정수 자료형만 외우면 된다. 

자료형 크기 범위
char
signed char
1바이트 -128~127
unsigned char 1바이트 0~255
short
short int
2바이트 -32,768~32,767
unsigned short
unsigned short int
2바이트 0~65,535
int
signed int
4바이트 -2,147,483,648~ 2,147,483,647
unsigned
unsigned int
4바이트 0~4,294,967,295
long
long int
signed long
signed long int
4바이트 -2,147,483,648~ 2,147,483,647
unsigned long
unsigned long int
4바이트 0~4,294,967,295
long long
long long int
signed long long
signed long long int
8바이트 -9,223,372,036,854,775,808~
9,223,372,036,854,775,807
unsigned long long
unsigned long long int
8바이트 0~18,446,744,073,709,551,615

 

 

다음은 실수 자료형이다. 마찬가지로 자료형에 따라 범위가 다르다. 본인이 가장 많이 쓰는 것은 double이다. 

자료형 크기 범위 유효자릿수
float 4바이트 1.175494e-38~3.402823e+38 7
double 8바이트 2.225074e-308~1.797693e+308 16
long
double
8바이트 2.225074e-308~1.797693e+308 16

 

 

 

마지막으로 문자 자료형이다

자료형 크기 범위 비고
char
signed char
1바이트 -128~127 문자 저장
unsigned char 1바이트 0~255 바이트 단위 데이터 저장

char에 문자를 저장하면 문자의 ASCII 코드값이 저장된다. 아스키 코드는 아래 표와 같이 값을 가진다. 이 뜻에 대해서는 후에 printf 부분에서 설명하도록 하겠다.

아스키 코드표

마찬가지로 해당 아스키 코드아스키코드 표를 외울 필요는 없다. 굳이 외우고 싶다면 우리가 잘 쓰는 알파벳의 시작인 대문자 A가 아스키코드값으로 65이며 소문자 a는 아스키코드값으로 97이라는 것을 알면 그 이후는 순서대로 같다는 것이다.

 

이제 이렇게 배운 자료형들로 상수와 변수를 선언하고 쓸 수 있다. 변수는 쉽게 말해 변하는 수이다. 어떤 값을 계속 저장하고 그 저장된 값들이 바뀔 수 있는 것이다. 상수는 그와 반대로 한번 정해지면 바뀌지 않는 값을 말한다. 그럼 이러한 작업들을 어떻게 처리해주는지 예를 들어서 설명하도록 하겠다.

#include <stdio.h>

int main() {
	
    int a; //a라는 이름을 가진 int형 변수 선언
    a = 4; //변수 a에 4라는 값을 저장
    
    int b = 7; //b라는 이름을 가진 int형 변수를 선언함과 동시에 7이라는 값을 변수 b 안에 저장
    b = 8; //b는 7이라는 값을 가지고 있었으나 이제 b에 8을 저장할 것임
    
    const int c = 1000; //상수 c를 1000으로 선언
    c = 1; //이 부분에서 에러가 날 것임
    
    char key = 'a'; //문자 a를 key 에 저장함
    
    return 0;

}

우선 코드 옆에 적힌 //는 주석이라고 한다. 주석은 주로 남이 코드를 볼 때 이해를 돕기 위해서 달아놓는 것으로 // 이후에 적은 글은 코드에 아무 영향을 주지 않는다. 여러 줄을 주석처리 하기 위해서는 /* ~~(주석처리하고 싶은 내용) ~~ */ 형식으로 여러 줄을 주석 처리할 수 있다.

 

다시 상수와 변수에 대한 내용으로 돌아와서 위의 예시 코드를 보면 5번째 줄에서 이름을 a로 하는 변수를 int형으로 선언했음을 알 수 있다. 그리고 그 밑에 a=4; 라는 구문을 통해 변수 a에 4라는 값을 저장했다. 이후에 배우겠지만 6번째 라인 이후에 a라는 값을 출력하라는 코드를 작성하면 4라는 값을 뱉을 것이다.

그럼 이제 8번째 라인 b라는 변수에 주목해보자. a와 같이 값을 나중에 저장해도 되지만 b는 선언과 동시에 7이라는 값을 저장해주었다. 8번째 라인까지만 적고 바로 b의 값을 출력하면 7이라는 값이 나올 것이다. 하지만 9번째 라인의 b=8 이후에 b의 값을 출력하라고 한다면 b의 값은 이전 값인 7이 아니라 8로 바뀌어 8이라는 값을 출력할 것이다.

이제 c라는 이름으로 선언된 것을 보자 c는 다른 것들과 다르게 앞에 const라는 단어가 붙어있다. constant라는 영어의 뜻을 생각해볼 때 지금 c는 바뀌지 않는 '상수'로 선언된 것이다. 이 이후에 12번째 라인처럼 c에 저장된 값을 바꾸려고 한다면 컴파일 에러가 날 것이다. 그럴 필요는 없지만 만약 저 소스코드를 실행하려고 했다면 12번째 라인의 c=1;이라는 구문을 지워주면 실행될 것이다.

 

문자형과 실수형도 비슷한 식이다.

위의 코드에서 a라는 문자를 key라는 문자형 변수에 저장했는데 char를 사용했으니 이는 ASCII 코드의 값인 97을 저장하고 있을 것이다.

 

 

 

printf()

printf는 출력을 위한 함수이다. 맨 앞에 언급됐던 printf("Hello World!\n");를 기억하는가? C언어에서 " "안에 있는 것을 문자열이라 하는데 printf() 안의 문자열인 Hello World를 출력하라는 뜻이다. 이를 올바르게 출력했다면 출력 창에 Hello World!가 나타나는 것을 볼 수 있다.

그런데 \n은 왜 출력되지 않았는지 의문을 가지는 사람들도 있을 것이다. 이는 제어문자라고 하는 특별한 문자이며 출력에 나타나지 않는다. \n은 개행 문자이며 하며 줄 바꿈(주로 enter로 사용되는)을 위해 사용한다.

 

이제 서식 지정자라는 것을 알아보도록 하겠다.

printf가 단순 우리가 아는 문장들만 출력할 수 있는 것이라면 사용에 제약이 굉장히 많을 것이다. 예를 들어 아까 내가 a에 저장한 4라는 값을 출력하고 싶은데 이걸 어떻게 해야 해??라는 등의 의문을 가질 수 있다. 서식 지정자에는 종류가 있는데 위에 Hello World를 예시로 들었으니 문자열 서식 지정자부터 시작하도록 하겠다. 문자열 서식 지정자는 %s로 표기한다.

 

printf("%s\n", "Hello World");

다음과 같은 구문이 main 함수 안에 들어있다면 이는 이런 식으로 해석할 수 있다. %s 라고 적힌 자리에 콤마(,) 뒤의 문자열인 "Hello World"를 출력하라는 뜻이다. 만약 출력하고 싶은 문자열이 두 개일 경우

printf("%s is %s", "June", "Student");

위와 같이 입력하면 뒤의 문자열들이 순서대로 들어가서

June is Student

라는 값이 올바르게 나올 것이다.

 

아까 설명한 자료형들로 돌아와서 정수형 서식 지정자는 char, short, int에 대해서는 %d로 표현하고 long이 하나 붙을 때마다 d앞에 l을 붙여 %ld %lld로 사용하면 된다. 실수형 서식 지정자는 float은 %f double이 %lf longdouble이 %Lf이며 문자형 서식 지정자는 문자는 %c 문자열은 %s 라고 생각하면 된다. 문자와 문자열에 대해서 간단히 설명하면 문자는 '한 글자'이고 문자열은 그 이상인 나머지이다. 본인이 주로 쓰는 것은 %d %lf %c %s 정도이다. 참고로 실수형 %lf 같은 경우 3.5의 값을 저장했음에도 출력하면 3.500000이라는 값이 나오는데 이를 소수점 둘째 자리까지 표현하고 싶을 시 %. 2lf라고 표현해주면 3.50이라는 값을 출력받을 수 있다.

 

아까 사용했던 예제를 불러와서 다음과 같이 수정할 경우

#include <stdio.h>

int main() {
	
    int a; //a라는 이름을 가진 int형 변수 선언
    a = 4; //변수 a에 4라는 값을 저장
    printf("a is %d",a);
    
    int b = 7; //b라는 이름을 가진 int형 변수를 선언함과 동시에 7이라는 값을 변수 b 안에 저장
    printf("first b is %d\n",b);
    
    b = 8; //b는 7이라는 값을 가지고 있었으나 이제 b에 8을 저장할 것임
    printf("second b is %d\n",b);
    
    const int c = 1000; //상수 c를 1000으로 선언
    printf("c is %d\n",c);
    
    char key = 'a'; //문자 a를 key 에 저장함
    printf("my key is %c and its ASCII value is %d\n",key,key); //한번은 문자형으로 출력 한번은 정수형으로 출력
    
    printf("%d - %d = %d\n", 5,3,2);
    printf("%f and %.2f",3.5,3.5);
    
    return 0;

}

위 코드를 실행한 결과는

a is 4
first b is 7
second b is 8
c is 1000
my key is a and its ASCII value is 97
5 - 3 = 2
3.500000 and 3.50

다음과 같을 것이다. 문자형 변수 key 에 저장돼 있던 글자가 a이고 a의 아스키코드 값이 97이었다는 것을 기억하면 key라는 값을 %c로 했을 때 a가 나오고 %d로 했을 때 97이 나온 것을 이해할 수 있을 것이다.

 

 

scanf()

scanf는 쉽게 말해 어떤 값을 키보드로 입력받아 저장하는 함수라고 생각하면 된다. 저장할 때는 서식 지정자를 사용하며 다음과 같이 쓸 수 있다.

#include <stdio.h>

int main() {
    
    int input;
    printf("아무 값이나 입력해주세요");
    scanf("%d",&input);
    
    printf("%d",input);
    
    return 0;

}

이를 실행하면 먼저 "아무 값이나 입력해주세요" 라는 문구가 화면에 뜰 것이고 아무 정수나 입력하면 입력한 정수가 화면에 다시 출력될 것이다. scanf를 사용할 때 주의할 점이 있는데 printf와는 다르게 뒤에 &를 붙였다. &를 붙이면 해당 변수가 저장된 위치(주소)를 가리키는데 지금 이해하기 어려우니 input 앞에 &이 붙었으면 input이라는 값을 저장된 위치에 제가 입력한 정수를 저장해주세요 라는 뜻으로 이해하면 된다. scanf가 오류가 난다면(아마 visual studio) scanf_s를 사용하기를 바란다.

 

scanf 또한 printf처럼 한번에 여러 개를 입력받을 수 있으며 입력받는 변수 개수만 잘 맞춰주면 된다.

int a,b; //이렇게 한번에 ,으로 선언 가능
scanf("%d %d",&a, &b); // 이럴 경우 35 40 이렇게 입력하면 a에 35 b에 40이 저장됨

 

실행 예시: (본인은 맥북)

다음 시간에는 연산자를 공부해보도록 하겠다.

질문, 오타 지적, 오류 지적 등은 댓글로 환영합니다.

Comments