C/C++ 언어 표준 코딩 정하기

2008. 11. 12. 15:39 컴퓨터/컴퓨터 이야기

아래의 글은 제가 운영하는 임베디드 리눅스 포럼인 FALINUX 포럼에 올린 글입니다. 저 혼자 작성하는 프로그램이라면 마음 편히 작성하면 되겠습니다만, 포럼에 자료를 올릴 때에는 작은 샘플 프로그램이라도 규칙을 가지고 작성해서 올리고 싶어서 C 언어 표준 코딩을 정리하게 되었습니다.

FALINUX 포럼에 올린 글을 여기에 올리는 이유는, 포럼보다 jwmx 블로그에 손님이 많아, 더 많은 분의 관심과 말씀을 기대하고 싶어서 입니다. 처음 글이라 빠진 부분도 많아서 앞으로 방법을 계속 추가하려 합니다만 잘 될지 모르겠습니다. ^^

표준 코딩 규칙의 필요성

gxLib와 관련하여 최근 글인 "PNG 이미지 출력을 위한 분석 1"을 올렸습니다만, 첨부된 gxLib 0.5.6 버전을 보시고 황당해 하실지 모르겠습니다. 왜냐하면, 함수 이름과 광역 변수 이름이 대소문자에서 소문자와 밑줄(언더 바)로 바로 바뀌었기 때문이죠. 저도 처음 C 언어를 사용했을 때에는 소문자만 사용했습니다. 그리고 두 개 이상의 단어가 조합된다면 밑줄로 구분했죠.

그러다가 Microsoft Windows 프로그래밍으로 넘어 가면서 헝가리언 명명법에 따라 대소문자를 사용하게 되었는데, 처음에는 이상했지만 몇 년 동안 사용하다 보니 익숙해져서, 이제는 소문자로만 작성하는 것이 이상합니다. 그래서 눈 딱 감고, gxLib를 대소문자로 변경했습니다만, 예전처럼 소문자로 바꾸어 달라는 요청이 많아서(실은 몇 분 안 되지만, 그나마 이렇게 말씀을 주시는 경우가 없었던 경험으로 봐서 많은 편입니다. ^^;) 다시 소문자로 변경하게 되었습니다.

앞으로 gxLib가 점점 커져갈 것이고, gxLib뿐만 아니라 다른 라이브러리도 작성할 것이며, 작은 샘플 프로그램이라도 미리 대비하여 표준 코딩 방법을 정해야 하지 않을까 해서, 이렇게 글을 올리게 되었습니다.

C 언어의 어려움

C 언어의 가장 큰 특징이라면 역시 자유로움이라고 생각합니다. 또 많은 분이 그렇게 생각하시리라 생각합니다. C 언어를 사용하다가 다른 언어를 사용하면, 왜 이렇게 타이프할 것이 많은지요. 그러나 자유로운 만큼 문제도 많아서 프로그래머별로 코딩하는 개성이 매우 뚜렷해서, 때로는 소스를 분석하는데 어려움을 느낄 때가 많습니다.

그래서 팀을 이루게 되면, 제일 먼저 표준 코딩 방법부터 정하고 시작하는데, 그마만큼 들여쓰기부터 눈에 거슬리는 것이 C 코딩입니다. 물론 다른 언어도 그렇겠습니다만, 유독 C 코딩은 유별난데가 있습니다. 오죽하면 남들이 이해하지 못하게, 아주 어렵게 짜는 대회가 있었겠습니까. 오래 전의 기억입니다만, 1등했던 코드를 봤더니 무슨 암호문 같더라는 거죠.

다른 분의 소스를 분석할 때에는 먼저 들여 쓰기나 블록의 시작과 끝인 { 와 } 문자의 위치, 등등을 먼저 맞추어 놓고 시작하시는 분도 많이 보았습니다.

포럼 표준 코딩 ver 0.0.1 작성에 대한 이야기

