서론

C언어는 아무도 이의를 제기할 수 없을정도로 장수한 프로그래밍 언어중 가장 인기가 높은 언어이다. 그리고 또한 C언어를 프로그래밍 언어의 입문으로 생각하여 처음 접하는 언어로 C언어를 택하는 사람도 많다고 생각된다.

하지만 이러한 현실 속에서 실질적으로 C언어에대한 책이나 강의를 보면 하나같이 다 똑같다.

printf("뭔가 이상한 %나 &가 섞여있는 문자열", 변수여러개);

요렇게 치면 놀랍게도 까만색창에 문자가 떠여~!!!! 와 박수~!

필자는 Visual Basic으로 프로그래밍을 입문해서 그런지, 이러한 가르켜주는 방식은 발전 가능성도 없으며(솔직히 이것만보고 운영체제에서 지정해준 버퍼에 내용을 쓰면 운영체제가 하나하나 읽어가며 화면에 표시해준다는걸 누가 알겠는가?) 매우 비효율적이라 생각된다.

그래서 그냥 자기만족용으로 써본다.

이 글의 추천독자는 뭔가 위와같은걸 해봤지만 정작 어떻게 그게 실현되는지는 모르는 고런 사람들이니 참고 바란다.

왜 C언어인가?

C언어는 꽤나 가볍고 꽤나 Low Level1을 다루기 쉬워서 오늘날에도 많이 쓰인다. 하지만 교육용으로 좋은언어인가? 라고 물으면 경쟁자가 꽤 많다.

대표적으로 프로그래밍 개념만 배우려한다면 스크래치나 Phyton만 배워도 충분하고 실용성을 따지자면 솔직히 Java를 따라올 언어가 없다. 이러한 생각을 반영했는지 실제로 요즘 해외 몇몇대학을 보면 프로그래밍 입문으로 C언어 대신 Java나 Phyton만 쓰는 학교도 꽤 있다는 모양이다.

하지만 다음 두가지를 생각해볼때 C언어가 처음배우는 언어로 적합한지는 둘째치고 알아두어야 언어임에는 틀림없어 보인다.

