C 언어 기초 공부

HEYDAY7·2021년 6월 10일
0

아주 더럽지만... 학교 수업에서 들은 C에 대한 내용을 정리 없이 적어둔다

시작

Low-level language 에서는 value의 의미가 아니라 어디에 저장되어 있는지가 중요!
High-level language 에서는 symbolic한 name으로 value를 나타냄

  • abstraction : underlying hardware에 상관 없이 동일한 interface를 갖는다. 그 기저에 깔린 것을 알아서 처리해준다.
  • maintainability : 유지보수도 좋음
  • Safeguards : bug가 날 것 같은 걸 미리 말해준다.

High-Level Langauges로 program 짠거를 번역해주는 법 machine code로

  • Interpreter ( program )
    -- line by line으로 받아서 해석해줌(a set of commands)
    -- 한줄씩 받아서 실행,
    (ex. 파이썬)
    -- 장점 : 개발과 디버깅이 쉽다.
    -- 단점 : 실행이 느리다. 번역을 매번 다시하기에

  • Compiler ( program )
    -- 전체 program(entire)
    -- execution이 없음. machine language로 된 실행 파일을 뱉어준다. (.exe, executable image)
    (ex. C언어, compiler를 돌려서 exe파일을 만들고, 그 후 실행)
    -- 장점 : 번역이 이미 끝나있어, 실행이 매우 빠르다!!, memory efficient하다.
    -- 단점 : 코드가 하나라도 틀리면 실행조차 되지 않는다. 번거로움!!!

C Compiler

Preprocessor

  • 소스 코드와 hearfile을 가져온다
  • preprocessor를 다 없애준다. #include 같은거 코드를 진짜 가져와 버리고, # define DAYS 30 같은거에서 영어 다 없애고 진짜 숫자로 바꿔버림
  • 지저분하고 복잡한 C가 된다.

Compiler

  • preprocessed된 C를 받는다.
  • C언어를 ISA로 바꿔준다. C 파일 하나마다 object file을 하나씩 만들어줌.

Linker

  • 여러 object file들을 다 묶어 하나의 exe 파일을 만들어준다.

GCC 라는 것을 이용하여 compile 할 수 있다.

C 시작

  • int main(void)
    -> output 은 int, 함수 이름 main, input 받지 않음(void)

  • 하나의 statement 마다 ;를 써야한다.

  • preprocessor ( #include )
    세미콜론 필요 없고, compiler로 넘길때 preprocessing 과정에서 다 제거가 된다. #include <stdio.h> 뜻은 stdio.h 라는 곳의 코드들을 모두 붙혀넣어주세요~ 라는 뜻

  • #define aaa 10
    aaa라는 변수명에 10이라는 숫자를 넣는다. aaa는 symbolic한 name이 되고, 나중에 compiler가 aaa를 모두 10으로 바꿔주게 된다. 프로그램 내에서 constant를 정의할 때 사용한다.

  • Variables
    data type이 매우 중요하다. type 정의가 중요한 언어가 C이고, type에 따라서 compiling 과정에서 동일한 operator라도 번역되는 코드가 달라지기 때문이다.
    만약 initializer가 없다면 global variable은 0으로, local variable은 garbage value로 initializer 된다.
    -- int, char, bool, float, double
    -- "const"를 쓰면 변화불가능하게 만들 수 있다.

sizeof 함수의 경우 byte의 크기를 나타내준다.

  • Scope
    어느 block이냐에 따라서 정해짐

C memory model

위아래로 System space가 있다.
그 다음은 Program text
그 다음은 Global variable
Local variable은 매우 유동적이다. 어떤 함수가 실행되느냐에 따라 다르다. run-time stack 구조!

즉 global variable은 제일 주소가 작은 거에서 시작해서 점점 증가하고 local variable은 제일 주소가 큰 것에서 점점 감소한다.

  • pointer의 개념!!!!
    stack pointer : stack이 끝나는 지점!
    frame pointer : memory 에서 현재 실행중인 함수가 시작되는 지점!

function

함수를 정의하는 구조는 다음과 같다.

datatype name(parameter)

  • data type : return되는 친구의 타입
  • name : 함수 이름
  • parameter : 들어가는 input

Declaration!!
함수를 미리 define할 필요는 없고, declaration만 미리 해주면 자유롭게 쓸 수 있다.

pointers and array

call by value!!! 단순히 값을 복사하는 것이고, 다른 memory object라고 볼 수 있다. 즉 영향을 서로 주지 않는다.
이를 극복하기 위해서 pointer라는 개념이 등장한다

  • pointer는 memory object의 주소를 담는다!!!
    <type> *<name>
    ex) int *ptr -> ptr의 값을 따라가서 확인해보면 integer가 있을 거다!!

