프로그래밍 언어
코드를 해석하는 방식에는 두 가지가 있다.
컴파일러 언어
코드 전체를 한 번에 해석하여 실행할 수 있는 파일로 변환한다. 코드를 해석하는 것을 컴파일이라고 하며, 컴파일러 언어는 컴파일 단계와 실행 단계로 분리되어 있다.
장점
- 실행할 때는 컴파일 없이 실행만 하면 되므로 코드 실행 속도가 빠르다.
- 컴파일러 언어는 개발자가 메모리 관리와 CPU 사용 같은 HW 측면에서 더 많은 제어 권한을 가진다. 따라서 자원을 효율적으로 관리할 수 있다.
단점
- 코드에 변경 사항이 있을 때마다 빌드를 다시 해야 한다. 빌드는 소스코드를 이진코드로 변환하는 컴파일 과정과 실행 파일을 만드는 과정인 링크를 묶어 부르는 말이다.
- 컴파일러 언어는 컴파일 시 지정된 플랫폼에 최적화되도록 만들어지기 때문에 플랫폼에 제약이 있다. 다른 플랫폼에서 실행되도록 하러면 다시 컴파일해야 한다.
인터프리터 언어
소스 코드를 컴파일 하지 않고, 코드를 한 줄씩 해석해서 바로 실행하는 언어이다.
장점
- 빌드 과정이 없고, 바로 실행할 수 있기 때문에 코드 수정이 자유롭다.
- 플랫폼에 독립적이므로 각 플랫폼에 지원하는 인터프리터만 있으면 실행 가능하다.
단점
- 실행 속도가 비교적 느리다.
- 한 줄씩 읽으면서 바로 실행하기 때문에 프로그램 실행 전에 버그를 발견하기 어렵다.
C언어
#include <stdio.h>
int main(void)
{
return 0;
}
- include는 라이브러리를 포함시킨다는 의미다. <> 안에 라이브러리의 이름을 적으며, stdio.h는 standard input output의 약자이다. 이 라이브러리를 포함시키면 입출력에 사용하는 함수인 printf와 scanf를 사용할 수 있다.
- 위의 코드는 main이라는 함수이다. main이라는 함수는 특별하기 때문에 프로그램 전체에서 단 하나의 main 함수만 존재해야 한다.
- return은 함수의 수행을 끝내겠다는 의미와 이 값을 외부로 전달하고 싶을 때 사용한다. 리턴 값은 함수 앞에 명시되어 있는 자료형과 일치해야 한다. main 함수에서의 return 0은 이 프로그램이 에러 없이 끝마쳤음을 의미한다.
변수
변경이 가능한 수로, 어떤 값이 들어갈지 예측할 수 없다.
우리가 원하는 데이터가 어디에 저장되어 있는지 기억하는 것보다 의미 있는 이름을 기억하는 게 더 쉽다. 그래서 사용할 메모리 공간에 이름을 부여하고 우리는 그 이름을 사용하는 것이며, 사용할 메모리 공간에 이름을 부여한 것이 변수이다.
메모리 영역
영역 | 설명 |
코드 영역 | 실행 명령어들을 저장한다. |
스택 영역 | 지역 변수 및 매개 변수를 저장한다. 선입후출인 FILO 구조이다. |
힙 영역 | 프로그래머가 직접 할당한다. 선입선출인 FIFO 구조이다. |
데이터 영역 | 전역 변수와 static 변수를 저장한다. |
코드 영역
소스코드가 저장되는 곳이다. 컴퓨터가 실행해야 할 명령어들이 적혀있다.
스택 영역
지역 변수와 매개 변수 등은 모두 스택 메모리를 사용한다. 아래 그림에서 지역 변수는 b, c, d이고, 매개 변수는 a이다.
콜스택, 메모리 힙의 데이터 저장 구조
- 원시 타입 데이터: 일반적인 정수, 실수, 문자 같은 데이터를 말한다.
- 참조 타입 데이터(=포인터): 배열, 구조체 등을 가리키는 변수를 말한다.
아래 그림에서 원시 타입 데이터는 a이고, 참조 타입 데이터는 b와 c이다.
원시 타입 변수에는 해당 데이터가 저장되어 있는 주소 값이 저장되어 있고, 해당 데이터 값은 스택에 저장된다.
참조 타입의 경우, 해당 데이터가 heap 메모리의 어디부터 시작인지에 대한 주소 값이 스택에 저장되어 있고, 해당 주소 값이 적힌 스택의 주소가 참조 타입 변수에 저장된다.
원시 타입 재할당
원시 타입 변수를 생성한 상태가 왼쪽과 같다고 해보자. 여기서 변수 a의 값을 20으로 수정했다.
그러면 오른쪽과 같이 변수 a에는 기존에 20을 저장하고 있는 메모리의 주소 값이 저장된다. 본인의 가리키고 있는 메모리에 저장된 값이 바뀌는 것이 아니다.
이제 변수 b를 30으로 재할당 해보자.
30은 없던 값이기 때문에 새로운 메모리를 확보하여 30을 저장하고, 변수 b가 가리키는 주소 값을 교체한다. 10이라는 값은 사용되고 있지 않으므로 가비지 컬렉터가 해당 값을 제거하여 메모리를 회수한다.
자료형
선언한 변수가 어느 정도의 메모리를 할당할 것인지 결정하는 것을 말한다.
위 표는 C언어의 자료형 종류이다. 같은 종류라도 다양한 자료형을 제공하는 이유는 메모리 크기를 보면 알 수 있듯이, 메모리 공간을 효율적으로 사용하기 위함이다.
학생들에게 8자리 정수형 학번을 부여한다고 가정해보자. 모든 학번은 int형으로 표현할 수 있기 때문에 굳이 메모리를 더 많이 차지하는 long long int형을 사용할 필요가 없다는 것이 그 예시다.
상수
변하지 않는 수로, 메모리 공간에 존재하지만 그 값을 변경할 수 없다. const 키워드를 사용하여 상수를 선언할 수 있다. 값이 바뀌면 안 되거나 바뀔 일이 없는 경우 const로 선언하는 것이 좋다.
const int NUM = 10;
데이터 입력
아래 코드는 C언어에서 사용자로부터 데이터를 입력받는 코드이다. scanf 함수를 사용하여 입력받을 수 있으며, 사용자가 작성한 데이터가 우리가 명시한 서식 문자열에 맞춰 작성한 변수의 주소값에 차례대로 들어간다.
#include <stdio.h>
int main()
{
int num;
char ch;
scanf("%d %c", &num, &ch);
printf("입력받은 정수: %d, 문자: %c", num, ch);
return 0;
}
배운 점
- 컴파일 언어는 코드 전체를 한 번에 모두 해석하여 실행 파일을 만들고, 인터프리터 언어는 코드를 한 줄씩 해석해서 바로 실행한다.
- 메모리 영역에는 소스코드가 저장되는 코드 영역, 지역 변수와 매개 변수가 저장되는 스택 영역, 동적으로 할당되는 값이 저장되는 힙 영역, 전역 변수와 static 변수가 저장되는 데이터 영역이 있다.
- 데이터 타입에는 원시 타입과 참조 타입이 있으며, 원시 타입 데이터는 스택에, 참조 타입 데이터는 힙에 저장된다.
- 변수에는 값이 저장되는게 아니라 그 값이 저장되어 있는 메모리 주소가 저장되어 있다.
- 원시 타입 데이터를 재할당 할 때 메모리에 있는 값을 변경하는 것이 아니라, 주소 값이 재할당할 값을 가지고 있는 메모리 주소 값으로 변경된다.
'데브코스' 카테고리의 다른 글
[10주차 - DAY1] C언어 연산자, 분기문, 반복문 (0) | 2024.04.29 |
---|---|
[10주차 주간 발표] 동적 라우팅과 다익스트라 알고리즘 (0) | 2024.04.27 |
[9주차 - DAY3] 코드 퀄리티 & 랜덤 데이터 API (0) | 2024.04.24 |
[9주차 - DAY2] jwt 확인과 pagination (0) | 2024.04.23 |
제발 정렬 좀 시켜달라고 (0) | 2024.04.22 |