본문 바로가기

C언어

C 언어 코딩 도장 3

문자 자료형 사용하기

C언어는 정수 자료형 char에 문자 한 개를 저장

char 자료형은 문자를 바로 저장하지 않고 문자에 해당하는 정숫값을 저장

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

ASCII 코드

 문자를 정수로 나타내는 규칙

 

문자를 ' '(작은따옴표)로 묶어서 표현

char c1 = 'a';

 

작은따옴표는 문자 두 개 이상을 묶을 수 없음

char c1 = 'Hello, world!'; //작은 따옴표는 문자 하나만 묶을 수 있으므로 잘못된 사용법!

 

+) 작은따옴표로는 문자 하나만 묶을 수 있지만 정수 자료형에 2바이트 값을 저장할 때는 문자 두 개를 작은 따옴표로 묶기도 한다.

unsigned short magic = 'BA';

 

문자 변수 선언하기

#include <stdio.h>

int main()
{
    char c1 = 'a';
    char c2 = 'b';

    //char를 %c로 출력하면 문자가 출력되고, %d로 출력하면 정숫값이 출력됨
    printf("%c, %d\n", c1, c1); //a의 ASCII 코드값은 97
    printf("%c, %d\n", c2, c2); //b의 ASCII 코드값은 98

    return 0;
}

printf 함수로 char 변수에 저장된 값을 문자로 출력할 때는 %c를 사용하고, %d로 출력하면 char 변수에 저장된 정숫값인 ASCII 코드 값이 출력된다.

 

작은따옴표로 문자를 넣지 않고 바로 정수를 넣어도 된다.

#include <stdio.h>

int main()
{
    char c1 = 97;
    char c2 = 98;

    printf("%c, %d\n", c1, c1);
    printf("%c, %d\n", c2, c2);

    return 0;
}

∴ 정수 97과 문자 a는 같다.

printf 함수에서 서식 지정자를 어떻게 지정하느냐에 따라서 다르게 보이는 것이다.

 

ASCII 코드 값 16진수를 이용해 어떻게 출력되는지 알아보자.

#include <stdio.h>

int main()
{
    char c1 = 0x61;
    char c2 = 0x62;

    printf("%c, %d, 0x%x\n", c1, c1, c1);
    printf("%c, %d, 0x%x\n", c2, c2, c2);

    return 0;
}

printf에서 16진수를 출력하려면 서식지정자 %x를 사용한다. 여기서 %x로는 16진수의 숫자만 출력될 때는 10진수와 구분하기 어려우므로 앞에 0x를 붙여주어 10진수와 구별해줄 수 있도록 한다. (16진수의 hexadeciaml에서 hex의 x를 사용!)

 

※ 문자 자료형에 숫자를 저장한다 하더라도, 문자 '0'과 숫자 0은 다르다!

#include <stdio.h>

int main()
{
    char c1 = '0';
    char c2 = 0;

    printf("%c, %d\n", c1, c1);
    printf("%c, %d\n", c2, c2);

    return 0;
}

작은 따옴표로 감싼 숫자 0을 저장하면, 숫자라고 하더라도 문자 상태로 출력된다. printf에서 %c로 출력하면 0, %d로 출력하면 문자 0의 ASCII 코드 값이 48이 나오지만, 숫자 0을 저장하면, %c로 출력했을 때 아무것도 출력하지 않는다. 왜냐하면, ASCII 코드 0은 NULL을 의미하기 때문에, 아무 것도 들어있지 않은 상태이다.

 

따라서 printf에서 %d로 출력했을 때 '0'과 0은 전혀 다른 값이라는 것을 알 수 있다.

 

문자로 연산하기

문자는 ASCII 코드 규칙에 의해 정수로 저장되기 때문에, 정수처럼 덧셈, 뺄셈 등을 할 수 있다.

#include <stdio.h>

int main()
{
    printf("%c %d\n", 'a' + 1, 'a' + 1);

    printf("%c %d\n", 97 + 1, 97 + 1);

    return 0;
}