버전 번호를 붙여 놓은 이유는, 저도 최근에 C 언어를 다시 시작했기 때문에 가장 좋은 방법을 알지 못합니다. 그래서 코딩 중에 방법을 자꾸 바꾸게 됩니다. 또한, 제 생각뿐만 아니라 가끔 건의도 받는 형편이라 앞으로 코딩 방법을 버전으로 관리하고 싶어서 사용하게 되었습니다.

함수, 변수 명명법

일단 간단한 것부터 차례로 정리하죠. 첫 번째 상수입니다. C 언어에서는 상수를 #define 문을 이용하게 되는데, 상수는 대문자와 밑줄로 작성합니다. 예로 아래와 같이 말이죠.

#define BUFFER_MAX_SIZE    1024

두 번째로 함수와 변수의 명명법을 말씀드려야 하는데, C 언어에서는 대부분이 소문자와 밑줄을 애용하시더군요. Microsoft C/C++이나 파스칼을 사용하시는 분은 대소문자를 섞어 사용하시는데, 대소문자를 섞어 사용하는 방법도 다양합니다.

헝가리안식 표기법을 애용하시는 분은 변수의 유형을 접두사로 사용하여 아래와 같이 사용합니다.

int   nWidth, nHeight;

함수 같은 경우는 반환하는 값이 있더라도 변수 유형까지 넣지는 않고 그냥 대소문자를 사용하시는, 단어가 두 개 이상이라면 역시 프로그래머에 따라 개성이 나옵니다.

int   showMessage()
{
   첫번째 단어는 소문자로 시작
}
int   HideWindow()
{
   단어는 모두 대문자로 시작
}

이렇게 두 개 단어 이상일 경우에는 첫 번째 단어를 소문자로 시작하는 경우가 있는데, 대표적으로 QT 함수가 이렇게 되어 있습니다. 그러나 대부분 모두 대문자로 시작하죠. 그러나 단어가 하나일 경우에는 소문자로 하시는 분도 있습니다.

int   ShowMessage()
{
   단어는 모두 대문자로 시작
}
int   show()
{
   단어가 하나라 구분할 필요 없을 때에는 소문자로 사용
}

그러나 포럼에서는 C 언어에서는 모두 소문자와 밑줄을 사용하기로 하겠습니다. 이유는 정말 많은 C 프로그래머가 소문자와 밑줄을 사용하시기 때문입니다. 저 혼자 모든 일을 처리하면 좋겠지만, 인터넷 세상에서 다른 사람의 코드를 자주 봐야 하는 일이 많아서, 많이 애용하는 방법을 따르는 것이 아무래도 좋겠다는 생각에서 입니다.

물론 개성을 중시할 수 있겠습니다만, 그만큼 다른 분과 같이 일할 때에는 나뿐만 아니라 다른 분도 고통을 감수해야 하기 때문에 될 수 있으면 개성보다는 다수가 사용하는 방법이 좋으리라 생각됩니다.

블록 구조

이 또한 매우 말이 많은 부분이라 때론 말싸움이 나올 정도입니다. 프로그래머가 아닌 사람이 보면, 뭘 저런 것 가지고 싸우나 하겠지만, 블록의 시작 키워드인 '{' 나 '}' 문자의 위치는 아주 오래전부터 논란거리였습니다. 공백 몇 개 차이인데, 정말 싸움까지 난다니까요. C 언어를 사용하는 프로그래머의 개성이 가장 두드러지게 나오는 부분이 바로 이 부분으로 몇 가지 유형을 보겠습니다.

// 유형 1
if ( )
{
   처리 내용
}
else
{
   처리 내용
}

// 유형 2
if ( ){
   처리 내용
}
else{
   처리 내용
}

// 유형 3
if ( ){
   처리 내용
} else{
   처리 내용
}   

// 유형 4
if ( ){
   처리 내용
   }
else{
   처리 내용
   }

