7. 숫자 이외의 데이터 타입(char, string, bool)

  • 24 minutes to read

숫자 이외의 데이터 타입인 문자(char), 문자열(char[], char*) 그리고 참(true) 또는 거짓(false) 값을 다뤄보도록 하겠습니다.

> // 숫자 이외의 데이터 타입: bool, char, char[] 등의 키워드로 숫자 이외의 데이터 저장
TIP

char 키워드는 캐릭터, , 중 원하는대로 발음해도 됩니다. 외국 프로그래머와 강사들의 발음을 들어보면 이 세가지 중 하나를 사용합니다. 박용준 강사는 주로 캐릭터로 발음합니다.

1. 문자 데이터 타입 사용하기(char)

문자 데이터 타입 변수는 1 바이트의 공간에 하나의 문자를 저장합니다. 문자형 변수는 char 키워드를 사용하여 선언하고 값을 초기화할 때에는 두개의 작은따옴표로 문자 하나를 묶어줍니다. 즉, 문자 리터럴은 반드시 작은 따옴표로 묶어야 합니다.

문자 하나를 담을 변수를 선언하고 사용하는 미리보기 샘플 코드는 다음과 같습니다.

> char c = 'A';
> c
'A'

char 변수 선언 및 초기화에 대한 내용을 그림으로 표현하면 다음과 같습니다.

그림: 문자 변수 선언 및 초기화

char-varible-init.png

