모두의 코드 - 1. C 언어가 뭐야?, 2 - 1. C 언어 본격 맛보기, 2 - 2. 주석(Comment)에 대한 이해, 2 - 3. 수를 표현하는 방법(기수법)

2024. 9. 21. 00:03Programming Language/C

1. C 언어가 뭐야?

왜 C언어를 배워야 하는가

  • 좋은 프로그래머가 되려면 컴퓨터의 내부 원리를 아는것이 필수, 만약 C언어를 배우게 된다면 컴퓨터의 내부 원리를 좀 더 쉽게 이해할 수 있다.
  • 많은 언어들이 C언어에서 파생되어 생겨났기에 C언어를 배운다면 다른 언어를 배울때 더 쉽게 습득할 수 있다
  • C언어는 배워야할 내용이 다른 언어에 비해 매우 적다, 물론 배울 내용이 적은것과 쉬운것과는 다름..

그럼 어떤 식으로 배워야 할까

강좌에서 배운 내용을 토대로 간단한 프로그램을 제작해봐라!

 

여정에 필요한 준비물

컴퓨터, 머리, 노오력, 컴파일러 

컴파일러..? 컴파일러란 무엇일까?

컴파일러는 컴파일을 해주는 것이다.

컴퓨터는 0과 1밖에 모르는 바보이기에 명령을 내리기 위해서는 0과 1만 작성된 내용을 CPU에게 인식시켜야한다.

컴퓨터 과학자들은 이런 불편을 개선하기 위해 "언어"로 프로그래밍 할 수 있도록 만들었다.

기존에 01010001001과 같이 명령을 내리던걸 1 + 1과 같이 표현해줄 수 있도록 말이다.

그런데 문제는 컴퓨터가 인간의 언어를 알아들을 수 없기에 컴퓨터가 이해할 수 있는 0...1로 바꿔주는  놈이 필요하다.

이렇게 사람들이 사용하는 "프로그래밍 언어"와 컴퓨터가 이해할 수 있는 "기계어"의 번역기 역할을 수행해주는 것이 컴파일이다.

 

그럼 컴파일러는 어디서 구할 수 있을까?

다행히 쉽게 컴파일러를 구할 수 있다.

유명한 컴파일러로는 무료로 배포되는 gcc와 clang을 들 수 있으나 초보자들에게는 약간 복잡하기에 마이크로 소프트에서 무료로 배포하는 Visual C++ 2017 Community를 사용하자!

 

https://visualstudio.microsoft.com/ko/vs/community/

 

Visual Studio 2022 커뮤니티 버전 – 최신 무료 버전 다운로드

Windows, Android 및 iOS용 최신 개발자 앱을 만들기 위한 모든 기능을 갖춘 확장 가능한 무료 IDE를 사용해 보세요. 지금 무료로 커뮤니티를 다운로드하세요.

visualstudio.microsoft.com

 

계속을 눌러주자!

이제 설치할 것을 선택할 수 있는데, 우린 일단 C/C++을 배우는게 목적이기에 스크롤을 조금 내려서 

C++를 사용한 데스크톱 개발을 선택해주고 

설치해주자 저것만 선택했는데 10.73GB인게 실화인가;

 

그럼 이제 알아서 설치가 된다

용량이 크기에 조금 시간이 걸릴 수 있다.

인터넷 상황에 따라서 30분 - 1시간까지도 걸린다고 한다.

 

설치 했으면 이제 재시작을 해줘야 한다.

 

이제 새 프로젝트를 만들어보자.

Windows 데스크톱 마법사를 선택해서 프로젝트를 생성해주자.

hello라는 이름으로 프로젝트 이름을 작성해주고 만들기를 눌러주자.

그러면 작은 창이 추가로 뜨는데 빈 프로젝트만 선택해서 확인을 눌러주자.

그러면 아래 처럼 프로젝트가 생성된다.

이제 프로젝트에 소스파일을 추가해야 합니다.

혹시 이 솔루션 탐색기가 보이지 않는다면 Ctrl + Alt + L을 눌러 띄울 수 있다.

 

* 솔루션 탐색기 띄우기 단축키 - Ctrl + Alt + L

 

이 새 항목 추가 창이 뜨면 아래 모든 템플릿 표시를 눌러서

C++파일을 선택한 채로 이름을 hello.c로 변경해서 생성해주자.

 

** C++파일을 선택했으나, 파일 확장자가 .c이므로 비쥬얼 스튜디오에서 알아서 C 컴파일러로 컴파일 해준다.

 

추가를 눌러주자.

이제 아래와 같이 입력해보자.

작성하고서 상단에 빌드 > 솔루션 빌드를 눌러서 컴파일을 해준다.

