[C] 컴퓨터: 알아듣게 말해..

장세민·2022년 9월 12일
0

📝 TIL

목록 보기
18/40
post-thumbnail

📌 아스키코드

아스키코드는 사람이 사용하는 기호를 컴퓨터 안에서 표현하는 방법에 대해 약속한 것이다.

어떻게?

예를 들어 소스 파일에 A라는 문자를 사용하면 컴퓨터는 8개의 비트를 01000001과 같은 상태로 저장한다.
또한 컴퓨터에 01000001과 같은 비트 열이 있으면 모니터는 화면에 A라는 문자를 보여준다.

아스키코드는 이처럼 문자를 코드화 하는 것!


<아스키코드 표>

종류문자 상수아스키 코드 값출력할 때
숫자 문자(10개)'0' ~ '9'48 ~ 57문자 출력
대문자 (26개)'A' ~ 'Z'65 ~ 90문자 출력
소문자(26개)'a' ~ 'z'97 ~ 122문자 출력
특수 문자 (33개)' '(공백), '$', '&' ...32, 36, 38 ...문자 출력
제어 문자(33개)'\0', '\t', '\n', '\r' ...0, 9, 10, 13 ...제어 기능 수행

표를 통해 알 수 있는 아스키 코드 값 특징은

1. 알파벳과 숫자는 각각 연속된 아스키 코드 값을 갖는다.

2. 소문자 대문자보다 아스키 코드 값이 크다.

3. 제어 문자는 백슬래시와 함께 표시하며 출력할 때 그 기능을 수행한다.


대문자를 소문자로 바꾸는 예제를 풀어보자.

  1. # include <stdio.h>
  2.  
  3. int main()
  4. {
  5. char small, cap = 'G';
  6.  
  7. if ((cap >= 'A') && (cap <='Z'))
  8. {
  9. small = cap + ('a' - 'A');
  10. }
  11. printf("대문자: %c %c", cap, '\n');
  12. printf("소문자: %c", small);
  13.  
  14. return 0;
  15. }

5행은 문자를 저장하기 위해 char형 변수를 선언하고 초기화 한다.
문자 상수는 4바이트의 크기를 갖지만 아스키 코드 값이 0~127 범위에 있으므로
2진수로 바꾸면


문자 'G' 00000000 00000000 00000000 01000111


왼쪽 3바이트는 모두 0이 되고 오른쪽 1바이트만 의미를 갖는다.
따라서 문자는 1바이트 크기의 char형 변수에 저장해 사용한다.

컴파일러는 문자에서 아스키 코드 값을 갖는 오른쪽 1바이트만 변수에 저장하고 남는 바이트는 버린다.

7행은 변수 'cap'에 저장된 문자가 대문자의 아스키 코드 값 범위에 속하는지 검사한다.
문자 'G'의 아스키 코드 값은 71이고, 대문자 A(65)와 Z(90) 사이의 값이므로 if문은 참


그런데, 9행을 보면 소문자에서 대문자를 뺀 차를 활용한다. why?

small = cap + ('a' - 'A');

소문자는 대문자보다 아스키 코드 값이 크고 같은 문자끼리는 아스키 코드 값의 차가 일정하고,
알파벳은 연속된 아스키 코드 값을 가지므로

'a' - 'A'의 값을 대문자 'G'에 더하면 소문자 'g'를 구할 수 있다.

👏👏👏