이 외에도 더 많은 유형이 있습니다만, 과연 여러분은 어떤 유형을 사용하시나요? 제 경험상으로 가장 많이 사용하는 유형은 1번 이라고 생각되어 포럼 표준 코딩에서는 유형 1번을 따르겠습니다.

사실 저는 유형 4번을 사용하고 있었습니다. 블로 구분이 뚜렷하고, 한 화면에 많은 행을 볼 수 있어서, 처음 C를 할 때부터 유형 4번을 사용했습니다. 그래서 유형 4번으로 고집을 부리고 싶었지만, 포럼인 만큼 학습 사이트이고, 앞으로 온라인에서 다른 사람의 소스를 자주 봐야 하는 관계로, 역시 많이 사용하는 유형을 따르는 것이 좋겠다고 생각되서 입니다.

탭 문자 보다는 공백문자

의외로 이 부분은 말씀드리기 쉽습니다. 탭 문자를 사용하시던 분도 몇 번 말씀 드리면 두말없이 바꾸는 것이 공백문자 사용입니다. 일단 탭 문자는 사용하는 사람마다 지정한 공백 문자 개수가 틀립니다. 기본이 8자이지만 이렇게 사용하시는 분은 드물고, 3개 또는 4개 공백문자를 지정해서 사용합니다.

문제는 탭 문자가 삽입된 소스코드 그대로 다른 사람에게 전달하면 아래와 같은 문제가 발생하게 됩니다.

int count_ethercard( void)
{
  FILE   *fp;
  char    buff[BUF_SIZE];
         char   *cmd_ifconfig   = "ifconfig -a ¦ grep eth";
  int    cnt_ether;

  fp = popen( cmd_ifconfig, "r");
         if ( NULL == fp)
    return 1;

  // 랜카드의 개수는 출력되는 행의 개수로 확인한다.
         cnt_ether = 0;
  while( NULL != fgets( buff, BUF_SIZE, fp))
    cnt_ether++;
  pclose(fp);

  return cnt_ether;
}

짧은 루틴도 이렇게 엉망으로 보이는데, 하물며 긴 소스일 경우에는 황당하죠. 그러나 탭 문자를 사용하지 않고 공백 문자만 사용한다면 이런 경우가 실수가 아니면 발생하지 않습니다.

탭 크기

소스 파일 내에서는 탭 문자를 사용하지 않기로 했지만, 탭 키는 사용해야 하므로 탭에 대해 공백 문자 몇 개를 사용해야 할지를 정해야 합니다. 탭에 대한 공백 문자는 얼마만큼 들여쓰기를 하겠냐는 내용이라, 이 부분도 말씀이 많습니다. 심한 경우는 공백 문자 하나를 사용하시는 분을 본 적이 있습니다. 탭 문자까지 손이 가는 것이 귀찮다나요? 이그~ 뭐, 개성이면 개성이니 뭐라 못하겠습니다. 포럼 표준에서는 3개의 공백 문자를 사용하겠습니다.

이유를 설명 드리면 if ()문 때문입니다. 공백 문자 3개이면 아래와 같이 들여쓰기가 됩니다.

if ( )
{  ¦
   처리 내용
}  ¦
else
{  ¦
   처리 내용
}

함수 별 주석 달기

주석 달기도 참, 말이 많지요. 사용하시는 분마다 천차만별한 것이 주석 달기입니다. 우선 모듈 단위의 주석을 보겠습니다. 이 방법은 다른 분의 방법을 모으고 모아서 정리한 것인데, 너무 길어도 좋지 않더군요. ^^

