분할 구현, extern 키워드

Yama·2023년 12월 6일
0

어소트락 수업

목록 보기
8/55

.exe파일이 나오는 과정

  1. main.cpp 컴파일(빌드)한 후 obj파일이 나온다.
  2. math.cpp 컴파일(빌드)한 후 obj파일이 나온다.
  3. 이 파일 2개가 링킹과정을 거친다.
  4. 문제가 없다면 .exe파일이 나온다.

링킹 오류

  • main.cpp에 선언만 해두고 math.cpp에 구현을 안해놔서 링킹 오류 발생.
  • 선언만 해두고 구현을 어디에도 안해놔서.

#include "math.h"

  • math.h에 파일에 잇는 함수 선언 부분을 다 복사하겠다는 의미.
#incldue "math.h"

int main(void)
{

	return 0;
}
  • 컴파일 전.
int Add(int a, int b);
int Sub(int a, int b);
int Mul(int a, int b);
int Div(int a, int b);

int main(void)
{

	return 0;
}
  • 컴파일 할떄

선언과 구현을 분리(헤더파일x)

main.cpp

int Add(int, int);

int Mul(int, int);

int main(void)
{
	int i = Add(1, 1); 

	i = Mul(2, 3);
	return 0;
}

math.cpp

#include <iostream>

int add(int a, int b)
{
	return a + b;
}

int Mul(int a, int b)
{
	return a * b;
}

선언 + 구현 + 메인 함수 분리.(헤더파일 사용)

main.cpp

#include "math.h"

int main(void)
{
	int i = Add(1, 1); 

	i = Mul(2, 3);
	return 0;
}

math.cpp

#include <iostream>

int add(int a, int b)
{
	return a + b;
}

int Mul(int a, int b)
{
	return a * b;
}

math.h

#pragma once

int Add(int a, int b);
int Sub(int a, int b);
int Mul(int a, int b);
int Div(int a, int b);

#include (iostream)

#incldue <iostream>
  • 기능 선언을 다 참조해둔것이당.
  • cpp 구현부분은 바이너리 코드로 빌드를 해놔서 라이브러리화 해둠.
  • printf에 대한 선언이나 많이쓰는 함수가 이미 다 iostream에 선언되어있다.

https://learncom1234.tistory.com/49

main.cpp와 math.cpp에 똑같은 이름의 전역변수

main.cpp

int g_Global = 0;

math.cpp

int g_Global = 0;

  • 링킹 오류가 발생한다.
  • 지금은 main과 math에 똑같은 전역변수가 2개가 있다.
  • 그래서 링킹 단계에서 하나로 합쳐진다면 2개의 똑같은 이름의 전역 변수가 2개를 정의한거기 때문이다.
  • 그래서 재정의 오류가 발생한것.

main.cpp에 똑같은 이름의 전역변수 2개

main.cpp

int g_Global = 0;

int g_Global = 0;

  • 컴파일 단계에서 재정의 오류가 발생한다.

정적변수 - static

main.cpp

static int g_Static = 0;

int main(void)
{
	g_Static = 10;
    
    int Add(10,10);
}

math.cpp

static int g_Static = 0;

int Add(int a, int b)
{
	g_Static = 100;
	return a + b;
}

  • 데이터 영역
  • 똑같은 이름의 정적변수가 2개가 main과 math에 있지만 컴파일과 링킹에서 문제 없이 exe파일이 나온다.
  • static 붙은 정적변수는 각자 파일쪽에서 선언된 곳에서만 사용되기 각자 선언된 곳에서만 사용되게 바뀐다.
  • 변수명이 동일하더라도 static이 붙어서 문제가 안된다
    • 컴파일러는 다르게 생각한다.
  • static은 파일 전용이라 체크해놔서 컴파일러가 지칭(구분)할수 있게 해준다.(활동범위가 제한되서)
  • main와 math에 g_Static는 다른 개체다.

헤더파일에 전역변수 선언

math.h

int g_Global = 0;

main.cpp

#include "math.h"

math.cpp

#include "math.h"
  • 재정의 문제가 발생한다.
  • 같은 변수명을 허용해주면서 각자 다른게(static)아니라 각자의 파일에 다 똑같은 전역 변수처럼 사용하고 싶다면
  • extern키워드를 사용해야된다.

extern

value.h

#pragma once

extern int g_manager;

main.cpp

#include "value.h"

int main()
{
	g_manager = 100;
    int Add(100,10);
}

math.cpp

#include "value.h"

int Add(int a, int b)
{

	g_manager = 200; // 4
    
	return a + b;
}

int g_manager = 0;
  • extern은 각각의 파일들은 하나의 전역변수가 있다고 알게된다.
  • 함수 선언만 받는 것처럼 전역변수에 대한 선언만 받게 된다.
  • 선언을 했다면 구현은 어딘가에는 존재해야한다.
    • 구현 부분이 없다면
      • 링킹 오류가 발생

지역 변수

  • 함수안에 선언
  • 해당 함수가 호출되면 함수 스택내에 포함
  • 해당 함수가 종료되면 해당 스택과 같이 해제됨

전역 변수

  • 함수 밖에 선언됨
  • 해당 파일 어떤 함수던 접근 가능
  • 데이터 영역 메모리 사용(프로그램 실행 도중 계속 유지됨)
  • 다른 파일에서는 접근이 불가능
  • extern 선언을 통해서 전역변수를 다른 파일에 연결가능

정적 변수(static)

  • static 키워드가 붙은 변수
  • 데이터 영역에 존재함
  • 선언된 곳에서만 접근 가능(함수 내, 파일 내(전역변수처럼 선언하면))
  • 함수 내에 선언한 경우
    • 지역변수처럼 해당 함수에서만 접근 가능하고, 메모리는 데이터 영역을 사용하기 때문에 함수 종료와 상관없이 데이터가 유지된다.
  • 전역 변수에 static를 붙인 경우 다른 파일의 전역변수와 이름 중복이 가능하다.

강의 코드

main.cpp

#include <iostream>
#include <vector>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#include "math.h"
#include "value.h"

#define TRUE 1

static int g_Static = 0;
int g_Global = 0;

int main()
{
	g_manager = 100;
	g_Static = 10;

	int i = Add(1, 1);

	i = Mul(2, 3);


	bool b = TRUE;

	printf("출력\n");

	i = pow(2, 4);

	int a = -20;
	a = abs(a);

	return 0;
}

math.cpp

#include "value.h"


static int g_Static = 0;
//int g_Global = 0;

int Add(int a, int b)
{
	g_manager = 200;
	g_Static = 100;
	return a + b;
}

int Sub(int a, int b)
{
	return a - b;
}

int Mul(int a, int b)
{
	return a * b;
}

int Div(int a, int b)
{
	return a / b;
}

int g_manager = 0;

math.h

#pragma once


int Add(int a, int b);
int Sub(int a, int b);
int Mul(int a, int b);
int Div(int a, int b);

1차 23.12.06
2차 23.12.07
3차 23.12.08
4차 23.12.11
5차 23.12.17
6차 23.12.25
7차 24.01.01
8차 24.01.22

0개의 댓글