'a' + 1과 같이 작은 따옴표로 묶은 문자는 정수를 더하거나 뺄 수 있다. 'a'의 ASCII 코드값이 97이기 때문에 98에 해당하는 문자 b가 출력된다.

 

#include <stdio.h>

int main()
{
    char c1 = 'a';

    printf("%c %d\n", c1 + 1, c1 + 1);

    printf("%c %d\n", 97 + 1, 97 + 1);

    return 0;
}

char 변수에 문자를 넣고 변수를 더하거나 빼도 결과는 같다.

 

제어 문자 사용하기

문자 자료형에는 숫자, 알파벳 이외에 제어 문자도 저장할 수 있다.

#include <stdio.h>

int main()
{
    char c1 = 'a';
    char c2 = 'b';
    char linefeed = '\n';

    printf("%c%c%c", c1, linefeed, c2);

    return 0;
}

작은 따옴표로 묶어서 제어문자를 넣고, printf에서 %c로 출력하면 해당 제어문자가 작동한다.

10진수 16진수 문자 표기법 설명
10 0x0A LF \n 개행, 라인 피드(Line Feed), 새 줄(new line), 줄바꿈
13 0x0D CR \r 복귀, 캐리지 리턴(Carriage Return), 줄의 끝에서 시작 위치로 되돌아감
9 0x09 TAB \t 수평 탭(horizontal tab)
더보기

텍스트 파일을 저장할 때 줄바꿈 규칙

  • Windows : CR, LF
  • 유닉스, 리눅스, OS X  : LF
  • Mac OS 9 : CR

제어 문자의 ASCII 코드 출력하기

#include <stdio.h>

int main()
{
    char linefeed = '\n';

    printf("%d 0x%x\n", linefeed, linefeed);

    return 0;
}

제어 문자라고 하더라도 printf 함수에서 %d나 %x로 출력하면 변수에 들어있는 정수가 바로 출력된다.

 

ASCII 코드를 전부 기억할 필요는 없지만, C 언어 문자는 ASCII 코드로 저장된다 정도는 기억해야 한다.

 

9.4 Quiz 완료

#include <stdio.h>

int main()
{
	char c1 = '\t';
    
    printf("Hello");
    printf("%c", c1);
    printf("world"\n);
    
    return 0;
}

#include <stdio.h>

int main()
{
	char c1 = 2;
    char c2 = 5;
    
    printf("%c\n", c1 + 48);
    printf("%c\n", c2 + 48);
    
   	return 0;
}

9.7 심사문제 완료

#include <stdio.h>

int main()
{
    char c1;
    char c2;
    char c3;

    c1 = '\t';
    c2 = '\n';
    c3 = '\t';

    printf("Hello%cworld%cHello%cworld\n", c1, c2, c3);

    return 0;
}

▲ 정답으로 제출한 코드

9.8 심사문제 완료

#include <stdio.h>

int main()
{
    char c1 = 'a';

    printf("%c\n", c1 - 32);

    return 0;
}

▲ 정답으로 제출한 코드

 

상수 사용하기

상수 = 변하지 않는 값(constant)

프로그램을 만들 때 변수에 저장된 값을 의도하지 않게 바꿀 가능성이 있다.

상수는 값이 의도하지 않게 바뀌는 것을 방지하기 위해 사용한다.

예) 거리 단위 변환

값을 바꾸는 것을 방지하기 위해 사용하며 코드의 의도를 명확하게 만들 수 있다.

상수와 리터럴의 차이

리터럴 - 값 그 자체

상수 - 변수처럼 리터럴이 저장된 공간

변수와 상수의 차이

변수 - 한 번 선언하면 값을 계속 바꿀 수 있음

상수 - 처음 선언할 때만 값을 할당할 수 있으며, 그 다음부터는 값을 바꿀 수 없음

리터럴 사용하기

#include <stdio.h>

int main()
{
    printf("%d\n", 10);             // 10 : 정수 리터럴
    printf("%f\n", 0.1f);           // 0.100000 : 실수 리터럴
    printf("%c\n", 'a');            // a : 문자 리터럴
    printf("%s\n", "Hello, world!");// Hello, world! : 문자열 리터럴

    return 0;
}

