cyphen156

상수 : C/C++의 const와 #define 그리고 자바의 static/final에 대한 생각 본문

잡생각 정리글

상수 : C/C++의 const와 #define 그리고 자바의 static/final에 대한 생각

cyphen156 2023. 7. 6. 15:57

※ 주의 글쓴이의 주관 200% 대충 이런생각하는사람도 있구나 정도로 받아들여줬으면 좋겠습니다.

잘못알고있다면 알려주시면 감사하겠습니다.

 

어제 퇴근하면서 좋아하는 개발자분(유튜브에 nullnull한 교수님이 있습니다...)이 자바 백엔드 공부하시면서 느낀점에 대한 영상을 시청했는데 상수라는 개념에 대한 이야기가 잠깐 나왔다.

내가 아는 상수는 선언과 동시에 초기화되어야 하는, 데이터의 불변성을 지키기 위해 선언되는 변수가 상수라는 것이었다. 

C와 C++에서는 상수가 앞서 언급했듯이 선언과 동시에 초기화 되고,  이 데이터가 변해서는 안된다는 것을 명시해주는 것이다. 

C/C++에서의 #defineconst의 차이

이 둘은 서로 비슷하게 상수의 역할을 하지만 엄청난 차이가 존재했다. 

바로 #define전처리기 지시어에 의해 해당 문자가 모두 컴파일 전에 다른 문자로 대체된다는 것으로 시 메모리에 올라가지 않는, 극한의 최적화였다.

반면에 const 키워드는 상수를 만들어서 프로그램 동작시 메모리 영역중 데이터 섹션에 위치하여 프로그램 종료시 사라지는 데이터라는 것이다.

둘의 장단점은 뭐가있을까?하고 찾아보았더니 프로그램 동작시 에러가 발생했을때 디버깅 난이도의 차이와 최적화와 관련이 있었다. 

#define은 에러 발생시 해당하는 변수가 모두 다른 문자로 대체되어있기 때문에 어디서 발생한 버그인지 찾아내기 매우 까다로워지고, 타입체크(int, float 등..)가 불가능해진다는 것이다. 그래서 보통 const를 사용하는것이라고 한다.

 

자 이제 C언어에서의 상수(#define과 const)에 대해 알아봤다

다음 알아볼건 자바에서의 상수다.

그래서 Java는 뭐가 다른데?

자바는 final 키워드는 "상수의 역할"을 한다.

변수를 final로 지정하면 그 값을 한번 초기화 하고 나면 변경시킬수 없도록 지정해준다. 

그럼 C와 같은거 아니야?

나도 그런줄 알고있었는데 아니었다. 

자바는 final키워드로 변수를 선언해도 프로그램 동작시 변수가 data섹션이 아니라 Heap영역에 할당된다.

또한 final만 선언하게 되면 각 인스턴스(객체)마다 final 변수를 하나씩 갖게 된다. 이것을 클래스마다 하나씩 갖게 하는것이 static키워드를 통한 정적 상수(static final) 선언이다. 

static final을 통해 변수를 생성하면 하나의 클래스를 통해 생성된 모든 인스턴스가 단 하나의 static final 상수를 공유하여 사용하게 된다. 이것을 이용한 것이 객체지향에서의 싱글턴 패턴이라 볼 수 있다.

이것은 상수가 메모리에 동적으로 할당되고, 자바는 JVM이 메모리를 관리하기 때문에 쉽지는 않겠지만(강제적으로 메모리를 직접 조작하는 경우 -> 대개 해킹, 치명적인 오류 발생) 오버플로우와 같은 메모리 영역 침범을 발생시켜 그 값을 변경시킬수 있다는 것을 의미한다고 나는 받아들였다.

 

결론내리자면

  • #define은 아예 프로그램 메모리에 안올라간다.
  • const는 data섹션에 존재하는 상수다
  • static final, final은 data섹션이 아닌 heap영역에 존재하는 변수다
  • static final은 클래스마다 갖을 수 있는 단 하나의 불변의 변수다
  • final은 인스턴스마다 가지고 있는 불변의 변수다

다시 말하지만 잘못알고있을 가능성이 매우 크니까 그냥 참고만해주세요

이제 다시 백준 문제 풀러가야지...TT