혼자 공부하는 C - CH1, CH2



  • 프로그래밍 언어는 정확한 표현 규칙을 정의해 놓은 것.
  • C언어는 1972년에 켄 톰슨이 Unix 시스템에 사용하기 위해 개발된 B언어를, 데니스 리치가 발전시켜 만듦.
  • 장점
    • 시스템 프로그래밍이 가능
    • 이식성을 가진 프로그램을 만들 수 있음
    • 함수를 사용한 개별 프로그래밍 가능.

컴파일

  • 프로그래밍 언어는 사람이 읽고 쓰는데 중점적이므로 컴퓨터는 이해하지 못합니다.
  • 소스파일을 기계어로 바꾸어주는 컴파일 (Compile) 과정이 필요합니다.
  • 따라서, 개발을 하기 위해서는 컴파일러 (Compiler)가 필요합니다.



C언어 개발 환경을 갖추어 보자

1. Visual Studio

visual studio 2022 community 버전을 다운받고 설치를 진행합니다.



다운로드



설치는 중간에 워크로드에서 C++를 사용한 데스크톱 개발을 선택해야 하며 다른 것은 모두 계속해주시면 됩니다.



설치 후 실행 화면





2. (WSL) Visual Studio Code

저는 리눅스를 주로 사용하기 때문에 WSL을 이용한 Ubuntu 환경에서 개발환경을 구축해보겠습니다.

  1. Visual studio code 를 다운로드 합니다. 링크

  2. WSL을 설치합니다.
    Microsoft의 설명서 링크

  3. WSL 환경의 터미널에서 필요한 툴을 설치합니다.

1
sudo apt install build-essential gdb

설치가 되었는지 버전을 출력을 통해 확인합니다.

1
gcc -v
  1. VScode에서 왼쪽 사이드바의 확장에서 Remote-ssh를 설치합니다.
  2. Vscode에서 왼쪽 사이드바의 원격 탐색기를 클릭하고 왼쪽 최상단의 원격WSL 대상으로 설정합니다.
  3. 바로 아래의 WSL 대상에서 설치된 Ubuntu 버전에 따라 새 창에서 연결 혹은 현재 창에서 연결을 선택합니다.
  4. 왼쪽 확장 탭에서 **C/C++**을 설치합니다



C/C++ 확장 설치



이제 개발 환경은 구축되었고 상단 탭 File > Open Folder 버튼으로 개발을 진행할 경로를 설정하면 됩니다.

테스트 해보겠습니다. main.c 라는 파일을 생성하고 아래 코드를 작성하였습니다.

1
2
3
4
5
6
7
#include <stdio.h>

int main(void)
{
printf("Be happy");
return 0;
}

빌드할 속성을 담은 파일을 생성해야 합니다.

  • 터미널 > 기본 빌드 작업 구성 > C/C++: gcc 활성 파일 빌드 (안나타나면 재시작)
  • 선택하면 .vscode/task.json 이 생성되는데 작업공간 (프로젝트)에서 사용할 빌드 정보를 담고있습니다.

이 상태에서

  • 빌드는 Ctrl + Shift + B를 입력하여 진행 할 수 있습니다
    • main.c를 빌드하여 main 이라는 파일이 생상되었고, ./main 으로 터미널에서 실행 가능합니다.
  • 디버깅은 F5를 누르면 진행됩니다
  • 디버깅 없이 실행은 Ctrl + F5를 누르면 진행됩니다.
  • 스크립트 라인 번호 왼쪽을 누르면 중단점 (Breakpoint)가 지정되며 해당 위치에서 멈춥니다. F10을 누르면 한줄한줄 실행이 가능합니다.



상수와 데이터 출력


C 프로그램은 함수로 이루어집니다. 여기서 main은 프로그램의 시작을 의미하며 반드시 있어야합니다.

1
2
3
4
5
int main(void) // Head. function prototype 이라고도 함
{ // Body
10 + 20; //
return 0; //
} //



코드 작성에는 규칙을 따라야 합니다.

  1. 세미콜론 ( ; ) 을 사용해 문장의 끝을 표시한다.
  2. 한 줄에 한 문장씩 작성한다.
  3. 일정한 간격으로 들여쓴다. (기본 4칸)



문자열 출력

하나의 글자는 문자, 문자가 여러개 이어지면 문자열

  • a : 문자
  • apple : 문자열



제어 문자 출력

  • \n : new line. 다음 줄로 이동
  • \t : tab
  • \b : backspace. 근데 지우는게 아닌, 한칸 왼쪽으로 이동함.
  • \r : carriage return. 캐리지 리턴. 맨 앞으로 이동.
  • \a : alert. 벨소리



정수와 실수 출력

printf 는 문자를 출력해주므로, 변환 문자를 사용해야한다.

  • %d : decimal로 정수를 나타낸다.
  • %lf : long float으로 실수를 나타낸다. default는 소수점 6자리이다.
    • %.1lf : lf 앞에 .n 을 붙여서 n번째 자리만 나타낼 수 있고, 반올림된다.

정수 상수 표현법

  • 정수는 10진수, 8진수, 16진수로 표현 가능.
  • 2진수로 표현하지 않는 것은 0, 1 두개뿐이라 표현이 길어져서 사용에 비효율 적이기 때문



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>