정수 리터럴 사용하기

#include <stdio.h>

int main()
{
	printf("%d\n", 19);
    printf("0%o\n", 017);
    printf("0x%x\n", 0x1F);
    
    return 0;
}

10진수는 숫자 그대로 표기하고

8진수는 숫자 앞에 0을 붙이고 (octal number, %o)

16진수는 숫자 앞에 0x를 붙인다.

실수 리터럴 사용하기

#include <stdio.h>

int main()
{
    printf("%f\n", 0.1f);
    printf("%f\n", 0.1F);
    printf("%f\n", 1.0e-5f);
    printf("%f\n", 1.0E-5F);

    return 0;
}

실수 리터럴이 float 크기라면, f 또는 F를 붙이고, long double 크기라면, l 또는 L를 붙이고, 지수 표기법은 e 또는 E와 지수를 표기한다.

상수 사용하기

const 자료형 상수이름 = 값;

#include <stdio.h>

int main()
{
    const int con1 = 1;
    const float con2 = 0.1f;
    const char con3 = 'a';

    printf("%d %f %c\n", con1, con2, con3);

    return 0;
}

 

 

상수는 const를 붙이는 것 말고는 변수와 선언하는 방법이 같다.

상수는 선언과 동시에 값을 초기화해줘야 한다. 선언만 해주고 초기화해주지 않으면 컴파일 오류가 발생한다.

 

const를 붙여서 상수가 된 상태에서 값을 할당해보기

#include <stdio.h>

int main()
{
    const int con1 = 1;

    con1 = 2;

    printf("%d\n", con1);

    return 0;
}

컴파일 결과 : const_assign_error.c(7,5): error C2166: l-value가 const 개체를 지정합니다.

const를 붙여서 상수가 되면 더이상 값을 할당할 수 없으며, 완전히 고정된 상태이다.

만약 다른 값을 사용하려면 새 상수를 선언해야 한다.

더보기

const의 위치

const는 자료형 앞에 붙여도 되고 자료형 뒤에 붙여도 된다.

int const con1 = 1;
float const con2 = 0.1f;
char const con3 = 'a';

정수 리터럴 접미사 사용하기

#include <stdio.h>

int main()
{
    printf("%ld\n", -10L);                       //long 크기의 정수 리터럴
    printf("%lld\n", -1234567890123456789LL);    //long long 크기의 정수 리터럴

    printf("%u\n", 10U);                        //unsigned int 크기의 정수 리터럴
    printf("%lu\n", 1234567890UL);              //unsigned long 크기의 정수 리터럴

    printf("%lu\n", 10UL);                      //unsigned long 크기의 정수 리터럴
    printf("%llu\n", 1234567890123456789ULL);    //unsigned long long 크기의 정수 리터럴

    return 0;
}

정수는 정수 그대로를 사용한다.

정수 리터럴 접미사(suffix)를 사용하면 크기를 명시적으로 표기할 수 있다.

접미사 자료형
생략 int
l, L long
u, U unsigned int
ul, UL unsigned long
ll, LL long long
ull, ULL unsigned long long

주의할 점 : 접미사와 자료형의 크기가 같아야한다.

 

10진수 뿐만 아니라 8진수와 16진수에도 접미사를 사용할 수 있다.

#include <stdio.h>

int main()
{
    printf("0%lo\n", 017L);             // long 크기의 8진 정수 리터럴
    printf("0%lo\n", 017UL);            // unsigned long 크기의 8진 정수 리터럴
    printf("0x%lX\n", 0x7FFFFFL);       // long 크기의 16진 정수 리터럴
    printf("0x%lX\n", 0xFFFFFFFFUL);    // unsigned long 크기의 16진 정수 리터럴

    return 0;
}

서식 지정자에서 %o와 %x에는 u를 붙이지 않는다. %u와 %o, %x는 동급이기 때문에 같이 쓸 수 없기 때문이다.

