예전에도 이런 글을 쓴 적이 있었는데, 이번에 MSDN 에서 잘 정리된 글을 본 김에 두 언어간의 차이를 좀 더 정리해 볼까 한다.


1. C++ 에서 클래스(class) 와 구조체(struct) 는 거의 동일하다. ( C++ 에서 struct 는 모든 멤버가 public 인 class 라고 생각하면 된다 ).
반면에 C# 은 class 와 struct 의 용도가 다르다. C# 의 struct 는 상속을 지원하지 않으며 명시적 기본생성자를 지원하지 않는다. 

2.  C++ 과 달리 C# 의 배열은 C++ 의 vector 와 유사한, 자체적인 메소드를 제공하는 자료구조 개체이다. 예를 들면 C# 의 배열 자료구조는 자체적으로 Min, Max, Length 등의 라이브러리 함수를 제공한다. 또한, C++ 과 C# 은 배열을 선언하는 방법이 매우 다르다. 

- C++ 의 배열 선언 

- C# 의 배열 선언


3. C++ 의 bool 타입은 int 와 동일하다. 반면에 C# 은 bool 은 true / false 를 갖는 고유한 데이터타입이며 아래와 같은 묵시적 타입캐스팅이 불가능하다.


4. C++ 의 long 은 int 와 마찬가지로 32 비트 자료형이다. C++ 에서 64 비트 자료형을 쓰기 위해서는 long long 을 쓴다. 반면에 C# 의 long 은 64 비트 자료형이다.

5. C++ 과 C# 모두 값에 의한 전달과 참조에 의한 전달을 지원한다. C 와 C# 모두 명시적으로 참조에 의한 전달을 표시하지 않은 경우 기본적으로는 값에 의한 전달방식으로 처리된다. C++ 과 C# 에서의 참조에 의한 전달 방식은 각각 아래와 같다.
 
- C++ 의 방식

- C# 의 방식
6. C# 은 기본적으로는 포인터 사용이 금지되어 있다. C# 에서 포인터를 쓰기 위해서는 컴파일러 옵션으로 _unsafe 를 쓴다. 포인터 사용을 가급적 금지한 이유는 C/C++ 에게 있어서 강력한 기능인 포인터가 그만큼 잘못사용할 경우 심각한 오류를 일으키는 존재였기 때문이다. 조엘 스폴스키는 최근에 널리 사용되는 프로그래밍 언어(대표적으로 자바를 많이 까더군) 들이 보여주는 포인터 사용에 제한적인 트렌드에 대해서 개탄하면서, 수준낮은 프로그래머들은 절대 포인터에 대해서 이해하지 못한다고 독설을 남기기도 했다. 어쨌든 보다 배우고 쓰기 쉽고, 안정성 추구하는 C# 의 언어 설계철학을 엿볼 수 있다.

7. switch 문
- C++ 과 달리 C# 의 switch 문은 break 가 없는 경우 자동적으로 다음 case 로 넘어가지 않는다. C++의 switch 문에서 break 를 빼 먹어서 생기는 실수를 방지하기 위한 규칙으로 보인다. 단, C# 의 switch ~ case 에서 case 문에 코드가 없는 경우에는 다음 case 로 넘어갈 수 있다.

8. C++ 의 typedef 대신에 C# 에서는 using 을 사용한다.

9. C# 의 지역 변수는 C++ 과 달리 항상 초기화를 해야만 사용할 수 있다. C++ 의 경우 실행시 에러가 나더라도 초기화 하지 않은 지역변수를 일단 쓸 수는 있다. (일부 C++ 코드에서는 일부러 초기화 하지 않은 변수를 사용하는 바람직하지 않은 테크닉이 사용되기도 한다) 그러나 C# 은 초기화하지 않은 지역변수를 사용할 경우 컴파일 에러가 발생한다. 

10. 자료구조에 있어서 모든 타입을 자유롭게 쓸수 있게 하여 재사용성과 효율성을 높이는 기법 -  C++ 의 템플릿(Template) 과 유사한 개념이 C# 에서는 제네릭(Generic) 이라 한다. 단, C# 의 제네릭의 타입정보는 런타임에 적용된다.

11. C# 도 C++ 과 마찬가지로 goto 를 지원한다. 단, C# 은 goto 에 지정된 label 에서 반드시 코드가 있어야 한다.
참고로 Java 에는 goto 가 없다. goto 는 강력한 기능이지만 코드의 가독성과 논리적인 flow 를 흐리게 한다는 점에서 많은 논란이 되어 왔다.

12. C++ 에서 사용하는 #define 을 통한 매크로 정의를 C# 은 할 수 없다. C# 의 define 은 컴파일 옵션에 따른 전처리기 사용에 국한된다.

13. unsigned 데이터 타입  : C/C++ 에 존재하는 unsigned 데이터 타입이 C# 과 자바에서는 없다. 
unsigned 타입을 없앤 이유는 signed 와 unsigned 를 혼용할 경우에 발생될 가능성이 있는 오류 때문으로 추정되는데, 여기에 대해서는 아래 포스팅에 잘 설명되어 있다. 

잘 모르겟거든 unsigned 는 쓰지 말지어다

unsigned 자료형의 이점은 양수 데이터를 표현하기 위한 최대치가 2 배로 늘어난다는 점이다. 최근의 컴퓨팅 환경은 메모리에 대한 제약이 예전에 비해 많이 사라져서 메모리에서 손해를 보더라도 오류를 낼 가능성이 있는 unsigned 타입을 삭제하는 언어 설계철학을 도입한 것으로 보인다.

14. C# 은 C++ 과 달리 전역변수와 전역함수를 쓸 수 없다. 따라서 C++ 프로젝트를 할 때 전역변수를 모아놓고 한곳에 관리해서 쓰는 constant.h 헤더를 사용하는 기법등을 C# 에서는 쓸 수 없다. C# 에서 이와 같이 하려면 해당 변수들을 멤버로 가진 클래스를 사용한다. 예를 들면 Constant.cs 를 만들고 여기에 Constant 클래스를 만드는 식으로..

15. C++ 과 달리 C# 은 비트필드를 지원하지 않는다.

16. C# 은 C++ 에는 없는 foreach 문이란 반복문이 존재한다. foreach 문의 용도는 C++ 에서의 for 와 거의 유사하다. 

17. 가비지 컬렉션
최근에 등장하는 언어들의 주요 특징 중 하나가 가비지 컬렉션을 지원한다는 점이다.
C# 에는 delete 가 없다. 단, C# 도 프로그래머가 명시적으로 new 로 할당된 데이터를 삭제할 수 있다.



새로운 언어를 공부하면서 기존에 널리 사용되던 언어와의 차이점을 비교해보고, 왜 이런 차이점이 생기게 되었는지를 생각해 보면 프로그래밍 언어의 설계철학과 발전 과정을 음미해 볼 수 있는 좋은 공부가 된다.

댓글을 달아주세요!
  1. w 2012.01.01 15:30 신고  댓글주소  수정/삭제  댓글쓰기

    C#에는 Java와 달리 unsigned 가 있습니다. Unsigned 는 분명 사용하기 까다로운 면이 있지만 없애기에도 애매한 것 같습니다. Pointer 도 마찬가지라고 생각합니다. 사실 C와 달리 C++ 는 참조자를 적극적으로 쓰면 pointer의 필요성이 급감합니다. Legacy들을 보면 쓸데없이 C++에서 pointer를 쓴 경우가 많죠.

이름 암호 홈페이지