[CS50] 3-0. Prequel
(1) 컴파일(Compile)
세 번째 강의의 원 제목은 '배열(array)'지만, 들어가기 전 프로그램 생성 및 실행에 대한 간단한 로직 설명이 있어 먼저 정리하려고 한다.
모든 프로그램의 구동 방식인 컴파일(Compile)을 언급하기 전에 기본적인 C언어 코드를 분석해보자.
#include <stdio.h>
int main(void)
{
printf("hello world\n");
}
#include <stdio.h>
는 헤더파일로, 메인에서 실행하는 함수가 무엇인지 알려주는 역할을 한다. .h 확장자를 가지고 있다. int main(void){}
는 주요 기능이 담긴 영역이다. printf()
는 출력 함수인데, <stdio.h>
에 들어 있다.
이는 컴퓨터에게 컴파일 절차를 알려준다. clang
혹은 make
등의 컴파일 절차를 실행하면 먼저 ①preprocessing에 들어가 헤더파일, 메인 영역, 기능 등을 읽는다. 그 후 ②compiling하여 어셈블리어(저급 수준 프로그래밍 언어)로 번역한다. 번역된 코드는 다시 ③assembling 작업에 들어가 기계어로 재번역한다. 여기서 우리의 코드는 0과 1의 조합이 된다. 마지막으로 ④linking하여 각각의 기계어 (헤더파일, 메인 영역, 기능)를 연결해 하나의 실행 프로그램으로 만든다. 이 과정을 줄여서 보통 compiling
이라고 부른다.
(2) 디버깅(Debuging)
프로그래밍 상에서 버그(bug)는 코드 상의 오류를 뜻하며, 디버그(debug)는 해당 오류를 검사 및 수정하는 과정을 가리킨다. 이 단어들의 뜻은 유명한 컴퓨터 과학자인 Grace Hopper가 'Mark2'라는 컴퓨터 시스템을 개발하는 동안 '진짜 벌레(bug)'가 들어가 오류를 발생시킨 것에서 유래되었다.
버그는 여러 이유로 발생할 수 있는데, 크게 2가지로 볼 수 있다. 문법상 또는 기능상의 오류인 코드 오류와 기능적으로는 잘 돌아가지만 원하는 결과가 나오지 않는 논리적 오류이다. 전자는 컴퓨터가 에러 메세지를 띄워주므로 쉽게 알 수 있다.
후자는 상황에 따라 다르다. 코드가 단순할 때는 찾기가 쉽겠지만, 복잡하다면 눈알이 빠질 위기에 처하거나 모니터를 부수고 싶은 충동에 휩싸인다. 이럴 때 확인할 수 있는 단순한 방법은 의심되는 기능 주위에 출럭 함수를 난사하는 것이다. 예를 들면, 아래 코드처럼 할 수 있다.
#include <stdio.h>
int main(void)
{
for (int i = 2; i <= 10; i++)
printf("i = %i", i) // debuging 함수
{
for (int j = 1; j <= 9; j++)
{
printf("j = %i", j) // debuging 함수
printf("%i * %i = %i\n", i, j, i * j);
}
printf("\n");
}
}
2단부터 9단까지 출력하는 것이 목적이었지만, 해당 코드는 10단까지 출력한다. 이때 사이사이 끼워놓은 출력 함수를 보고 어디가 원인인지 파악할 수 있다. 찾고 나면 버그 코드를 고치고 디버깅 함수를 지우면 된다. 그러나 매우 불편한 방법임이다. 복잡하고 많은 양의 코드라면 이것이 얼마나 귀찮겠는가. 이럴 때 세상이 좋아짐에 만세를 부르게 된다. 우리가 보통 코딩할 때 사용하는 툴, IDE(Integrated Development Environment, 통합 개발 환경)에서 Debuging을 제공한다.
빨간색 정지 버튼 같은 점은 Break Point(중지점)로 상위 코드가 쭉 실행되다 저기서 멈춘 후 한 단계씩 로직이 어떻게 실행되는지 확인할 수 있다. 굳이 출력 코드를 썼다 지웠다할 필요가 없다.
(3) 코드의 디자인
코드 작성만큼 테스트도 중요한데, 이유는 버그 발생을 최소화하고 내가 원하는 결괏값을 얻기 위해서이다. 그 과정에서 코드 몇 줄로 해결될 일을 수십 줄로 늘려 메모리를 낭비할 필요는 없으니까.
스타일 측면도 중요하다. 바로 가독성을 의미하는데, 그래야 협업이나 유지보수에 용이하기 때문이다.
#include <cs50.h>
#include <stdio.h>
int main(void){int n = get_int("n: ");if (n % 2 == 1){printf("odd\n");}else{printf("even\n");}}
입력값의 홀수와 짝수를 구분하는 간단한 코드지만, 한 줄로 적어 놓으니 눈이 불편하다. 실행에는 문제가 없지만, 다음에 코드를 고치거나 참고할 때 눈에 확 들어오지 않는다. 유지보수의 편의성과 직관성, 나아가 내 눈의 피로도까지 감안한다면 코드를 정리하여 가독성을 높이는 편이 나을 것이다.
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int n = get_int("n: ");
if (n % 2 == 1)
{
printf("odd\n");
}
else
{
printf("even\n");
}
}
눈도 속도 편안하다. 개행이나 들여쓰기를 습관화하자.
Author And Source
이 문제에 관하여([CS50] 3-0. Prequel), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@real-bird/CS50-3-0저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)