실수 리터럴 접미사 사용하기

실수 리터럴에 접미사를 사용하여 크기 지정해보기

#include <stdio.h>

int main()
{
	printf("%f\n", 0.1f);		// 0.100000 : float 크기의 실수 리터럴
    printf("%f\n", 0.1F);		// 0.100000 : float 크기의 실수 리터럴
    printf("%f\n", 0.1);		// 0.100000 : double 크기의 실수 리터럴
    printf("%Lf\n", 0.1l);		// 0.100000 : long double 크기의 실수 리터럴
    printf("%LF\n", 0.1L);		// 0.100000 : long double 크기의 실수 리터럴
    
    printf("%f\n", 1.0e-5f);	// 0.000010 : float 크기의 실수 리터럴
    printf("%f\n", 1.0e-5F);	// 0.000010 : float 크기의 실수 리터럴
    printf("%f\n", 1.0e-5);		// 0.000010 : double 크기의 실수 리터럴
    printf("%Lf\n", 1.0e-5l);	// 0.000010 : long double 크기의 실수 리터럴
    printf("%Lf\n", 1.0e-5L);	// 0.000010 : long double 크기의 실수 리터럴
    
    return 0;
}

 

접미사 자료형
f, F float
생략 double
l, L long double

 

상수는 값을 변경할 수 없다는 점, 정수나 실수 뒤에 붙은 문자는 크기를 나타내는 접미사라는 점만 기억하면 된다.

 

10.5 Quiz 완료

#include <stdio.h>

int main()
{
    printf("H%cllo, %s %d %Le \n", 'e', "world!", 8, 4.9e-302L);

    return 0;
}

#include <stdio.h>

int main()
{
    const unsigned long long con1 = 10ULL;
    const float con2 = 3.2f;
    const char con3 = 't';

    printf("%llu %f %c\n", con1, con2, con3);

    return 0;
}

10.8 심사문제 완료

076, -2147483647LL, 4.528172L

▲ 정답으로 제출한 코드

10.9 심사문제 완료

long double con1 = -2.225074e-308L

▲ 정답으로 제출한 코드

입력 값을 변수에 저장하기

정수 입력받기

Windows나 macOS 등의 운영체제는 마우스나 키보드로 입력을 받음

C 언어를 배울 때는 콘솔에서 키보드로 글자만 입출력

명령 프롬프트에서 키보드로 명령을 입력하는 게 표준 입력, 명령 프롬프트에서 명령의 결과가 글자로 표시되는 게 표준 출력이다.

콘솔에 입력하는 방식 = 표준 입력(standard input, stdin)

콘솔에 출력하는 방식 = 표준 출력(standard output, stdout)

scanf(서식, 변수의 주소)

표준 입력으로 사용자의 입력을 받는 함수

stdio.h 헤더 파일에 선언되어 있음

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
    int num1;

    printf("정수를 입력하세요: ");
    scanf("%d", &num1);

    printf("%d\n", num1);

    return 0;
}

입력한 값이 그대로 출력된다.

scanf 함수는 표준 입력을 받아서 변수에 값을 저장하는 함수

scanf 함수에서 첫 번째 인수는 서식 지정자를 넣고, 두 번째 인수는 입력값을 저장할 변수를 넣는다.

주의할 점!

변수 앖에 &를 넣어야한다.(Unit 63에서 자세히 설명할 예정)

 

#define _CRT_SECURE_NO_WARNINGS

리눅스나 macOS 사용자는 안 넣어도 됨

scanf 함수는 나온지 오래되어 입력값의 길이를 설정할 수 없어 보안에 취약함

∴ visual studio에서는 사용하지 말도록 권고하기 때문에 보안 경고가 일어나 컴파일 에러가 발생함. 그것을 방지하기 위해 위와 같은 명령어를 입력하는 것.

한 번에 정수 두 개 입력받기

값을 두 개 입력받아서 변수 두 개에 저장해보기

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
    int num1, num2;

    printf("정수를 두 개 입력하세요. : ");
    scanf("%d %d", &num1, &num2);

    printf("%d %d\n", num1, num2);

    return 0;
}

