C/C++와 Java를 비교해보면 아래와 같다.

구분CC++JAVA
#typedefOOX
#defineOOX
#gotoOOX
struct(구조체) 자료형OOX
Union 자료형OOX
데이터형 변환묵시적명시적랩퍼 클래스
배열포인터포인터객체
문자열배열배열String 자료형
메모리 관리수동수동자동
객체지향 개념비 객체지향 (절차 지향)반 객체지향객체지향
연산자 오버로딩XOX
함수(메소드) 오버로딩XOO
다중 상속XOX
운영체제 독립성XX비종속

main function

모든 프로그램들은 최초 실행 때에 시작 진입점을 가지게 되는데 C++에서는 main 함수가 되며 Java에서도 동일한 이름의 main 메소드가 프로그램의 진입점이 된다.

예제 1-1)과 예제 1-2)를 비교해보면 약간의 모양은 다른 부분이 있지만 거의 비슷해 보인다.

예제 1-1) C++ main function

#include <iostream>

int main(int argc, const char * argv[])
{
    std::cout << "Hello, World!\n";
    return 0;
}

예제 1-2) 자바 main method

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world");
    }
}

C/C++의 main과 Java의 main을 비교해보면 아래와 같다.

구분C/C++Java
returnintvoid
prameterint argc, const char * argv[]String[] args
위치클래스 밖에 있다.클래스 안에 있다.

C/C++은 return은 보통은 정수인데 컴파일러에 따라 void도 존재한다. prameter도 맞찮가지로 컴파일러에 따라 없을 수도 있다.

프로그램 안에 main은 자바에 달리 클래스 밖에 존재하는데 이는 모든 것을 객체화한다는 객체 지향 언어 프로그래밍(object-oriented programing)에 위배된다고 하여 완벽한 객체 지향 언어가 아닌 반 객체 지향이라고도 한다.

define 메크로

C/C++와 비교해 Java에 없는 것중에 하나는 전처리문이다. 그 중 define에 대해서 설명한다.

define은 일명 메크로라고도 하는데 값, 함수를 지정한 것을 대체 치환해 주어 프로그래밍을 편하게 해준다. 여기서 치환해 준다는 말은 C++ 컴파일은 Java와 달리 전처리라는 소스 치환 과정을 있는데 실제 소스에 define된 값을 실제 값, 함수로 변환해주는 과정이다.

예제2-1)와 예제2-2)를 전처리 전후를 비교하면서 보자.

예제2-1) C++ 소스 코드

#include <iostream>

#define HELLO "Hello, World!\n"
#define MAX(a,b) ( (a) > (b) ? (a) : (b) )

int main(int argc, const char * argv[])
{
    std::cout << HELLO;
    std::cout << "Max:" << MAX(10, 100);
    return 0;
}

예제2-2) C++ 전처리 후의 소스 코드

# 1 "main.cpp"
# 1 "<built-in>"

... 중간생략 ...

# 10 "main.cpp" 2

int main(int argc, const char * argv[])
{
    std::cout << "Hello, World!\n";
    std::cout << "Max:" << ( (10) > (100) ? (10) : (100) );
    return 0;
}

전처리 파일을 컴파일마다 다르게 보일 수 있다. 예제는 g++로 만든 전처리 파일이다.

위에 소스를 보면 메크로 값 HELLO와 메크로 함수 MAX(a, b)에 주목하자. 개발자가 작성한 소스 파일이 전처리 과정을 거치고 HELLO는 실제 값인 "Hello, World!\n"이 들어가고 MAX(a, b) 은 ( (10) > (100) ? (10) : (100) )으로 변경된 것을 볼수 있다.

그럼 Java에서는 define인 아예 없는 것인가? 대답은 "그렇다"이다. 하지만 값 치환은 비슷하게 코드를 만들 수는 있다. 예제2-3)을 보자.

예제2-3) Java 소스 코드

public class Main {

    public static final String HELLO = "Hello, World!\n";

    public static void main(String[] args) {
        System.out.println(HELLO);
    }
}

예제2-3) Java 소스 코드는 HELLO 변수에 static, final로 지정하고 값을 대입하여 이를 출력하도록 했다. 이 소스를 컴파일하면 바이트 코드가 나오고 이를 다시 역컴파일 하면 C++의 define문과 비슷하게 치환되어 나오는걸 볼수 있다.

예제2-3) Java 역컴파일

public class Main
{

    public Main()
    {
    }

    public static void main(String args[])
   {
        System.out.println("Hello, World!\n");
    }

    public static final String HELLO = "Hello, World!\n";
}

실제로 예제2-3)가 역컴파일을 한 것이다. println에 넣었던 HELLO는 사라지고 실제 값인 "Hello, World!\n"이 들어가 있는 것을 확인 할수 있다.

이렇게 C++나 Java에서 치환되는 것이 실제 프로그램이 구동할 때 메모리에 관리되는 변수보다는 실제값이 직접 들어가게 되므로 아주 조금은 속도가 향상될 것으로 생각된다. 하지만 이 속도가 너무나 미세하기에 단순히 프로그램의 속도 향상을 위한 목적이라면 define을 쓰지는 말길 바란다. 오히려 너무 난발하면 디버깅이 힘든 프로그램이 되기에 주의를 요한다.

Tip)

Effective C++책의 항목2에서는 define의 사용보다는 const, enum, inline 함수 사용을 권장한다. 원인은 나중에 문제가 발생할 때 코드를 디버깅하기가 힘들기 때문이다. 너무나 중요한 로직 부분이나 디버깅이 힘들수 있게다고 생각된다면 define은 쓰지말길 바란다.



'기타' 카테고리의 다른 글

HTTP 응답 코드 및 메소드  (0) 2018.11.06
YouTube to MP3 - 유투브 MP3 다운받기  (0) 2018.10.27
C/C++와 JAVA 비교  (0) 2018.01.10
REST API란?  (0) 2017.12.10
JSON이란?  (0) 2017.12.10
마크다운(Markdown) 이란?  (0) 2017.12.10

+ Recent posts