성공적으로 컴파일 하면 아래와 같이 나온다.

 

2 - 1. C 언어 본격 맛보기

도대체 무슨일이 있던걸까

우리가 작성한 코드를 다시 한번 확인해보자.

일단 맨 첫 줄부터 보자.

#include 는 오른쪽에 붙은 <>안에 있는 파일을 우리의 프로그램에 불러온다는 의미이다.

말 그대로 해당 파일의 내용이 컴파일 할 때 우리 파일에 그대로 복사한다.

우리의 경우는 stdio.h라는 파일을 포함시켰다.

 

우리는 왜 stdio.h라는 파일을 이 프로그램에 포함했을까에 대한 설명은 아래에서 보고 다음 라인을 보자.

이 문장은 main이라는 함수를 정의한건데 이 main 함수는 모든 C 프로그램이 처음 시작하는 부분이다.

프로그램을 실행한다는 말의 의미는 CPU의 명령어 레지슽에 프로그램의 시작 명령어 주소값을 전달한다고 하였는데, 실제로는 이 main함수내부의 첫줄에 있는 첫 번째로 실행할 명령어의 주소값이 전달된다고 생각하면 된다

 

그 다음의 main 왼쪽에 int 는 영어의 integer의 약어로 이 함수가 종료될 때 정수값으로 반환한다는 의미로 반환 타입을 의미한다.

