작성한 코드가 실행파일이 되기 까지
전처리(preprocessing) → 컴파일링 (compiling ) → 어셈블링(asembling ) → 링킹(linking)
- 전처리 : 컴파일 전 #로 시작되는 소스 코드를 먼저 실행함. #include는 전처리기에 다른 파일의 내용을 포함시키라고 알려줌. 라이브러리 파일도 c로 작성되어있다고?
- 컴파일 : c코드를 컴퓨터가 이해할 수 있는 어셈블리 코드로 변화시킴. (소스 코드 → 어셈블리 코드) 이 작업을 처리하는 프로그램은 컴파일러라고 함.
- 어셈블링 : 실제 0과 1로 이루어진 코드로 처리해줌. (어셈블리 코드 → 오브젝트 코드) 이 작업을 처리하는 프로그램은 어셈블러라고 함.
- 링크 : 만약 프로그램이 math.h나 stdio.h같은 여러 개의 파일을 포함하고 있다면 하나의 오브젝트 파일로 합치는 작업을 해야함. 이게 바로 링크.
💡 만약 컴파일링 과정을 거치지 않기 위해 바로 머신코드로 우리가 원하는 프로그램을 작성하려고 한다면 어떤 문제가 있을까요?
⇒ 머신 코드는 0과 1로 작성되어있으니 인간이 프로그램을 작성하는 데에 매우 비효율적일 것이다.
- 버그(bug) : 코드의 오류를 의미함. 그레이스 호퍼라는 컴퓨터 과학자가 컴퓨터 내에서 벌레(=버그,bug)를 찾은 것에서 유래함.
- 디버깅(debugging) : 디버깅은 코드 안의 버그를 찾고 고치는 과정을 말함.
* CS50 샌드박스에서 디버깅하려면 help50 make filename 의 형태로 명령어 입력
* 명령어 clear는 콘솔창 이력을 지워서 깨끗하게 만듬
* CS50 IDE에서는 명령어 debug50으로 디버깅 가능. ex) debug50 ./buggy2
* 디버깅 종료는 Crtl + c
코드 왼쪽의 빨간 점은 중지점(break point)로 현재 실행 부분을 알려줌. 디버깅 단계에서는 코드를 하나씩 확인함으로써 잘못된 부분을 찾을 수 있다. 화면 오른쪽에 보이는 게 디버거인데 컴퓨터 메모리 안에서 일어나는 일들을 보여줌.
💡 디버깅을 도와주는 프로그램은 어떤 경우에 더 큰 도움이 될까요? 만약 이런 프로그램의 도움 없이 직접 디버깅을 해야 한다면 어떻게 코드를 작성하는 것이 좋을까요?
⇒ 놓치기 쉬운 부분을 디버거로 확인할 수 있으니까, 코드를 길게 작성했을 때 더 큰 도움이 될 것 같음.
만약 직접 디버깅을 해야 한다면 주석으로 코드의 어느 부분이 어떤 역할을 하는 지 표시하고, 메모리 내에서 일어나는 일을 확인할 수 있는 코드를 작성해두면 좋을 것 같음. (예를 들면, for문 안에서 변경되는 i값을 출력하도록 printf("%d", i); 작성하기)
https://cs50.readthedocs.io/style/c/
위 링크에 들어가면 CS50에서 작성한 스타일 가이드를 볼 수 있다.
주위에 마땅히 설명할 사람이 없을 때 눈앞에 고무오리를 두고 내가 작성한 코드에 대해 설명해보는 것. 이 과정에서 문제가 뭔지 발견할 수 있다. 그래서 고무 오리 디버깅이라고 하는 것.
💡 만약 여러 사람들이 함께 참여하는 프로젝트에서, 각자가 작성하는 코드 스타일 서로 다르다면 어떤 비효율적인 일이 발생할까요?
⇒ 서로의 코드를 이해하기 힘들고 프로젝트 전체의 효율이 떨어질 것이다.
C언어에서 각 자료형이 차지하는 크기는 아래와 같다.
* 참고로 1 byte = 8 bit
- bool : 불리언, 1 byte
- char : 문자, 1 byte
- int : 정수, 4 byte
- float : 실수, 4 byte
- long : (더 큰) 정수, 8 byte
- double : (더 큰) 실수, 8 byte
- string : 문자열, ? byte
컴퓨터 안에는 RAM이라는 칩이 메모리 역할을 함.
메모리를 이미지화 하면 저렇게 여러 칸으로 나눠져있다고 생각할 수 있음. 이 때, 한 칸 = 1바이트
예를 들어, HI! 라는 문자들을 메모리에 저장한다고 해보자. H, I, !는 아스키 코드에서 지정된대로 72,73,33라는 정수의 형태로 컴퓨터에 저장된다. 알다시피 컴퓨터에서는 모든 걸 이진법으로 표현하기 때문에 실제로는 72,73,33를 이진법으로 바꾼 값이 한 칸씩 저장된다.
💡 실생활의 어떤 데이터를 배열로 표현할 수 있을까요?
⇒ 학생들의 성적, 키나 몸무게 실험을 통한 관측 데이터 등
실제로 데이터를 계산 처리할 때 배열에 집어 넣는 경우가 많음.
* 변수가 바뀌는 걸 원하지 않는다면 자료형 앞에 const를 적음. 그리고 관습적으로 변수는 대문자로 적음.
const는 상수인데 말그대로 변하지 않는 값임.
ex) const int N =3;
* 전역 변수 : 함수 바깥에서 선언하는 변수
💡 점수의 평균을 구하는 예제에서, 동적으로 작성한 코드는 그렇지 않은 코드에 비해 어떤 장단점이 있을까요?
⇒ 동적으로 작성한 코드는 데이터를 새로 입력받을 수 있기 때문에 그렇지 않은 코드에 비해 더 활용도가 높다. 하지만, 코드가 조금 더 복잡해진다는 단점과 입력값이 잘못되면 에러가 날 위험도 있음.
문자열은 정해진 크기가 없음.
- 배열의 이름 : 배열의 시작 위치를 알려줌
- 널 문자(\0) : 배열의 끝나는 위치를 알려줌. printf 함수는 널문자를 만나면 출력을 종료한다.
- 배열의 인덱스 : array[0] 괄호 안의 숫자가 인덱스를 나타냄
문자열이 끝나는 곳을 알아야 하기 때문에 (안그러면 다르 변수와 구별이 안되겠죠?) 문자열은 늘 문자수+1만큼 자리를 차지함.
💡널 종단 문자는 왜 필요할까요?
⇒ 문자열이 끝나는 곳을 알기 위해서! 다른 문자열 혹은 변수와 구별하기 위해서 필요한듯. 널 종단 문자가 없으면 지정된 범위를 초과해서 출력하는 오류를 범하겠죠?
명령행 인자의 예시 : -o
argc와 argv는 main함수의 인자로 쓰인다.
argc : 커맨드 창에서 입력받은 단어의 개수가 저장됨.
argv[] : 커맨드 창에서 입력한 문자열을 저장함.
💡 명령행 인자는 프로그램의 확장성에 어떤 도움이 될까요? 구체적인 예시를 떠올려보세요.
⇒ 명령행 인자를 쓰면 내부에 코드를 쓰지 않아도 데이터를 입력받을 수 있다는 점에서 더 편리해보임.
명령행 인자를 이용하면 동적으로 값을 받을 수 있으니까 그에 따라 실행되는 코드를 다르게 하는 등 더 유용한 프로그램을 작성할 수 있다.
부스트코딩 뉴비챌린지 스터디 5주차 : 메모리, 포인터 (0) | 2020.09.06 |
---|---|
부스트코딩 뉴비챌린지 스터디 4주차 : 구조체 (0) | 2020.09.05 |
부스트코딩 뉴비챌린지 스터디 4주차 : 알고리즘 (0) | 2020.09.05 |
부스트코딩 뉴비챌린지 스터디 2주차 : C언어 (0) | 2020.08.13 |
부스트코딩 뉴비챌린지 스터디 1주차 : 컴퓨팅 사고 (0) | 2020.07.14 |
댓글 영역