본문 바로가기
프로그래밍 언어/c(일반)

extern 구조체 또는 변수 사용법 및 예시

by [Akashic Records] 개발의선지자 2024. 5. 8.

분할 컴파일 : 하나의 프로그램을 여러 개의 .c, .h 파일로 분할하여 작성

분할 컴파일 시 다른 파일에 선언된 전역 변수를 사용할 떄는 extern 선언을 사용

-> extern 선언 변수는 "다른 파일에 해당 변수명이 전역 변수 선언되어 있으니 공유하여 사용하겠다"

 

1. 변수

형식  : extern 자료형 변수명

 

사용법

1) .c 파일에서 extern 선언

ex) exam2.c, exam3.c 에서 exam1.c의 전역변수 total을 사용하고 한다.

 

exam1.c

exam1.c에 아래와 같이 정의한다.

int total=0; //전역 변수 선언
main() {...}

exam2.c

exam2.c에 아래와 같이 정의한다.

extern int total //extern 변수 선언, 다른 .c 파일에 전역 선언된 변수 접근하여 사용하겠다!
main() {...}

 

exam3.c

exam3.c에 아래와 같이 정의한다.

extern int total //extern 변수 선언, 다른 .c 파일에 전역 선언된 변수 접근하여 사용하겠다!
main() {...}

 

그러나 전역변수를 사용하고자 하는 파일이 많을수록 extern 변수를  남발하게된다.

그래서 일반적으로  헤더파일에  extern 선언하여 해당 헤더파일을 Include하여 접근하여 사용한다.

2) .h 파일에서 extern 선언

ex)  exam2.c, exam3.c 에서 main.c 에서 extern int total을 사용하고자 한다.

주의 헤더파일에 extern 변수 정의 후 main 소스파일에 "반드시" 한번 정의한다.

0으로 초기화 한다.

 

exam1.h

exam1.h에 아래와 같이 정의한다.

extern int total; //extern 변수 선언

 

 

main.c

main.c에 아래와 같이 정의한다.

int total=0; //초기화
main() {...}

 

exam2.c

exam2.c에 아래와 같이 정의한다.

#include "exam1.h" //extern 변수가 선언된 헤더파일 인크루드

test2() {
	printf("%d\n", total); //0
}

 

exam3.c

exam3.c에 아래와 같이 정의한다.

#include "exam1.h" //extern 변수가 선언된 헤더파일 인크루드

test3() {
	printf("%d\n", total); //0
}

 


2. struct 구조체 

헤더파일 : exam.h , exam1.h, exam2.h

소스파일 : exam.c , exam1.c, exam2.c

 

1. h 파일에서 extern 선언

exam.h  

사용할 구조체 선언된 헤더파일에서 extern 구조체 선언

#ifndef __EXAM_H__
#define __EXAM_H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "exam1.h"
#include "exam2.h"

typedef struct __score
{
        int grade[3];

}_score;

typedef struct __schooltbl
{
        _score score;
        unsigned char name[20];
        int num;
        float height;

}_schooltbl;


extern _schooltbl schooltbl;

#endif

 

exam1.h

#ifndef __EXAM1_H__
#define __EXAM1_H__

int test1();

#endif                                                                                                                                                                                                                                                                              ~

 

exam2.h

#ifndef __EXAM1_H__
#define __EXAM1_H__

int test2();

#endif                                                                                                                                                                                                                                                                              ~

 

exam.c

extern 선언 구조체를 메인 소스 파일에서 전역 선언해준다.

#include "../header/exam.h"

_schooltbl schooltbl;
int main(int argc, char* argv)
{

        memcpy(schooltbl.name, "chris", sizeof(schooltbl.name));
        printf("%s\n", schooltbl.name);
        schooltbl.num = 1;
        printf("%d\n", schooltbl.num);
        schooltbl.height = 171.5;
        printf("%04f\n", schooltbl.height);
        int i = 0;
        schooltbl.score.grade[i++] = 80;
        schooltbl.score.grade[i++] = 70;
        schooltbl.score.grade[i++] = 90;

        for(i=2;i>=0;i--)
        {

                printf("grade[%d] : %d\n",i, schooltbl.score.grade[i]);


        }

        printf("###############################\n");
        test1();
        printf("###############################\n");
        test2();
        printf("###############################\n");


        return 0;

}

 

exam1.c

#include "../header/exam.h"

int test1()
{
// 구조체 값 변경 후 출력 함수
        memcpy(schooltbl.name, "steve", sizeof(schooltbl.name));
        schooltbl.num = 2;
        schooltbl.height = 182.2;
        int i = 0;
        schooltbl.score.grade[i++] = 30;
        schooltbl.score.grade[i++] = 70;
        schooltbl.score.grade[i++] = 65;

        for(i=sizeof(schooltbl.score.grade) / sizeof(int);i>=0;i--)
        {

                printf("grade[%d] : %d\n",i, schooltbl.score.grade[i]);
        }

        printf("%s\n", schooltbl.name);
        printf("%d\n", schooltbl.num);
        printf("%04f\n", schooltbl.height);


        return 0;

}

 

exam2.c

#include "../header/exam.h"

int test2()
{
//구조체 출력 함수
        printf("%s\n", schooltbl.name);
        printf("%d\n", schooltbl.num);
        printf("%f\n", schooltbl.height);

        for(int i=2;i>=0;i--)
        {
                printf("grade[%d] : %d\n",i, schooltbl.score.grade[i]);
        }

        return 0;
}

컴파일 및 빌드

1. gcc

gcc -o exam exam.c exam1.c exam2.c
./exam

 

2.Makefile

Makefile 위치 : 소스 파일 디렉토리 

CC = gcc
TARGET = test
OBJS = exam.o exam1.o exam2.o

$(TARGET) : $(OBJS)
        $(CC) -o $@ $^

all : $(TARGET)

.c.o :
        $(CC) -c -o $@ $<


clean : 
        rm -f $(OBJS) exam

make all

make all
gcc -c -o exam1.o exam1.c
gcc -c -o exam2.o exam2.c
gcc -o test exam.o exam1.o exam2.o

 

make clean

rm -f exam.o exam1.o exam2.o exam

 

 

 

 

'프로그래밍 언어 > c(일반)' 카테고리의 다른 글

포인터(3) - 포인터&배열 함수인자 전달  (0) 2024.07.12
포인터(2) - 포인터 배열 / 배열 포인터  (0) 2024.07.11
static 정적 변수  (0) 2024.05.07
삼항 연산자  (0) 2024.05.06
연산자 정리  (0) 2024.05.02