11행을 보면 제어 문자를 백슬래시('\')와 제어 기능 암시 문자('n')를 함께 사용했다.
제어 문자는 형태가 없어 %c로 출력하면 해당 제어 기능이 수행된다.


📖 scanf 함수를 사용한 문자 입력

scanf 함수로 문자를 입력할 때는 %c 변환 문자를 사용한다.

%c는 형태가 있는 문자를 입력하지만,
공백이나 탭 문자(tab), 개행 문자(enter)와 같은 제어문자도 입력한다.

이들 세 문자는 숫자를 입력할 때 값을 구분하기 위해 사용되지만
문자를 입력할 때는 그 자체가 하나의 입력 데이터가 된다.


쉽게 이해해보자!

  1. # include <stdio.h>
  2.  
  3. int main(void)
  4. {
  5. char ch1, ch2;
  6.  
  7. printf("문자를 입력하세요.");
  8. scanf("%c%c", &ch1, &ch2);
  9. printf("[%c%c]\n", ch1, ch2);
  10.  
  11. return 0;
  12. }
  13.  
  • a와 b를 연속으로 입력하고 enter를 치는 경우

문자 'a'와 'b'가 차례로 변수 ch1과 ch2에 저장


  • a와 공백()을 연속으로 입력하고 enter를 치는 경우

문자 'a'가 ch1에 저장되고 공백 문자가 ch2에 저장


  • a만 입력하고 enter를 치는 경우

enter에 해당되는 개행문자가 변수 ch2에 저장,
따라서 ch1에 입력된 'a'가 출력되고 바로 ch2에 저장된 개행문자가 출력되므로 줄이 바뀜


💬 화이트 스페이스(white space)

Space Bar, Tab, Enter를 눌렀을 때 입력되는 문자를 묶어 부르는 말이다.

%d, %lf, %s와 같은 변환 문자로 숫자나 문자열을 입력할 때는 데이터를 구분하는 용도로 쓰이며,
그 자체가 데이터로 입력되지는 않는다.

  1. # include <stdio.h>
  2.  
  3. int main(void)
  4. {
  5. int a, b;
  6.  
  7. printf("문자를 입력하세요.");
  8. scanf("%d %d", &a, &b);
  9. printf("%d %d\n", a, b);
  10.  
  11. return 0;
  12. }

예를 들어 2개의 int형 변수에 10(공백)20을 입력하면
중간에 있는 공백 문자는 10과 20을 구분하는 용도로만 쓰인다.
공백은 숫자가 될 수 없기 때문!

그러나 %c는 문자를 입력하므로 화이트 스페이스도 입력 대상이 된다.


그렇다면 문자는 구분할 수 없을까?
scanf(" %c  %c", &ch1, &ch2);

scanf 함수는 %c앞에 화이트 스페이스를 사용하면 문자도 분리하여 입력할 수 있다.


📖 getchar 함수와 puchar 함수

scanf 함수와 printf 함수는 문자뿐만 아니라 숫자도 입력하는 기능이 포함되어 있으므로
문자만 입출력하는 경우는 문자 전용 함수를 쓰는 것이 효율적이다.

getchar 함수와 putchar 함수는 문자 전용 입출력 함수이다.

int getchar(void);    // 매개변수가 없고 입력한 문자를 반환
int putchar(void);    // 출력할 문자를 인수로 줌
  • getchar 함수
    매개변수가 없으므로 괄호만 사용하여 호출, 반환값은 int형 변수
    반환값은 필요에 따라 변수나 배열에 옮겨 문자나 문자열로 사용
    scanf 함수와 마찬가지로 공백, 탭, 개행 문자도 입력하는데 이들 문자를 제외하는 옵션은 없다.

  • putchar 함수
    문자 상수나 문자의 아스키 코드 값을 인수로 주면 해당 문자를 화면에 출력
    그리고 출력한 문자를 다시 반환하며 출력 과정에서 에러가 발생하면 -1을 반환


🚨 getchar함수 반환형이 int형인 이유

getchar 함수의 반환형이 int형인 이유는 문자 이외의 값도 반환하기 때문이다.
문자의 입력을 끝내기 위해 Ctrl + Z를 누르면 -1을 반환하는데,
아스키 코드 값의 범위 0~127과 겹치지 않는다.

데이터를 입력하는 경로가 파일로 바뀌고 반환하는 값이 255라면

파일의 데이터를 모두 읽은 경우 반환하는 -1과 구분이 불가능할 수 있다.
-1은 모든 비트가 1인 상태로 저장되므로 1바이트 크기 공간에서는 255와 -1을 표현하는 비트열이 같기 때문이다.


따라서 문자를 반복 입력하는 경우 int형 변수에 저장하고 -1과 비교한 후에 -1이 아니면 별도의 char형 변수에 옮겨 사용!
profile
분석하는 남자 💻

0개의 댓글