나는 지금 이지스퍼블리싱에서 발간한 'C언어 입문'책을 3학년 1학기에 듣는 자료구조에 대비하기 위해서 복습하고 있다.
2회독이고 파이썬으로 코딩을 쫌 하다 보니 11장까진 무난해서 쭉 복습을 진행했다 2번 혹은 3번에 나눠서 이를 정리할 예정이고,
내 생각에 그때 그때 찾아봐도 괜찮을 것 같은 내용은 뺐다
어차피 다시 봐야하니깐 미련두지 말자
(내 1전공인 수학과 동기들이 공부할 자료기에 좀 알아듣기 쉽게 자세히 적겠다)
C언어는 만들어진지 오래됐고 어셈블리어(기계어)에 가까운 언어이다. 그 당시에는 하드웨어가 현재처럼 발달하지 않았고, 따라서 개발자가 메모리를 어떻게 하면 효율적으로 쓸 수 있을지에 대해서 고민했다고 들었다.
그래서 그런지 C언어는 이런 자료형을 여러가지로 만들어 놨는데, 구분하자면 크게 3가지로 나눌 수 있겠다.
unsigned int Number = 3 //이때 long은 기본값(default 값)이기 때문에 생략이 가능하다
short int Number = 3 //이때 signed는 기본값(default 값)이기 때문에 생략이 가능하다
→ 4장은 위에서 변수를 초기화하는 방법과 10진수 8진수 16진수에 관해서 설명하고 있는데 나중에 필요하다면 책을 참고해 보길 바란다. 현재 빠르게 복습하는 과정에선 불필요하다고 느껴진다
책에 비해서는 매우 간단하게 설명을 진행하겠다.
먼저, 함수의 필요성에 대해서 말을 시작해보자. 함수는 왜 필요할까?
우리가 덧셈을 한다고 해보자 만약 덧셈을 할때마다 4+5 이렇게 해도 괜찮다. 하지만 더 복잡한 행위를 정의해놓는다면 그것을 사용할때마다 일일히 치지않고 편하지 않을까? 당연하다 이는 물론이거니와 유지보수도 훨씬 편할 것이다. 그래서 함수를 사용하는 것이고 C언어로 작성된 코드는 이런 함수들의 집합체라고 할 수 있다.
함수를 정의 하는 방법에 대해서 소개하겠다 함수는 다음과 같은 방법으로 정의한다
(return시 반환될 반환형) 함수이름(함수에 넣을 인자){
}
Ex>
Void main(int Number1, Float Number2, Char Number3){
}
위에서 Ex>로 보여준 main함수는 C언어에서 있는 고유의 함수이다 모든 C언어 프로그램은 main이라는 함수를 시작함수로 정해놓고 이어 나간다. 또 하나 C언어를 작성할때 규칙이 있는데 main 시작 함수 이외에 함수를 정의할때는 main함수 위에 정의를 해놓아야 한다는 것이다.
예를 들어, 덧셈함수를 정의해보자.
#include <stdio.h>
int sum (int value1, int value2){
int value = value1 + value2;
return value;
}
void main(void){
int result = sum(3,5);
printf("this is result %d",result);
// return 0; 보이드 형식으로 정의한 함수 뒤에 return을 넣으면 오류로 처리된다
// 하지만 return뒤에 아무것도 적지 않고 return;이면 오류가 발생하지 않고 함수를 끝내기만한다
}
위의 함수를 이해한다면 오늘 완벽히 이해한 것이다 하나씩 뜯어보겠다
먼저 위에 헤더파일 <stdio.h>를 include를 했다 이는 C언어 표준 라이브러리 함수이다.
뭔가 굉장히 많은 모르는 말이 지나갔는데 그냥 읽고 넘겼을 것이다 여기서 잠깐 6장 내용으로 넘어가겠다
실행파일이 만들어지는과정
→ 실행파일(.exe)가 어떻게 만들어지는지 설명해보겠다.
기본적으로 다음과 같고 앞에 두단계를 거친 여러 목적파일을 연결해 하나의 실행파일을 만드는 것이다.
[컴파일전 .c 파일] → [컴파일후 기계어로 된 .obj 목적파일] → [이러한 목적파일이 합쳐진 실행파일.exe]
위와 같다. 그렇다면 실행파일을 만들때 어떤식으로 만들면 시간이 덜 걸릴까 당연하게도 컴파일하는 과정을 뺀 목적파일이 많이 구성돼 있으면 구성돼 있을수록 실행파일이 더 빨리 만들어질 것이다. 그러기 위해서는 목적파일로 미리 몇몇 파일은 만들어놓고 실행파일을 만들때 연결을 지어야지 빠를텐데 따라서 몇몇 유지보수할 필요가 없는 자주사용하는 함수들은 목적파일로 바꿔놓으면 좋을 것이다. 그런데 이 처음부터 목적파일이었던 파일과 컴파일후 목적파일로 된 파일을 연결짓는 과정에서, 처음부터 목적파일로 만들어놓은 파일중 일부 함수는 사용하지 않는데도 연결지어버렸기 때문에 실행파일에 사용하지 않는 함수들도 포함돼있다
이를 해결한게 라이브러리 파일이다 이 목적파일을 library 파일(.lib) 로 변환시켜두면 필요한 함수만 라이브러리 파일에서 뽑아서 쓰면 되는 것이다.
Tip> 특히 Python에서는 무수히 많은 라이브러리 파일이 있고 여기서 확실하게 알아두고 가는 것을 추천한다
헤더 파일이란 무엇일까?
위에서 #include <stdio.h>
를 보았을 것이다 이게 무엇인지 궁금할테다.
우리는 위에서 라이브러리 파일을 보았다. 우리가 이 라이브러리 파일과 object 파일에 Add()함수 Sub() 함수를 정의해놨다고 해보자 따라서 우리는 우리가 지금 작성중인 코드에 Add(1,3)
을 추가했다고 해보자 과연 잘 돌아갈까?
정답은 아니다 왜냐하면 우리가 지금 작성하고 있는 파일에서는 Add함수가 어떻게 생겨먹었는지 모르기 때문이다.
따라서 우리는 Add라는 함수는int Add(int n1, int n2)
라고 우리가 작성하고 있는 코드에 선언을 해줘야 한다. 하지만 라이브러리 파일에 있는 함수를 사용할때마다 선언을 해주어야 하는 것에 불편함을 느꼈고 따라서 이런 함수 원형을 모아두고 선언해서 사용하는데 이를 헤더파일(*.h)라고 한다 한마디로 라이브러리 설명서라고 생각하면된다. 따라서 우리는 라이브러리에 있는 함수를 사용하기전에 이런 헤더파일을 먼저 읽게 하는 것이다.
헤더파일을 읽게하는 방법은 전처리(preprocessing)를 하는 방법인 #을 사용해서 하는 것이고 다음과 같이 한다
#include <stdio.h>
stdio.h라는 헤더파일을 포함한다는 것이고 stdio.h는 vscode,visual studio에서 경로를 알고 있기 때문에 꺽쇠를 사용해서 포함하고
만약 우리가 직접 헤더파일을 만드는 경우 다음과 같이 큰 따옴표"" 를 사용한다
#include "C:\users\Cworking\my.h"
우리는 전처리를 하면서 #을 사용한다고 했다. 이렇게 전처리를 하는 것에는 다음과 같이 상수를 치환하는 것도 있고 간단한 함수를 치환할 수도 있다
#define MAXCOUNT 3
← 우리는 이 소스파일에 있는 MAX_COUNT라는 이름을 모두 3으로 치환할거야
#define PowValue(a) a*a
← 우리는 이 소스 파일에 있는 PowValue(a)라는 이름을 모두 a*a로 치환할거야
#include <stdio.h>
int sum (int value1, int value2){
int value = value1 + value2;
return value;
}
void main(void){
int result = sum(3,5);
printf("this is result %d",result);
// return 0; 보이드 형식으로 정의한 함수 뒤에 return을 넣으면 오류로 처리된다
// 하지만 return뒤에 아무것도 적지 않고 return;이면 오류가 발생하지 않고 함수를 끝내기만한다
}
이제 다시 위로 돌아오자 이제 많은 것들이 보일 것이다 위에서 말했듯이 시작함수인 main함수부터 시작을 할 것이다 여기서
main앞에 있는 void는 반환 자료형이고 우리가 현재 반환하는것이 없다는 것이다 또 main(void)에서 void는 인자로 받는것이 없다는 뜻이다.
result라는 변수를 초기화 하면서 위에서 정의해둔 sum 함수를 호출 했는데 sum함수에서 게산을 쭉 한 이후에 계산한 값인 value를 return해주면서 result 변수를 value값으로 초기화 했다.
그 이후 printf라는 함수를 호출했는데 여기서 printf는 stdio.h라는 헤더파일에 미리 함수 원형이 저장돼있다 또 printf는 C언어 컴파일러를 만든 회사가 만들어놓은 C표준 라이브러리에 저장돼있다.
다음시간에는 배열과 포인터 전까지 블로그를 작성해보겠다
출석 check
함수의 구조와 함수원형 부분을 읽고 잘 몰랐던 내용을 확실하게 이해할 수 있었습니다!!