그 다음에 { 는 main 함수의 시작을 의미하고, 이 안에 넣는건 main 함수의 거야! 라는걸 나타낸다.

 

그 다음에는 위 프로그램의 핵심인 printf 를 살펴보자.

printf 는 오른쪽의 괄호 내부의 내용을 출력해주는 함수이다.

 

그런데 왜 printf 함수가 어떻게 화면에 출력하는 것일까?

사실 화면에 글자를 출력하는 것은 쉬울 것 같지만, 매우 복잡한 과정을 거친다.

왜냐면, 일단 운영체제는 자신이 화면에 글자를 뿌려야한다는 메세지를 보내야하고, 또 운영체제는 하드웨어(모니터)에 이를 뿌린다(출력한다)는 것을 이야기 해줘야 하기 때문이다.

이런 내용을 모두 작성하기에는 너무 힘들기에 위 내용을 담고있는 도구를 사용하게 되는데, 이 도구를 갖고 있는 파일이 위에서 말했던 stdio.h이다.

 

stdio는 STanDard Input Output의 약자로 "표준 입출력"이라는 뜻이다.

stdio.h파일에는 입력과 출력, 즉 화면에 출력하고(혹은 파일에 데이터를 쓰고), 사용자로부터 입력을 받아들이는것(혹은 파일을 읽어오는것)을 수행하는 기능을 제공한다.

C에서 .h로 끝나는 파일은 헤더파일이라고 하고 헤더파일은 나중에 배울것이다.

아무튼 printf를 사용할 수 있는 이유는 상단에 stdio.h파일을 #include하고 있기 때문이다.

 

그리고 C에서는 모든 문장의 종료에 ;(세미콜론)을 붙여줘야 한다.

마지막 return 0; 부분은 

0을 반환한다는 의미로 main함수의 반환형이 int이기 때문에 정수값 0을 반환해주는 것이다.

그러면 이 함수는 누구한테 이 값을 반환할까

프로그램을 실행한 프로그램한테 반환하게 된다.

숫자 0을 반환하면 컴퓨터에게 프로그램이 무사하게 종료됨을 알리는 것이고 반면 1을(0이외에 아무숫자나 상관없어 보인다.) 반환하면 컴퓨터한테 무사히 종료되지 않았음(에러 상황)을 알리는 것이다.

 

**근데 사실 적어도 윈도우에서는 이 return 값이 무시된다고 한다

 

주석(Comment) 넣기

주석은 컴파일러는 무시하지만 사용자가 이해하기 쉽게 설명을 남겨 놓는 코멘트이다.

C언어에서 주석은 두가지 형태를 가진다

/* */(영역 주석)와 //(라인 주석)이다.

 

 

2 - 2. 주석(Comment)에 대한 이해

작성할 내용 없음

2 - 3. 수를 표현하는 방법(기수법)

수(Number)와 숫자(Digit)의 차이는 수의 경우 어떤 물질의 양을 나타내는 단위, 숫자는 이를 기록할 수 있도록 시각화한 것을 의미한다

사과 100개가 있음을 알리기 위해서 사과 100개를 나열해서 보여주거나, 100개를 그려야만 한다면 힘들 것이다.

숫자는 이걸 단순히 100이라는 문자를 통해서 알려준다.

 

그런데 사실 숫자를 표현할때 1, 2, 3, 4, 5라는 문자를 이용하는데 오직 숫자로만 수를 표현할 수 있는 것은 아니다.

0과1로만을 이용해서 수를 표현할 수 도 있다.

이렇게 수를 표현하는 방식을 기수법(Numeral system)이라고 한다.

 

수학적 배경 지식 - 밑과 지수

수학은 "복잡한걸 단순하게"를 지향하며 발전해왔다.

예를 들어보자.

 

2를 100번 곱한 수를 표현하기 위해서는 

 

2×2×2××2

 

와 같이 2와 x를 수 많이 써야만 표현할 수 있다.

이를 단순화하기 위해서 아래와 같은 기호를 만들었다

 

2100

 

이때 아래에 있는 2를 밑(base)라고 부르고 위에 있는 100을 지수(exponent)라고 부른다.

지수에서 가장 중요한 사실은 바로

 

(Number)0=1

 

이라는 사실이다.

왜 숫자를 한번도 곱하지 않았다면 1이 될까?

사실 이 값은 수학자들 사이에 약속된 정의값이라고 생각하면 된다.

이게 1이 아니라면 지수와 관련된 다른 법칙들이 성립하지 않게 되기 때문이다.

그냥 다른 법칙들을 만족시키기 위한 약속이라고 생각하면 될듯하다.

십진법, 이진법, 16 진법

우리는 아라비아 숫자, 10개를 이용하는 십진법(decimal)을 사용하고 있다.

우리가 "253"이라는 숫자가 나오면 아래와 같이 생각할 수 있다.

253 = 2 x 102 + 5 x 101 + 3 x 100

 

다시 쓰면 

 

253 = 200 + 50 + 3

 

이 된다.

주목해야할점은 한 자릿수가 늘어날 때마다 그 자리를 나타내는 숫자에 10이 곱해진다는 점이다.

253앞에 7이 붙은 7253을 표현한다면 

 

7253 = 7 x 103 + 2 x 102 + 5 x 101 + 3 x 100

 

이 된다.

이게 십진법의 가장 큰 특징이다.

 

이런 아이디어를 적용시켜 이진법을 생각해보자

컴퓨터는 0과 1 밖에 표현할 수 없다(전기적 신호가 on인지, off인지) 그러면 컴퓨터는 253을 어떻게 표현할까.

먼저 작은 숫자부터 이진법으로 어떻게 표현하는지부터 알아보자.

예를 들어 6이란 숫자가 있을때 이를 이진법으로 표현한다면 

6 = 4 + 2 = 1 x 22 + 1 x 21 + 0 x 20 = 1102

와 같이 표현 할 수 있다. 

 

십진법의 경우는 자릿수가 늘어날 때마다 10을 곱했으니 2진법의 경우는 자릿수가 늘어날때마다 2을 곱해줄 수 있다.

또한 십진법이 0부터 9까지를 쓴 만큼 이진법도 0과 1만을 사용해야하기에 6을 110으로 표현할 수 있다.

 

110 밑에 2가 작게 붙어 있는건 이건 2진법을 사용한 이진 숫자임을 알리는 것이다

 

이진수가 무엇인지 확실하게 감을 잡기 위해 23, 49의 두가지 십진수를 이진수로 변경해보자

 

23 = 16 + 4 + 2+ 1 = 1 x 24 + 0 x 23 + 1 x 22 + 1 x 21 + 1 x 20 = 101112

 

49 = 32 + 16 + 1 = 1 x 25 + 1 x 24  + 0 x 23 + 0 x 22  + 0 x 21  + 1 x 20  = 1100012

 

그렇가면 이제 이진수를 어떻게 십진수로 바꿀 수 있는지 알아보자.

해당 10진수 값을 2로 나누어서 몫이 0이 될때 까지 나눈 다음에 마지막 나머지(0이 되기전 나머지)부터 역순으로 읽어주면 된다.

 

그런데 이진수는 숫자가 너무 길어지고 커지는 경향이 있다, 그렇기에 보통은 16진법을 사용하고 있다

16진법도 여태 사용했던 개념을 그대로 적용하면 된다

그런데 16진법은 숫자가 16개가 필요하기에 1-9와 A-F까지의 문자를 같이 사용한다

1부터 9까지는 10진법과 동일하게 숫자를 사용하고 10부터는 A, 16을 F로 사용하면 된다.

예를 들어 123이라는 숫자가 있다고 한다면 

 

123 = 7 x 16 + 11 = 0x7B

 

라고 표현할 수있다.

16진수도 동일하게 자릿수가 늘어날 때마다 16을 곱해주면 된다.

 

19 = 16 + 3 = 1 x 161 + 3 x 160 = 0x13

 

이 되고 

 

16782 = 4 x 163 + 1 x 162 + 8 x 161 + 14x160 = 0x418E

 

가 된다.

 

16진수를 10진수로 변경하는 방법과 10진수를 16진수로 변경하는 방법은 앞에서 2진수를 10진수로 10진수를 2진수로 변경하는 방법과 동일하다.

물론 16이기에 숫자가 커지고 계산이 어려워졌다는 변경점도 있긴하다.

반면에 2진수를 16진수로 16진수를 2진수로 바꾸는 방법은 매우 간단하다

 

먼제 16진수를 2진수로 바꾸는 방법을 살펴보자. 

이 방법은 단순히 16진수의 각 자리수를 반드시 4자리의 2진수로 변경하고 연결해주면 된다.

 

예를 들어보자 

0x4F38E라는 16진수가 있을때 2진수로 변환한다면 

16진법 10진법 2진법
4 4 100
(예외적으로 맨 앞자리의 경우는 4자리를 맞출 필요없음)
F 16 1000
3 3 0011
8 8 0100
E 14 0111

이 되고 이를 종합해보면 0x4F38E는 2진수로 1001000001101000111이 된다.

마찬가지로 2진수를 16진수로 변환하는 방법은 뒤부터 4자리씩 뜯어서 그 숫자를 10진법으로 변환한 뒤 16진법으로 변경하면 된다.

2진법 10진법 16진법
100  4 4
1000 16 F
0011 3 3
0100 8 8
0111 14 E

 

그럼 이제 컴퓨터 메모리와 이진법과의 상관관계를 알아보도록 하자.

 

컴퓨터의 메모리의 단위

컴퓨터에 데이터를 저장하는 공간은 컴퓨터를 종료하면 데이터가 날아가는 휘발성 메모리(대표적으로는 램(RAM, Random Access Memory))와 컴퓨터를 종료해도 데이터가 날아가지 않는 비휘발성 메모리(대표적으로는 롬(ROM, Ready Only Memory 흔히 말하는 CD - ROM이나 DVD - ROM, 아니면 메인보드 Bios에 박혀있는 롬 등등)로 나뉜다.

 

앞으로 메모리라고 말하는건 휘발성 메모리인 RAM를 말하는 것이다.

이 RAM은 데이터에 랜덤하게 접근할 수 있는데 반면 하드 디스크나 CD는 순차적으로 접근해야하기에 속도가 매우 빠르다.

 

쉽게 말해 우리가 아파트에 713호에 사는 철수를 찾는다고 한다면 철수가 RAM아파트에 살때는 단번에 713호에 산다는것을 알 수 있는데 하드디스크 아파트에 산다면 101호부터 호를 찾아가서 713호까지 찾아봐야한다는 의미이다.

물론 RAM은 전원이 모두 꺼지면 날아가기 때문에 중요한 데이터들은 틈틈히 하드 디스크에 저장하게 된다.

 

컴퓨터 한 개 의 메모리 소자는 0 혹은 1의 값을 보관할 수 있고 이 2진수 한자리를 가리켜 비트(Bit)라고 한다.

1개의 비트는 0또는 1값을 보관할 수 있기에 저장할 수 있는 값이 매우 적다.

그렇기에 사람들은 8개의 비트를 묶어 바이트(Byte)라고 부른다.

즉 8비트는 1바이트 인것이다

(참고로 4비트를 특별히 묶어 니블(nibble)이라 부른다만 많이 쓰이진 않는다.)

 

8비트로 나타낼수 있는 수의 최대 수는 

 

000000002 ~ 111111112 = 0 ~ 255 = 0 ~ 0xFF

 

이고 0부터 255로 총 256개의 수를 나타내게 된다.

 

그 다음 단위로는 워드(Word)라고 부르는 단위가 있다.

컴퓨터에서 연산을 담당하는 CPU에는 레지스터(register)라는 작은 메모리 공간이 있는데, 이곳에 값을 불러다 놓고 연산을 수행하게 된다.

 

예를 들어 a + b 를 수행하기 위해서는 a와 b라는 값을 어디에 적어놓아야지 a + b 를 할 수 있는 것 처럼, CPU에서 연산을 수행하기 위해서 잠시 내용을 써놓는 부분이 레지스터이다.

 

이런 레지스터의 크기는 컴퓨터 상에서 연산이 실행되는 최소 단위라고 볼 수 있고, 이 크기를 워드라고 부른다.

32비트 컴퓨터 시절에는 이 1워드가 32비트, 즉 4바이트 였으나, 지금은 대부분 64비트 컴퓨터이기에 이 경우는 1워드가 64비트, 8바이트가 되었다.