int main(void)
{
printf("%d\n", 12);
printf("%d\n", 014);
printf("%d\n", 0xC);

printf("%o\n", 12); // oct
printf("%x\n", 12); // hex 소문자
printf("%X\n", 12); // hex 대문자
}

// 12
// 12
// 12

// 14
// c
// C



실수 상수 표기법

3가지로 표현 가능하다

  • 소수점 형태 → 0.000314
  • 지수 형태 → 3.14 * 10**-4
  • 정규화 (normalization) 표기법 → 3.14E-4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>

int main(void)
{
printf("%.1lf\n", 1e6);
printf("%.7lf\n", 3.14e-5);
printf("%le\n", 0.0000314);
printf("%.2le\n", 0.0000314);

return 0;
}

/*
1000000.0
0.0000314
3.140000e-05
3.14e-05
*/



문자와 문자열 상수 표현법

  • 문자는 작은 따옴표 ’ 로 묶는다.
  • 문자열은 쌍 따옴표 " 로 묶는다.



상수가 컴파일된 후의 비트 형태

코드는 컴파일을 거쳐서 연산자들이 명령어가 되고, 상수는 연산이 가능한 형태로 바뀐다.

상수는 종류에 따라 각기 다른 형태로 바뀐다.

모든 데이터는 비트 (bit)로 바뀐다. 1비트는 0, 1 두 가지 값을 갖는다.

비트가 8개면 1 바이트 (Byte)이고, 2**8가지이다.


정수 상수와 실수 상수의 컴파일

  • 정수 상수를 컴파일 하면 4바이트로 표현된다.
  • 실수는 8바이트로 표현된다.
  • 정수 10, 실수 10.0 을 컴파일 하면 아래처럼 바뀝니다.

정수 10: 00000000 00000000 00000000 00001010

실수 10.0: 01000000 00100100 00000000 00000000 00000000 00000000 00000000 00000000

문자 상수의 컴파일

  • 2진수 형태의 아스키 코드 값으로 번역된다.
  • ‘A’ 의 아스키 코드 값은 65이므로 정수상수 65와 같은 형태로 번역된다.
  • 즉, 문자상수는 소스 코드의 문자를 표현하는 방법이고 컴퓨터 안에서는 정수와 같은 형태로 처리된다.



정수 상수가 컴파일 된 후의 비트 형태

양수의 변환

  • 정수는 4바이트 크기의 2진수로 변환됩니다.
  • 4바이트는 8개의 비트가 4개 있는 것이므로, 2**8 * 4 = 255개의 문자를 표현할 수 있습니다.
    • 1비트 : 02110\sim2^1-1 으로 0~1의 숫자 표현 가능
    • 8비트 : 02810\sim2^8-1 으로 0~255의 숫자 표현 가능
    • 32비트 : 023210\sim2^{32}-1 으로 0~4294967295의 숫자 표현 가능

컴파일러는 23212^{32}-1 보다 큰 상수를 사용하면 자동으로 데이터의 크기를 8바이트로 늘려 처리합니다.

값의 크기와 상관없이 데이터의 크기를 8바이트로 만들고 싶다면,
정수 접미사에 LL (Long Long)을 붙이면 됩니다.


음수의 변환

  • 음수는 절대값을 2의 보수로 바꾸어 처리합니다.
    • 2의 보수: 2진수의 0과 1을 바꾼 상태에서 1을 더한 값.
    • -1: ~ 00000001 → ~11111110 → ~ 11111111

예) -10을 변환하는 과정.

  1. -10 을 절대값으로 변환 → 10
  2. 10을 2진수로 변환 → 00000000 00000000 00000000 00001010
  3. 0과 1을 보수로 바꿈 → 11111111 11111111 11111111 11110101
  4. 1을 더해줌 → 11111111 11111111 11111111 11110110

10 00000000 00000000 00000000 00001010
-10 11111111 11111111 11111111 11110110
00000000 00000000 00000000 00000000



실수 상수가 컴파일된 후의 비트 형태

실수는 제한된 데이터 크기에 수를 푠혀가 위해 IEEE 754 표준을 따릅니다.

여러가지 타입이 있으나, 가장 많이 쓰이는 double만 보겠습니다

  • 부호 비트: 가장 왼쪽의 1비트로, 양수는 0, 음수는 1로 표시.
  • 지수부: 다음 11 비트는 지수값을 의미.
  • 소수부: 다음 52비트는 소수값을 의미.

최대값은 지수부분과 소수부분의 가장 큰 값이며, 최소값은 부호 비트만 바꾸면 됩니다.

1.79×103081.79×10308-1.79\times 10^{308} \sim 1.79\times 10^{308}



위 내용을 활용한 예시로, 학번, 이름, 학점을 출력하는 프로그램을 작성하면 아래와 같습니다.


1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

int main(void)
{
printf("학번: %d\n", 32165);
printf("이름: %s\n", "홍길동");
printf("학점: %c\n", 'A');
}

/*학번: 32165
이름: 홍길동
학점: A*/



오늘은 C언어의 개발환경 구축 및 기본적인 출력 방법을 살펴보았습니다.

읽어 주셔서 감사드립니다~👋