scanf 함수에 %d 두 개를 지정하고, 변수도 &num1, &num2 두 개를 지정했다.

입력값 두 개가 각각 num1, num2에 저장된다.

scanf 함수는 printf 함수와 사용 방법이 유사한데, 입력받을 개수만큼 서식 지정자를 넣어주고, 서식 지정자 개수만큼 변수를 넣어주면 된다.

※ & 잊지 말기!!

실수 입력받기

실수를 입력받아 변수에 저장해보기

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
    float num1;

    printf("실수를 입력하세요 : ");
    scanf("%f", &num1);

    printf("%f\n", num1);

    return 0;
}

실수를 입력받기 위해 변수는 float, scanf, printf의 서식 지정자는 %f로 지정한다.

참고로 변수를 double로 지정했다면, scanf, printf에 서식지정자는 %lf로 지정한다. (double은 printf의 서식 지정자로는 %f로 써도 되지만, scanf는 무조건! %lf로 지정해야 한다.)

long double로 지정했다면, 서식 지정자는 %Lf로 지정한다.

문자 입력받기

scanf는 숫자 뿐만 아니라 문자도 입력받을 수 있다.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
    char c1;

    printf("문자열을 입력하세요 : ");
    scanf("%c", &c1);

    printf("%c\n", c1);

    return 0;
}

문자를 입력받을 것이기 때문에 변수는 char로 선언, scanf, printf에 서식 지정자로 %c를 지정해준다.

scanf에 %c를 지정하면 문자 한 개만 저장되기 때문에, 여러 문자를 입력해도 첫 번째 문자를 제외한 나머지는 무시된다.

문자열 입력은 Unit 40에서 설명 예정

 

더보기

getchar로 문자 입력 받기

scanf 함수 대신 getchar 함수를 사용해서 문자를 입력받을 수 있다.

#include <stdio.h>

int main()
{
	char c1 = getchar();
    
    printf("%c\n", c1);
    
    return 0;
}

 

getchar 함수는 표준 입력에서 문자 하나를 입력받은 뒤 결과를 반환한다. 

 

putchar로 문자 하나를 화면에 출력하기

getchar 함수에 대응하는 함수인 putchar로 문자 하나를 화면에 출력할 수 있다.

#include <stdio.h>

int main()
{
	char c1 = 'a';
    
    putchar(c1)
    
    return 0;
}

getchar, putchar 함수 모두 stdio.h 헤더 파일에 선언되어 있다.

11.5 Quiz 완료

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
    int num1;
    int num2;
    int num3;

    printf("정수 세 개를 입력하세요 : ");
    scanf("%d %d %d", &num1, &num2, &num3);

    printf("%d\n", num1);
    printf("%d\n", num2);
    printf("%d\n", num3);

    return 0;
}

11.7 심사문제 완료

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
    int num1;
    float num2;
    char c3;

    scanf("%d %f %c", &num1, &num2, &c3);

    printf("%d\n", num1);
    printf("%f\n", num2);
    printf("%c\n", c3);

    return 0;
}

▲ 정답으로 제출한 코드

 

+) char와 unsigned char의 차이?

char = 문자와 문자열을 표현할 때 사용

unsigned char = 파일이나 네트워크 패킷의 내용을 1바이트 단위로 표현할 때 사용

Windows에서는 unsigned char를 BYTE 자료형으로 정의해서 사용

 

+) printf에서 \를 출력하려면?

printf에서 제어 문자를 사용할 때 \를 사용하며 \ 자체는 출력되지 않는다. \를 그대로 출력하려면 \\처럼 \을 두 번 입력하면 된다.

printf("\\");

 

'C언어' 카테고리의 다른 글

C 언어 코딩 도장 6  (0) 2025.01.13
C 언어 코딩 도장 5  (0) 2025.01.12
C 언어 코딩 도장 4  (1) 2025.01.10
C 언어 코딩 도장 2  (0) 2024.09.02
C 언어 코딩 도장 1  (0) 2024.07.21