& 를 통해서 한 variable의 주소를 가져올 수 있다.

int intVariable = 10;
int *intPtr;
intPtr = &intVariable;

이렇게 되면 intVariable을 10이고, intPtr은 intVariable의 주소를 나타낸다. 만약 intPtr의 값에 접속하고 싶다면 *intPtr을 하면 된다.
--> 따라서 pointer를 사용해서 함수를 콜하면? call by reference 이다!!

etc

Null pointers 도 있다.

int *ptr;
ptr = NULL;

Array

비슷한 데이터가 sequentially 저장되어 있는 것. 기억해야 하는 것은 메모리 공간에 주소가 작은 곳 부터 하나씩 차근차근 저장됨.
C의 array는 하나의 data type만 저장 가능. fixed size!
int values[10];의 의미는 길이가 10인 array가 생기며 모두 int type을 담을 수 있다. 각 data의 접근은 values[0~9]로 하게 되며, values에는 array의 주소가 담기게 된다.
!! 특징 : 그냥 array의 주소는 결국 array의 첫번째 element의 주소와 동일하다.

  • String Array!!!!
    string aray의 경우 끝나는 지점을 알려줘야 한다. 마지막에 '\0'을 넣어줘야 한다. 이러지 않으면 쓰레기 값들이 들어간다.
    -> 따라서 결국 만약 10자리 string을 array에 저장하고 싶다면 최소 array는 size가 11은 되야 한다!!

  • Multi-dimensional Array
    int image[640][480]

Structure

class와 비슷한데 좀 다르다...
struct라는 data type을 사용하고 중괄호를 묶는다

struct studentType {
  char name[10];
  int midterm;
  tin final;
  int total;
};

단순히 class와 비슷하지만 method가 없다!!! variable의 조합만 담고 있는 것이 structure. 이렇게 만든 struct를 custom type이 만들어 진 것이라고 생각하면 편하다.
struct studentType studentA; 를 하면 'struct studyentType'이라는 type을 가지는 studentA가 선언된다.


  • 이를 더 깔끔하게 사용하기 위해서 typedef 라는 방식이 있다.
    typedof <type> <name>
    이 의미는 'type'이라는 type을 'name'이라는 custom 이름으로 그 type을 만들어서 사용하겠다!

Arrays vs. Linked Lists

C의 Array의 경우 run-time stack을 사용하여 저장한다.
Linked list의 경우 Heap을 이용해서 저장한다.

Stack

  • grow upwards
  • 자동으로 variable들을 자동으로 넣다 뺀다.
  • local variable access
  • faster and no fragmentation

Heap

  • grow downwards
  • 프로그래머가 직접적으로(manually) 넣거나 빼야한다.
  • global variable access
  • slower and fragmented

-> dynamic memory allocation "malloc" function
memory size를 byte로 받는다.

  • allocation
int *intPtr;
intPtr = (int *) malloc(sizeof(int)); 
char *cPtr;
cPtr = (char *) malloc(sizeof(char));
  • deallocation
free(intPtr);
free(cPtr);

LinkedList

profile
(전) Junior Android Developer (현) Backend 이직 준비생

0개의 댓글