첫째는 모든 언어가 C언어에서 영감을 받았다는 것이다. 대표적으로 ==이나 != 부터 시작해서 { }같은 중괄호 스타일 static int SomeFunc(int A, char B){}같은 함수 선언양식까지 모두 C언어에서 영감을 받은 것들이고 C언어만 배워두면 다른 언어배울때 기본적인 구조가 같기에 배우기 훨씬 수월하다. (근데 이건 C#배워도 된다는게 함정)

둘째는 실제 컴퓨터가 어떻게 연산을 수행하는지 알수있는 언어중 가장 쉬운 언어라는 것이다. 우리가 int a[100];이라는 배열을 선언하면 컴퓨터는 메모리상에 어떻게 저장하고 어떻게 그 위치를 알아내며 어떻게 그 위치를 사용하는지 생각해본적 있는가? 물론 요즘나온 언어들은 우리가 그런거 신경쓸 필요 없이 다 알아서 해준다. 하지만 알고 프로그래밍하는것고 모르고 하는것, 이 둘 사이에는 분명한 차이가 존재한다. 그리고 어차피 요즘나온 언어가 다 처리해 준다고는 하지만 파일 읽기나 쓰기, 소켓통신같이 조금만 심화되게 들어가면 이부분을 모르면 되게 코드가 비 효율적이게 된다.

그러니 C언어 배울때 불평하지 말고 한번쯤은 해두는 것이 좋다.

C언어의 모토

는 "프로그래머를 믿으라!"이다.......

즉, "난 이 모든 기능들을 지원하지만 이것들 조금만 잘못써도 버그 엄청나게 남. 하지만 난 널 믿으니깐 알아서 짤 쓸수 있을꺼라고 믿어!" 이런 느낌이다.

물론 모토가 이것일뿐 그것을 실현하는 컴파일러, 대표적으로 Microsoft C++ Compiler의 경우 프로그래머를 믿어서(;;) 표준안을 무시하고 여러가지 함수를 변경한걸로 유명하다.

이에대한 반응은 자기 취향따라 달라지는듯 하다.

무엇으로 배워야 하는가?

사실 C언어에 표준안이 존재하긴 하지만 (ANSI C가 초기버전, C11이 가장 최근꺼) 현실적으로 C라는 언어 자체에 의미를 부여하는것은 컴파일러2이고 각 컴파일러들은 각자의 사정에 맞춰서 다들 제멋대로 만들기때문에 좀 심하게 말하자면 컴파일러에따라 그냥 다른 언어라고 불러도 될 정도이다.

그럼 이렇게 그냥 다른언어라도 봐도 될꺼같다는 말이나올정도로 컴파일러에 따라 언어의 성격이 바뀌는데 어떤 컴파일러를 사용해야할까?

일단 보통 접하는 유명한 컴파일러는 Intel® C++ Compilers, GCC, Microsoft C++ Compiler, LLVM/Clang 등이 있다.

차례대로 간략히 설명하자면

  1. Intel® C++ Compilers: 엄청난 최적화로 유명하다. Intel CPU로 돌아가는 컴퓨터 한정으로 코드가 자동으로 병렬화되서 CPU의 한계를 최대한 이끌어 낸다. 보통 슈퍼컴퓨터에서 돌릴 프로그램 작성할때 많이 쓰인다.
  2. GCC: 리눅스에서 주로 쓰인다. (같은 재단GNU에서 만듬) 위 넷중 표준을 가장 잘 지키고 가장 많이 쓰인다. 리눅스 컴파일할때도 주로 이놈을 사용한다. (리눅스에서 리눅스 컴파일 하는데 GCC를 쓴다. 음?)(닭이먼저 달걀이 먼저?) 윈도용으로 포팅해놓은것도 있다. Dev-C++가 GCC를 컴파일러로 사용한다.
  3. Microsoft C++ Compiler: (개발자를 못믿어서)표준따위 안드로메다로 날라갔다. 하지만 비주얼스튜디오 설치하면 같이 날라와서 쉽게 접할 수 있다.
  4. LLVM/Clang: Apple에서 밀어주는 컴파일 방식이다. 정확히는 Clang이 C언어를 기계어가 아닌 중간단계의 언어로 바꿔주고 LLVM이 그 중간단계의 언어를 기계어로 바꿔주는 방식이다. 이렇게 함으로써 컴파일러개발자는 컴파일러 개발자대로 하나만 포팅하면 여러언어를 한번에 지원하고, 언어개발자는 언어개발자대로 하나만 포팅하면 여러 기기를 한번에 지원하는 컴파일러를 만들어보자는 것이 LLVM이다.

이중에서 개인적으로 추천하는건 GCC이다. 이유는 표준을 가장 잘 지켰고, 업데이트가 되어도 크게 변하지 않고, 문제점이 생겼을때 질문할 커뮤니티 규모가 가장 크기 때문이다. 하지만 리눅스를 처음 다루는사람은 GCC사용하기가 어려울테니 윈도우용으로 포팅된 GCC를 사용하거나 그냥 비쥬얼스튜디오 사용하는것도 나쁘지 않다.

  1. 아두이노에 LED깜빡이는, 공유기가 인터넷 공유해주는 정도의 수준을 의미함

  2. 영어를 분석해서 기계어로 바꿔주는놈

  3. Binary -> 이진법의 -> 0101011101 요런 파일

  4. 사실 단순히 변수 선언을 엄청 많이해서 이 오류를 나오게 하는것도 불가능은 아니다. 하지만 이럴경우 보통 컴파일러가 알아서 영역을 확장하도록 지시를 해놓기 때문에 재귀함수로 인한 과도한 함수호출이 아니면 보통 이런애러 잘 안난다.