/********************************************************************************
 모  듈 : tcp/udp 소켓 사용
 작성자 : 장길석
 버  전 : 0.0.2
 설  명 : netrx 를 위한 tcp/udp 소켓 사용함수 정의 
 참  고 :
 
          1. tcp 는 서버 모드로 설정한다.
          2. udp 는 상대 PC 로 전송하기 위한 IP 를 처음에
             가질 수 없기 때문에 따로 상대 PC IP 를 지정하여
             전송에 사용한다.
             
             ip_sock_t 에서 to_ip, to_addr

 버  전:
         0.0.1  tcp/udp 처리를 하나로 묶음
         0.0.2  udp 소켓을 위해 ip_sock_t 에 to_addr 과 to_ip 추가
                to_ip   : string    목적지 ip
                to_addr : in_addr_t 목적지 ip 에 대한 inet_addr() 값
********************************************************************************/

이와 같이 /* */ 문자를 사용했으며, 내용에는 모듈에 대한 제목과 작성자의 이름, 버전 번호, 설명 및 참고, 버전별 수정 내용을 입력합니다.

함수에 대한 주석

함수별로 주석을 다는 것도 매우 중요합니다. 문제는 너무 화려하게 하면 소스 코드 길이가 늘어나서 어지러워 보이더군요. 예를 들어 아래와 같은 경우입니다.

