-
정의 vs 선언 1프로그래밍 언어 C, C++ 2021. 1. 16. 02:16728x90
Java, C# 고급 언어를 먼저 사용하고 C, C++을 나중에 시작했다면, 컴파일 에러가 많이 힘들게 할 것이다.
어쩌면 편한 언어를 사용해왔기 때문에 오히려 처음 프로그래밍 언어를 배우는 사람보다 더 힘들게 하는것일 수도 있다.
고급 언어와 같은 부류처럼 *.c, *.cpp 파일만 존재하면 좋을텐데, 불행히도 *.h, *.hpp 파일들이 느닷없이 등장한다.
사실 이게 가장 큰 차이점이기도 하고, 이게 C, C++ 언어를 배우는데 걸림돌 중에 하나가 아닐까 싶다.
특히, 고급 언어를 능숙 능란하게 다루는 개발자에게는 더욱 정 떨어지게 만든다. ㅎㅎ
쉽게 설명된 곳이 없거나, 혹은 찾기 어려웠을것이다.
근데, 사실 한가지만 알면 모든 의문의 실마리 풀려 버릴것이다.
그 키워드는 놀랍게도 정의, 선언에 모든 것이 있다.
1234567891011#include <stdio.h>int main(){int a = 0;// 선언printf("a = %d\n", a);return 0;}cs 선언을 보자. int라는 타입의 a라는 변수를 0이라는 값으로 초기화 했다.
1) 메모리 종류 중 하나인 스택에 4바이트를 확보한다.
=> 흔히 이말을 "할당한다"라고 표현한다. int 타입은 4바이트
2) 방금 할당한 스택 메모리를. a라는 이름으로 된 변수가 int타입으로 사용할 수 있게 되었다.
=> a의 주소값이 스택 메모리의 시작 주소와 같다.
3) 방금 명명한 a라는 변수에 0을 대입한다.
=> 흔히 이 부분을 "초기화한다"라고 한다. 만약 int a; 였더라면 여기가 생략된다.
5 line이 1), 2), 3)이 순차적으로 일어난다고 이해하면 좋다.
위의 코드처럼 선언이란 것이 사실 메모리를 할당한다는 말을 포함하고 있다.
선언이 다른 위치에 있는 코드를 보자.
1234567891011#include <stdio.h>int main(){printf("a = %d\n", a);return 0;}int a = 0;// 선언cs C, C++은 절차형 언어다.
컴파일러가 4 line 까지 읽어들인 상태에서,
5 line을 읽으면 처음 보는 변수 a를 보고 컴파일 에러를 토해낸다.
10 line에 있는 선언 부분을 알아 주면 좋을텐데, 기계들은 인간미가 없다 ㅋ
(Java에서 main이 멤버 메쏘드이고 a가 멤버변수라면,
line의 순서에 상관없이 괜찮다고 할 것이다. 허나 그건 C++클래스에서도 똑같다. 차이없다.
다만, 고급 언어에서는 전역 변수 자체가 존재 하질 않는다걸 명심해라.
알고 보면 고급언어가 제약이 많고 더 불편하다고 말하고 싶다.)
12345678910111213#include <stdio.h>extern int a;// 정의 1int main(){extern int a;// 정의 2printf("a = %d\n", a);return 0;}int a = 0;// 선언cs 위에 처럼 3, 6 line 둘다 있거나, 둘 중 하나만 있더라도 해당 컴파일 에러 문제가 해결된다.
extern 키워드가 변수 타입 앞에 붙게 된다면,
"이 타입의 변수는 코드 어딘가에 선언되어 있어."
라고 컴파일러에게 알려줄 뿐이다. 할당을 하는 선언이 아니니 새로운 변수를 만드는게 아니라는걸 알아야 한다.
당연히 아래 처럼 하더라 전혀 문제가 되지 않는다. ㅎㅎ
12345678910111213141516#include <stdio.h>extern int a;// 정의 1extern int a;// 정의 2extern int a;// 정의 3extern int a;// 정의 4extern int a;// 정의 5int main(){printf("a = %d\n", a);return 0;}int a = 0;// 선언cs 감이 왔을 것이다.
int a; => int 자료형 만큼을 할당하고 a라고 명명함.
extern int a; => 컴파일러에게 알려만 줌.
지금까지는 자료형의 변수에 대해서만 다뤘다.
함수도 사용법이 거의 동일하지만, 약간 다르니까 주의깊게 살펴보자.
1234567891011121314#include <stdio.h>int main(){printf("number() = %d\n", number());return 0;}int number(){return 1004;}cs 10 line에 number()함수가 구현되어 있는데,
5 line에서 쓰려고 시도하려니 당연히 컴파일러가 에러를 낸다.
1234567891011121314151617181920#include <stdio.h>int number();// 정의1extern int number();// 정의2int main(){int number();// 정의3extern int number();// 정의4printf("number() = %d\n", number());return 0;}// 선언int number(){return 1004;}cs 정의1~4 어디든 상관없이, 1개이상 정의되어 컴파일러에게 알려주면 에러가 고쳐진다.
자~ 그럼 다른점만 살펴보자.
함수는 중괄호{}가 있으면 선언이라고 하고, 중괄호가 없으면 정의다.
따라서 extern은 생략이 가능하고 명시해서 표시해도 된다.
그럼 여기까지 컴파일 에러라는것을 살펴보았다.
링크 에러라는것도 존재한다. 여러 파일로 나눴을때 복합적인 상황을 연출과 함께 같이 살펴보자.
아래 링크로...
'프로그래밍 언어 C, C++' 카테고리의 다른 글
랜덤함수 (0) 2021.01.17 정의 vs 선언 2 (0) 2021.01.16 프로그래머 워밍업 2 (0) 2021.01.09 프로그래머 워밍업 1 (0) 2021.01.07 개발자, 무엇을 준비 할까? (0) 2021.01.04