문자 데이터 타입인 char 키워드로 선언된 변수는 문자 하나를 저장하기 위해 사용됩니다. char 데이터 타입은 8비트(1바이트) 저장공간을 차지합니다. 단일 문자는 작은따옴표(')로 묶습니다. char 자료 형에는 여러 개의 문자를 저장할 수 없습니다. 즉, 작은따옴표 안에는 단 하나의 문자만이 들어올 수 있습니다.

char 변수에는 정수 데이터가 들어올 수 있습니다. 정수 데이터를 표현할 때에는 부호 있는 정수일 때에는 char 키워드를 사용하고 부호 없는 정수일 때에는 unsigned char 키워드를 사용합니다.

char 변수가 담을 수 있는 정수의 범위는 다음과 같습니다.

  • char의 범위: -128 ~ 127
  • unsigned char의 범위: 0 ~ 255

2. 문자 변수 선언하기

문자 변수에 문자를 저장하고 출력하는 내용을 살펴보겠습니다.

코드: character_demo.c

// char 키워드: 문자 데이터 타입 변수를 선언할 때 사용 
#include <stdio.h>

int main(void)
{
    char grade = 'A'; // 문자 하나 저장
    char num = -128; // -128 ~ 127 사이의 정수 저장 가능
    unsigned char age = 255; // 0 ~ 255 사이의 정수 저장 가능

    printf("%c\n", grade); // A
    printf("%d\n", num); // -128
    printf("%d\n", age); // 255

    return 0;
}
A
-128
255

char 변수에 'A'와 같이 문자 하나를 작은따옴표로 묶어서 저장했습니다. char 변수는 -128부터 127까지의 정수 데이터도 저장이 가능합니다. unsigned char 변수는 음수를 표현하지 못하지만 양수의 값이 char 보다 두 배 많습니다.

3. 이스케이프 시퀀스 사용하기

앞서도 살펴본 내용인데요. 백슬래시(\) 기호 뒤에 한 문자를 지정하는 것을 "이스케이프 시퀀스"라고 합니다. 백슬래시 기호는 한글 글꼴을 사용할 때에는 원() 기호로 표시되고 영문 글꼴을 사용할 때에는 백슬래시(\, 역슬래시) 기호로 표현됩니다.

이스케이프 시퀀스는 줄 바꿈 문자, 작은따옴표 기호 자체, 탭 이동과 같은 제어 문자를 표현할 때 사용됩니다.

콘솔 창에서 한 줄을 내리는 \n 기호를 사용해보겠습니다.

코드: character_escape_sequence.c

#include <stdio.h>

int main(void)
{
    char ch1 = 'A';
    char ch2 = 'B';
    char newLine = '\n'; // \n: 줄 바꿈 문자
    printf("%c%c%c\n", ch1, newLine, ch2);

    return 0;
}
A
B

'\n'과 같은 이스케이프 시퀀스는 2개의 문자로 표현되지만 실제로는 하나의 문자로 인식합니다.

C 언어에서의 백슬래시(\) 기호

C 언어에서 백슬래시 기호는 이스케이프 시퀀스를 표현하는 특수 기호입니다. 만약, 문자열로 백슬래시 기호 자체를 표현하려면 '\\' 형식으로 백슬래시 기호 두 개를 함께 나열해야 합니다.

char 데이터 타입과 오버플로 문제 해석하기

이 글에서는 char 데이터 타입의 범위를 초과하는 값인 200을 할당했을 때의 예상 출력과 발생하는 문제점을 분석하고, 개선 방안을 제시하겠습니다.

코드 분석

다음은 C 프로그래밍 언어로 작성된 코드입니다:

void main(void)
{
   char c = 200;
   printf("%d", c);
}

예상 출력

  • char 타입은 보통 1바이트(256가지 값)를 사용하며, 부호 있는 char의 경우 -128에서 127까지의 범위를 가집니다. char c = 200;은 이 범위를 초과하기 때문에 오버플로우가 발생합니다.
  • 200을 이진수로 표현하면 11001000입니다. 이것을 부호 있는 8비트 char로 해석하면, 최상위 비트가 부호 비트이므로 음수로 처리됩니다. 이진수 11001000의 2의 보수 값은 -56입니다.

따라서, 이 코드는 -56을 출력할 것으로 예상됩니다.

문제점

  1. 자료형 범위 초과: char로 표현할 수 있는 범위를 넘어서는 값을 할당함으로써 발생하는 오버플로 문제입니다.
  2. 표준 준수 문제: main 함수는 표준 C에서 int 타입을 반환해야 합니다. void main(void)는 일부 컴파일러에서는 허용되지만 표준에서는 권장하지 않습니다.

개선 방안

  • 부호 없는 unsigned char을 사용하면 0에서 255까지의 값을 문제없이 처리할 수 있습니다. 따라서 unsigned char을 사용하면 200이라는 값도 안정적으로 처리됩니다.
  • main 함수의 반환 타입을 int로 변경하고, 프로그램 종료 시 return 0;을 추가하여 C 표준을 준수하도록 합니다.

개선된 코드 예:

int main(void)
{
   unsigned char c = 200;
   printf("%d", c);
   return 0;
}

이 코드는 200을 출력하며 C의 표준을 잘 준수합니다.

결론

charunsigned char의 차이를 이해하고 적절히 사용하는 것은 C 프로그래밍에서 중요합니다. 부호 있는 char의 오버플로를 피하고, 더 넓은 범위의 값을 안전하게 처리하려면 unsigned char의 사용을 고려해야 합니다. 또한, 모든 C 프로그램은 표준에 따라 int main()을 사용하고, 명시적으로 return 값을 제공해야 합니다.

4. 문자열 데이터 타입(char*) 소개

문자열 데이터 타입은 프로그래밍에서 가장 자주 사용되는 타입 중 하나입니다. 문자열 변수를 선언하기 위해 char* 또는 char * 형식을 사용할 수 있으며, 문자열은 반드시 큰따옴표(")로 감싸야 합니다. 여기서 char*는 '포인터'라는 중요한 개념의 일부로, 이는 후에 자세히 다루게 됩니다. 현재는 char*를 사용하여 문자열을 저장할 수 있는 컨테이너를 생성한다는 기본 사실만 이해하면 충분합니다. 문자열을 출력하기 위해서는 printf() 함수 내에서 %s 형식 지정자를 사용합니다.

이제 문자열 변수의 선언, 초기화, 그리고 사용 방법을 보여주는 예시를 살펴보겠습니다.

예제 코드: string_demo.c

#include <stdio.h>

int main(void)
{
    char* message = "안녕하세요."; // 문자열 변수 선언 및 초기화
    printf("%s\n", message); // "안녕하세요." 출력

    message = "반갑습니다."; // 변수 값 변경
    printf("%s\n", message); // "반갑습니다." 출력

    return 0;
}
안녕하세요.
반갑습니다.

문자열은 하나 이상의 문자로 구성되며, 큰따옴표로 묶어서 문자열 변수에 할당합니다. char* 타입을 사용하면 여러 문자를 포함하는 문자열 데이터를 효과적으로 저장하고 사용할 수 있습니다.

5. 문자 배열을 사용한 문자열 저장

C 언어에서 문자열을 다루는 또 다른 방법은 문자 배열을 사용하는 것입니다. C 언어는 별도의 문자열 타입을 기본으로 제공하지 않기 때문에, 문자열을 저장하려면 주로 포인터나 문자 배열을 사용하게 됩니다. 배열에 대한 자세한 설명은 배열과 포인터 단원에서 다루게 되지만, 이번 섹션에서는 문자 배열을 사용해 문자열을 저장하는 방법에 대해 간단히 알아보겠습니다.

예제 코드: string_with_char_array.c

#include <stdio.h>

int main(void)
{
    // 문자 배열을 사용해 문자열 저장
    char s[5] = "Code"; // 문자열을 저장하기 위해 널 종결 문자를 고려하여 배열 크기를 지정

    // %s 형식 지정자를 사용하여 문자열 출력
    printf("%s\n", s); // 문자 배열을 사용해 문자열 출력

    return 0;
}
Code

char s[5]를 선언함으로써, 우리는 최대 네 문자로 구성된 문자열을 저장할 수 있는 공간을 마련하게 됩니다. 중요한 점은, 문자열의 끝을 나타내기 위해 널 종결 문자 '\0'가 자동으로 문자열의 끝에 추가된다는 것입니다. 이는 문자열이 메모리에서 어디서 끝나는지를 나타내는 중요한 신호로 작용합니다. 따라서 실제로 사용할 수 있는 문자의 개수는 배열 길이에서 하나를 뺀 것입니다.

6. 문자열 길이 확인 및 문자 변경

문자열은 연속적으로 이어진 문자들의 집합입니다. 이번 섹션에서는 문자열의 길이를 확인하고, 문자열 내 특정 문자를 변경하는 방법에 대해 알아봅니다.

코드: string.c

#include <stdio.h>

int main(void)
{
    //[1] 문자열 변수 선언과 동시에 초기화 
    char message[] = "C Language";

    //[2] 문자열 출력: %s 서식 지정자 사용
    printf("%s\n", message); // C Language

    //[3] 문자열 길이: sizeof() 연산자 사용
    printf("문자열 길이: %llu\n", sizeof(message)); // 10 + 1

    //[4] 문자열 중에서 문자 하나만 [n - 1] 형태로 출력: 위치는 0번째 숫자부터 시작
    printf("%c\n", message[0]); // C

    //[5] 문자열 중에서 특정 위치에 있는 문자 변경
    message[0] = 'Z'; // 첫 글자를 'Z'로 바꾸기

    //[6] 다시 전체 문자열 출력
    printf("%s\n", message); // Z Language

    return 0;
}
C Language
문자열 길이: 11
C
Z Language
  • [1] 문자열 변수에 문자열을 저장하면 맨 마지막에 눈에 보이지 않게 '\0' 문자 하나가 더 추가됩니다. 이것을 널 종결 문자라고 합니다.

message 변수에는 다음 그림과 같이 문자들이 저장된 형태입니다.

그림: 문자열 변수가 저장된 상태

message-variable.png

  • [2] 문자열을 출력할 때에는 %s 자리 표시자를 사용합니다. %s는 널 종결 문자를 만날 때까지 출력됩니다.

  • [3] 문자열의 길이는 sizeof() 연산자를 사용하여 구할 수 있는데, 널 종결 문자까지 포함하여 문자열의 길이 보다 1이 더 큰 값을 출력합니다.

  • [4] 문자열에서 문자 하나만을 가져올 때에는 [n – 1] 형태를 사용하여 n – 1번째에 위치한 문자를 가져올 수 있습니다.

그림: 문자열 변수의 문자 위치

message-variable-index.png

  • [5] 만약, 문자열에서 특정 위치의 문자를 변경하려면 [n – 1] 번째 위치에 새로운 문자를 할당하면 됩니다.

7. 상수와 변수: 변하는 값과 변하지 않는 값

프로그래밍에서 상수와 변수는 각각 변하지 않는 값과 변하는 값을 저장하는 데 사용됩니다. 상수는 const 키워드를 사용하여 선언하며, 한 번 설정된 값은 프로그램 실행 도중에 변경될 수 없습니다. 반면, 변수는 값을 저장하고 필요에 따라 변경할 수 있는 저장공간입니다. 이제 const를 사용하여 문자열 상수를 선언하는 예제를 살펴보겠습니다. 코드의 문자열은 자유롭게 변경하여 실행해 볼 수 있습니다.

예제 코드: immutable.c

#include <stdio.h>

int main(void)
{
    // 상수: 변하지 않는 값
    const char* name = "백두산";

    // 변수: 변하는 값
    int age = 102;

    // 출력 예: 이름: 백두산, 나이: 102
    printf("이름: %s, 나이: %d\n", name, age);

    return 0;
}
이름: 백두산, 나이: 102

Mutable은 영어로 '변할 수 있는'을 의미하며, Immutable은 '변경할 수 없는'을 뜻합니다. 이러한 개념은 변수(Variable)와 상수(Constant)를 설명할 때 중요하며, 변수는 Mutable(변경 가능), 상수는 Immutable(변경 불가) 속성을 갖습니다. 프로그래밍에서 이 두 용어는 기본적인 지식으로 간주됩니다.

8. 상수를 이용한 실수와 문자열 데이터 저장

이번에는 실수와 문자열 데이터를 상수로 저장하는 방법을 살펴보겠습니다. 상수는 한 번 값을 지정하면 프로그램 실행 중에 그 값을 변경할 수 없는 변수입니다. 이 특징은 프로그램에서 변하지 않는 값을 관리할 때 매우 유용합니다.

예제 코드: const_double_string.c

#include <stdio.h>

int main(void)
{
    // [1] 상수 선언 및 초기화
    const double PI = 3.14;
    const char* SITE_NAME = "VisualAcademy";

    // [2] 상수 사용
    printf("%.2f\n", PI); // 출력: 3.14
    printf("%s\n", SITE_NAME); // 출력: VisualAcademy

    return 0;
}
3.14
VisualAcademy

상수는 const 키워드를 사용하여 선언하며, 이 강의에서는 상수의 이름을 대문자로 표기하는 관례를 따릅니다. 이 방식은 코드 내에서 상수의 사용을 명확하게 하고, 프로그램의 가독성을 높이는 데 도움이 됩니다.

9. 논리 데이터 타입(bool) 소개

논리 데이터 타입은 참(true) 또는 거짓(false)의 값을 저장하는 데 사용됩니다. bool 키워드로 선언된 변수는 논리형 값, 즉 참과 거짓 정보를 저장할 수 있습니다. 이를 통해 조건문, 반복문 등 프로그램의 흐름을 제어하는 데 필수적인 역할을 합니다. bool 타입은 1바이트의 메모리 공간을 사용하며, 이 공간에는 truefalse 두 가지 값만 저장할 수 있습니다. 이러한 특성은 프로그램 내에서의 결정 로직을 구현할 때 매우 유용하게 사용됩니다.

10. #include <stdbool.h>

C99 표준에서 추가된 논리 데이터 타입을 사용하려면 stdbool.h 파일을 포함해야 합니다.

11. C 언어에서 bool, true, false 키워드 사용하기

C 언어에서 bool, true, false 키워드는 기본적으로 지원되지 않습니다. 하지만 stdlib.h 헤더 파일을 사용하면 이러한 키워드를 사용할 수 있습니다.

stdilb.h 헤더 파일은 C 표준 라이브러리의 일부입니다. 이 헤더 파일은 여러 가지 유용한 함수와 매크로를 제공합니다. 그 중에서도 bool, true, false 키워드를 사용할 수 있게 해주는 매크로가 있습니다.

코드: bool_demo.c, BoolDemo.c

#include <stdio.h>
#include <stdbool.h>

int main(void)
{
    bool bln1;
    bool bln2;

    bln1 = true;	// 참(1)
    bln2 = false;	// 거짓(0)

    printf("%d %d\n", bln1, bln2); // 1 0

    return 0;
}
1 0

C 언어에서 참과 거짓을 표현하는 true, false 키워드는 실제로는 10으로 저장되어 사용됩니다.

12. 논리 자료형 사용하기

stdbool 헤더 파일은 C99 이상에서 지원되는 표준 라이브러리 헤더 파일로, 논리 자료형인 참(True) 또는 거짓(False) 값을 저장할 때 사용됩니다. 이 헤더 파일을 사용하면 bool, true, false 키워드를 사용할 수 있어 코드의 가독성을 높일 수 있습니다.

이번에는 bool 변수를 사용해보겠습니다.

코드: boolean_demo.c, BooleanDemo.c

//[?] 논리 자료형: 참(True) 또는 거짓(False) 값 저장
#include <stdio.h>
#include <stdbool.h> // bool, true(1), false(0)

int main(void)
{
    bool bln = true; // 참(1)
    printf("%d\n", bln); // 1

    bool isFalse = false; // 거짓(0)
    printf("%d\n", isFalse); // 0

    return 0;
}
1
0

C 언어의 stdbool.h 헤더 파일에서 논리 데이터 타입에 사용될 미리 정의된 키워드는 truefalse입니다. 다만, printf() 함수를 통해서 출력되는 값은 숫자 형식으로 10으로 표현됩니다. 이처럼, C 언어에서는 true1이고 false0입니다.

13. 장 요약

이번 장에서는 문자, 문자열 그리고 논리 타입에 대해서 다루었습니다. 간단히 데이터 타입만 사용해봤지만, 앞으로 이루어지는 모든 영역에서 더 많이 다루고 더 자세히 다룰 예정입니다.

정보처리산업기사 실기 시험 기출 문제 - 문자와 정수의 출력

문제

다음 C 프로그램이 실행되었을 때의 동작을 설명하고, 출력 결과를 예측하시오.

소스 코드 파일명: character_and_integer_outputs.c

#include <stdio.h>

main() {
    // ASCII_Code 'A' = 65, 'a' = 97
    int a = 10;
    char b = 'a';
    printf("%d\n", a);
    printf("%d\n", b);
    printf("%c", b);
}

입력 예시

이 프로그램은 입력을 받지 않습니다.

출력 예시

10
97
a

해설

이 프로그램은 정수 변수와 문자 변수의 값을 초기화한 후, printf 함수를 사용하여 이들 값을 다양한 형식으로 출력합니다.

  1. int a = 10;는 정수 변수 a를 선언하고 10으로 초기화합니다.
  2. char b = 'a';는 문자 변수 b를 선언하고 ASCII 코드에서 소문자 'a'에 해당하는 문자로 초기화합니다. 소문자 'a'의 ASCII 코드 값은 97입니다.
  3. printf("%d\n", a);는 변수 a의 값을 정수 형식으로 출력합니다. 따라서 10이 출력됩니다.
  4. printf("%d\n", b);는 변수 b의 값을 정수 형식으로 출력합니다. 문자 'a'의 ASCII 코드 값인 97이 출력됩니다.
  5. printf("%c", b);는 변수 b의 값을 문자 형식으로 출력합니다. 따라서 a가 출력됩니다.

이 프로그램은 기본적인 데이터 타입과 출력 형식 지정자를 사용하여 변수의 값을 출력하는 방법을 설명합니다. ASCII 코드를 이해하고 문자와 정수 간의 변환 방식을 보여줍니다.ㅗ

VisualAcademy Docs의 모든 콘텐츠, 이미지, 동영상의 저작권은 박용준에게 있습니다. 저작권법에 의해 보호를 받는 저작물이므로 무단 전재와 복제를 금합니다. 사이트의 콘텐츠를 복제하여 블로그, 웹사이트 등에 게시할 수 없습니다. 단, 링크와 SNS 공유, Youtube 동영상 공유는 허용합니다. www.VisualAcademy.com
박용준 강사의 모든 동영상 강의는 데브렉에서 독점으로 제공됩니다. www.devlec.com