// gx_get_buffer_dc -------------------------------------------------------------
// 설명: 화면 출력을 빠르게 하기 위한 버퍼 DC를 구함.
// 참고: BitBlt를 빠르게 처리하기 위해 DC Type를 DCTYPE_SCREEN으로 지정한다.
// 인수: width       버퍼의 폭
//       height      버퍼의 높이
// 반환: 버퍼 Device Context 핸들
//-------------------------------------------------------------------------------
dc_t *gx_get_buffer_dc( int width, int height)
{
   int   szStruct;
   dc_t  *dc;

   szStruct = sizeof( dc_t);

함수 이름이 코드에 있음에도 주석에 또 달아 놓았습니다. 그리고 함수 코드 부분에 있는 인수 설명이 위에 있다 보니 연결이 되지 않고, 주석이 함수 코드 위에 있어서 같은 몸뚱이로 보이지 않고 다른 부분으로 보이고, 프로그램 중에도 위에 있는 주석을 확인하지 않는 문제가 있습니다.

그래서 아래와 같이 주석을 함수 이름 밑에 두며, 설명, 참고, 인수 및 반환 값에 대한 정보를 입력합니다.

dc_t *gx_get_buffer_dc( int width, int height)
// 설명: 화면 출력을 빠르게 하기 위한 버퍼 DC를 구함.
// 참고: BitBlt를 빠르게 처리하기 위해 DC Type를 DCTYPE_SCREEN으로 지정한다.
// 인수: width       버퍼의 폭         --> 변수와 설명은 공백 문자 여러 개로 분리
//       height      버퍼의 높이
// 반환: 버퍼 Device Context 핸들
{
   int   szStruct;
   dc_t  *dc;

   szStruct = sizeof( dc_t);

함수 내부의 주석

함수 내부의 주석은 아래의 두 가지 모두 사용하겠습니다.

                    :
dc->release_dc       = release_buffer_dc;
dc->bits_per_pixel= gx_fb.bits_per_pixel;   

// 칼라 깊이에 따라 라인 별 소요되는 바이트를 계산하며,
// 깊이에 따른 가상 함수를 지정한다.

switch( gx_fb.colors)
{
case 1   :  dc->bytes_per_line  = width / 8;
                    :

또는

                    :
dc->release_dc       = release_buffer_dc;
dc->bits_per_pixel= gx_fb.bits_per_pixel;   
/*
 * 칼라 깊이에 따라 라인 별 소요되는 바이트를 계산하며,
 * 깊이에 따른 가상 함수를 지정한다.
 */
switch( gx_fb.colors)
{
case 1   :  dc->bytes_per_line  = width / 8;
                    :

행 별 주석 달기

행별 주석은 // 를 사용하며, 시작은 81 열부터 합니다. 81 열인 이유는 탭 크기가 공백 3 문자이기 때문입니다. 예전에는 81 열보다 작은 72  열을 사용했지만, 요즘 모니터가 와이드형이 많아서 72 열은 너무 작더군요.

결언

아직 더 정리할 내용이 많습니다만, 앞으로 계속 추가해 가도록 하겠습니다. 이제 위의 내용을 정리해 보겠습니다. 표준 코딩에 대해서는 당연히 여러 주장이 있겠습니다. 좋은 생각과 많은 의견을 올려 주시면, 수렴하여 표준을 계속 정립해 나가겠습니다.

포럼 표준 코딩 0.0.1

  • 규칙 1) 상수는 모두 대문자와 밑줄(언더 바)을 이용한다.
    BUFFER_SIZE, WIDTH_MAX, USER_CAPTON

  • 규칙 2) 함수와 변수는 모두 소문자와 밑줄을 이용한다.
    show_message(), bmp_filename, hide()

  • 규칙 3) 블로 들여쓰기는 아래와 같이 블록의 시작과 종료 문자를 블록의 시작에 위치한다.
    if ( )
    {
    }
    else
    {
    }
    for ()
    {
    }
    while ()
    {
    }


  • 규칙 4) 탭 문자 크기를 공백 문자 3개로 한다.

  • 규칙 5) 탭 문자를 사용하지 않는다. 들여쓰기는 모두 공백 문자를 이용한다.

  • 규칙 6) 모듈 별 주석 달기(소스 상단의 전체 주석)
    /* */를 사용하며, /*****.....**** 의 마지막 별은 81 열까지 배열한다.
    /********************************************************************************
     모  듈 : tcp/udp 소켓 사용
     작성자 : 장길석
     버  전 : 0.0.2
     설  명 : netrx 를 위한 tcp/udp 소켓 사용함수 정의 
     참  고 :
     
              1. tcp 는 서버 모드로 설정한다.
              2. udp 는 상대 PC 로 전송하기 위한 IP 를 처음에
                 가질 수 없기 때문에 따로 상대 PC IP 를 지정하여
                 전송에 사용한다.
                 
                 ip_sock_t 에서 to_ip, to_addr
    
     버  전:
             0.0.1  tcp/udp 처리를 하나로 묶음
             0.0.2  udp 소켓을 위해 ip_sock_t 에 to_addr 과 to_ip 추가
                    to_ip   : string    목적지 ip
                    to_addr : in_addr_t 목적지 ip 에 대한 inet_addr() 값
    ********************************************************************************/
        

  • 규칙 7) 함수별 주석 달기
    함수 이름 밑에 '//' 주석 문을 사용하며, 설명, 참고, 인수, 반환을 입력한다. 작성할 내용이 없으면 생략
    dc_t *gx_get_buffer_dc( int width, int height)
    // 설명: 화면 출력을 빠르게 하기 위한 버퍼 DC를 구함.
    // 참고: BitBlt를 빠르게 처리하기 위해 DC Type를 DCTYPE_SCREEN으로 지정한다.
    // 인수: width       버퍼의 폭
    //       height      버퍼의 높이
    // 반환: 버퍼 Device Context 핸들
    {
       int   szStruct;
       dc_t  *dc;
    
       szStruct = sizeof( dc_t);

  • 규칙 8) 함수 내부 주석 달기
    // 와 /* */ 두 가지 모두 사용한다.
                        :
    dc->release_dc       = release_buffer_dc;
    dc->bits_per_pixel= gx_fb.bits_per_pixel;   
    
    // 칼라 깊이에 따라 라인 별 소요되는 바이트를 계산하며,
    // 깊이에 따른 가상 함수를 지정한다.
    
    switch( gx_fb.colors)
    {
    case 1   :  dc->bytes_per_line  = width / 8;
                        :

    또는

                        :
    dc->release_dc       = release_buffer_dc;
    dc->bits_per_pixel= gx_fb.bits_per_pixel;   
    /*
     * 칼라 깊이에 따라 라인 별 소요되는 바이트를 계산하며,
     * 깊이에 따른 가상 함수를 지정한다.
     */
    switch( gx_fb.colors)
    {
    case 1   :  dc->bytes_per_line  = width / 8;
                        :

  • 규칙 9) 행별 주석 달기
    81 열에 // 코드로 주석을 삽입한다. 81 열인 이유는 탭 문자에 대해 공백문자 3개를 이용하기 때문입니다.
이 댓글을 비밀 댓글로
  1. 저도 항상 새로운 사람이 오게 되면 예전에 작성해 두었던 Programming Guide라는 문서를 먼저 보게 합니다.
    서로의 코딩 스타일이나 방식이 다르면 나중에 더 복잡한 일이 생기는 경험이 있어서..
    하지만, 정작 당사자들도 필요성은 느끼지만 쉽게 적응하지는 못하더라구요.. 이것도 스트레스라고..^^
    그 이야기를 듣고 내용을 좀 더 최대한 단순화 시키면 제각각의 코딩 스타일이 나오고..^^

    결국 푸념이네요..^^

    아.. 참고로 위의 내용에서.. 저의 경우 함수명에서도 접두사를 사용하도록 하고 있습니다.. 함수명만으로도 리턴 타입을 알 수 있도록.. 저는 이게 유용하더라구요..^^
    • 하하, 네. 코딩 습관을 바꾸기에는 참 쉽지 않죠.
      저도 경험했습니다만 말싸움이 심해지는 경우도 있었습니다.
      함수명에서도 접두사를 사용하시는 군요. ^^
      저도 접두사를 사용합니다만, 리턴 타입은 아니고 업무에 관련된 접두사를 사용합니다.
      gx_어쩌구저쩌구() rs_어쩌구저쩌구() ^^
    • 소우
    • 2008.11.12 21:48
    늘 좋은 프로그램 잘 쓰고 있습니다. 간만에 아는 이야기가 나와서 한마디 적고 갑니다.

    저같은 경우는 C에서 변수선언시 형을 써줍니다.

    int --> itmp
    char --> ctmp
    long --> ltmp

    등등입니다. 나중에 변수볼때 편리해서 이렇게 코딩을 합니다.
    • 아하~ 접두사에 밑줄을 사용하지 않으셨군요. 그래도 보기 좋네요.
      저는,

      int --> n_temp
      char ---> ch_temp
      long ---> l_temp

      이렇게 사용했거든요. 흠~ 그러나 접두사를 한자만 사용하면
      소우님 말씀처럼 밑줄 없이 사용할 수 있겠네요.
      좋은 말씀 매우 감사합니다. ^^
    • jinisopen
    • 2008.11.13 02:24
    큰 사이트 가면 코딩 규칙만 책 몇권이죠...ㅎㅎ
    • 하하....저는 어느 회사 표준 코딩 책을 사진으로만 보았는데,
      무슨 메뉴얼로 보일 정도로 두껍더군요. ^^
  2. 변수,함수 명명법도 한번 서술해주셨으면 좋겠습니다.. ^^

    예를들면
    Variable은 주로 명사이며, 첫 대문자로 시작한다. iCount, fMean..
    Parameter Variable은 마지막에 _를 붙인다. int f(int iCount_);
    return Variable은 마지막에 _r를 붙인다. iCount_r
    global Variable은 마지막에 _g를 붙인다. iCount_g
    Procedure는 동사+인자이며, 첫소문자로 시작한다. showCount(iCount);
    Function은 반환타입+입력타입이며, 모두 소문자로 연결한다. TPnt2 Pnt2_r = pnt2_pnt3(TPnt3 Pnt3_);
    • 열혈사용자
    • 2008.11.14 09:32
    표준코딩 정말 필요해요. 저도 남이 짜논 소스 보다보면 정말 열불이 날때가 한두번이 아니었습니다.
    그래서 저는 되도록이면 자세한 주석과 함께 알아보기 쉽게 작성하려고 하죠.
    요런거 널리 퍼지면 좋겠네요.
    정말 수고하셨어요~~~~
    • Jay
    • 2008.11.19 01:26
    좋은 글 읽고 갑니다. 감사합니다. 업데이트 기다리겠습니다.
    • ㅇㅇㅇㅇ;;
    • 2010.12.21 06:57
    잘 읽고 갑니다..

    그런데, 정말 죄송합니다만, c언어에서는 #define 으로 변수를 'c 문서 안에 정하는 방법' 밖에 없나요?

    다른 명령어로 손 쉽게, 프로그램 상에서 define으로 정의 내리는 값을 입력하게 할 순 없나요..

    한참 이거 찾아다니고 있었는데, 도무지 마땅한 자료를 찾을 수 없네요..
    • 예를 들어 주시면 저도 고심해 보겠습니다. ^^
      • ㅇㅇㅇㅇ;;
      • 2010.12.22 17:25
      일단, c언어를 배운지 얼마 안되는지라 쩔쩔 매는 가운데
      고심해주시겠다는, 선심을 풀어주셔서 정말 감사합니다.ㅠ
      아래의 예는 제가 짠, 간단한 역행렬을 구하는 프로그램의 일부에요.

      #include <stdio.h>
      #define n 3

      void matdisp(double mat[][n])
      {
      int i,j;

      for( i=0 ;i < n;i++)
      {
      for( j=0 ;j < n;j++)
      printf("%.2e\t",mat[i][j]);
      printf("\n");
      }
      }

      int main(void)
      {
      int i,j,k;
      double a,b;
      int flag;

      double ma[n][n]={0};
      double mb[n][n]={0};
      double mc[n][n]={0};
      double tmp=0.;

      for( i=0 ;i < n;i++)
      {...
      ...

      위에 프로그램 짠 것을 과제로 제출하고보니 어떻게하면 프로그램을 실행했을 때
      행렬의 크기를 입력하고 역행렬을 구할 수 있을까 하곤 흥미가 붙어서
      여러가지 방법으로 도전을 해봤지만 역시 실력이 짧아서 그런지 에러만 뜨네요..ㅠ
      염치 불구하지만 여쭈어봅니다..ㅇㅇ;

      (위는 n=3일때의 경우지만, 프로그램 실행할 때 n의 값을 입력해서 실행하고 싶네요..ㅠ
      저 상태로는 3*3에서 밖에 못쓰니.. 뭔가 활용도를 높히고 싶다랄까...)
    • 님 저도 잘 하는 실력은 아니지만

      #define n 3

      이렇게 하시면 문제가 됩니다

      printf문도 pri3tf가 되기 때문이죠

      그래서 define 을 쓸때는 대문자나 특수 기호를 써서 하는 게 좋습니다

      #define NUM 3 이런 식으로 하세요

      전처리기는 말 그대로 어떤 문자를 다른 문자로 치환 하는 기능이 있기 때문입니다

      도움이 되셨으면 좋겠네요
  3. 자민님께서 매우 명쾌하게 설명해 주셨네요. ^^
    한가지 아쉬운 점은 상수를 사용하셨기 때문에
    컴파일 때에 크기가 고정이되는 단점이있습니다.
    그래서 다양한 크기의 행렬을 계산하는 함수로 만들기 어렵지요.
    함수로 구현이 필요하시면 포인터를 사용하여 구현해 보시면 어떨까요?
    아래처럼 말이죠.


    void matdisp(double **pmat, int nCellSize)
    {
    int i,j;

    for( i=0 ;i < nCellSize;i++)
    {
    for( j=0 ;j < nCellSize;j++)
    printf("%.2e\t",mat[i][j]);
    printf("\n");
    }
    }

    int main(void)
    {

    matdisp( pMat, 3);
error: Content is protected !!