[TIL] WEEK04 - C언어 keywords(1)

woo__j·2024년 4월 20일
0

TIL - Today I Learned

목록 보기
13/23

C언어는 '절차지향적' 언어, 차례로 소스 코드를 해석&실행함

1. 선언(declaration)과 정의(definition)의 개념

: 가장 큰 차이점은 메모리 할당의 여부

  1. 선언(declaration)
  • 컴파일러에게 변수의 정보만 줌
  • 실제 메모리 사용X, 어떠한 변수가 있다는 정보만 있고 실제 데이터는 없음
  1. 정의(definition)
  • 컴파일러에게 실제 변수를 생성하도록 함
  • 실제 메모리 사용O
    -> 그니까 난 a라는 변수를 쓸거야! 미리 선언하고, a는 x라는 값을 가지고 있어 정의해주는 느낌

2. 전방선언(forward declaration)

실제로 식별자를 정의하기 전에 식별자의 존재를 컴파일러에게 미리 알리는 것
함수의 경우 전방선언을 하려면 함수 원형으로 사용해야 한다
전방선언을 할 경우 클래스의 존재만 인지시키는 것이기 때문에 포인터로밖에 선언하지 못 함

*사용하는 이유?
: 참조하려는 헤더파일에 변경이 생겨도 헤더파일의 재컴파일이 이루어지지 않기 때문에 효율성/속도 향상, 역참조가 되는 구조를 막기도 함

3. static & extern

  • 전역변수: 함수 본문 밖에서 선언한 변수 (어디서든 접근 가능, 스택 메모리 아닌 데이터 섹션에 들어감)
  • 지역변수: 함수 본문 내에서 선언한 변수 (함수가 끝나면 실제 메모리에서도 사라짐)
  1. static: 한 파일 내에서만 쓰고 싶은 전역 변수/함수 선언
  • 함수 내 지역변수로 사용된 static 변수는 함수 내에서만 접근이 가능하지만, 함수가 리턴되어도 값이 초기화되지 않음
  1. extern: 여러 파일에서 사용하고 싶은 변수/함수를 선언
  • 헤더에 extern 변수를 선언하고 해당 헤더를 include하면 모든 파일에서 접근 가능

+) const: 상수 선언 키워드로, 변수의 값을 변경할 수 없도록 함

4. 컴파일과 링크를 통해 실행파일이 만들어지는 과정

: 소스파일(.c) -> 컴파일 (.obj) -> 링크 (.exe)

  1. 전처리: 소스코드를 처리하기 쉽게 재구성하는 과정 (헤더 파일을 현재 소스파일에 붙이는 역할)
  2. 컴파일: 소스코드를 컴퓨터가 읽고 처리할 수 있게 기계어로 변환하는 것 (.obj 파일 생성)
  3. 링크: 실행 프로그램을 만들어주는 과정
    (실행에 필요한 obj파일이나 라이브러리 파일들을 묶어 최종 실행파일로 만들어줌 -> .exe 실행파일 생성)
  4. 빌드: 컴파일+링크 작업

5. 포인터

: 메모리 주소값을 저장하기 위한 변수

  • 주소를 이용해 간접적으로 원본에 직접 접근한다

    • 값에 의한 전달: 원본이 바뀌지 않음
    • 참조에 의한 전달: 원본이 바뀔 수 있음
  • 포인터 변수의 자료형은 해당 주소에서 몇 바이트를 읽어야하는지 알려줌

  • 주소 연산자 &:저장된 메모리 주소를 가져오는 연산자

  • 참조 연산자 *: 포인터 변수가 개체를 가리키고 있다면, 개체가 어떤 값을 갖는지 접근

    • 역 참조연산자를 통해 값 변경도 가능
  • 다중 포인터: 포인터의 포인터, 주소를 저장하는 변수의 주소를 저장하는 변수

ex)
int num = 10;
int* p = #
int** pp = &p;

num = 10
p = num 변수의 메모리 주소 값
*p = p가 가리키는 주소에 있는 값, 즉 num 변수의 값 10
&p = 포인터 p의 주소 값
pp = 이중 포인터 pp의 값, p의 주소 값
*pp = pp가 가리키는 주소에 있는 값,  p 변수의값 = num 변수의 주소
&pp = 이중포인터 pp의 주소 값

포인터 형변환 : 포인터 타입의 의미는 얼마만큼의 데이터를 읽어오는지에 대한 것으로, 형변환 되면 읽어올 데이터의 양과 해석 방법이 달라지는 것 뿐, 저장된 값에는 아무런 영향을 미치지 않는다

int i = 0x1B2B3B4B; / i의 주소값은 0x100으로 가정 /
int pi = &i; / 변수 i의 주소를 포인터 pi에 저장 /
char
pc = (char)pi; / 포인터 pi의 값을 포인터 pc에 저장 /
-> pi 뿐만 아니라 pc에서도 변수 i에 접근이 가능해짐
그러나 두 포인터 변수의 타입이 다르기 때문에
연산자를 이용해 읽어오는 데이터의 값은 다름
pi는 int형으로 4바이트를 읽고, pc는 char형으로 1바이트를 읽음

6. malloc & free

동적(Dynamic) 메모리 할당: 프로그램이 실행되는 도중 필요한 만큼의 메모리를 할당하는 것 (heap 영역)

  • 프로그램 실행단계에서 기억공간의 크기를 필요한만큼 할당하고, 다 쓰면 직접 반납을 해줘야 함

정적(Static) 메모리 할당: 프로그램이 실행되기 전 메모리를 미리 할당하는 것 (stack 영역)

  • 컴파일 단계에서 메모리가 미리 할당되고, 함수 혹은 프로그램이 끝나면 소멸됨

메모리 관련 함수 헤더: <stdlib.h>

1. malloc
: 메모리를 할당받는 함수로, 메모리 공간을 확보하고 메모리 블록을 할당

  • 매개변수로 size를 지정하여 사용자가 얼만큼의 메모리를 할당받을 것인지 명시해야 함
    ex) student_score = (int)malloc(sizesizeof(int));
    포인터 변수 = (형변환)malloc(malloc 함수의 매개변수)
  • 매개변수에 들어갈 값은 메모리의 크기
  • 형변환은 포인터 변수의 자료형
  • 메모리 크기는 자료형의 크기*개수로 하는 것이 좋음

2. free
: 메모리를 할당했다면 heap 손상을 발생시키지 않기 위해 메모리를 해제

  • 동적 메모리 할당은 개발자가 메모리를 해제해주지 않는 이상 메모리가 할당된 상태로 있기 때문에 낭비될 수 있어 해제를 무조건적으로 해줘야 함
    ex) free(student_score);
  • 매개변수에 메모리를 해제할 시작 주소, 즉 포인터 변수를 써주면 됨

0개의 댓글

관련 채용 정보