1580, 3/79 회원가입  로그인  
   sihun1113
   [C기초] 12 - 삼항연산자(3항연산자)

http://www.hackerschool.org/HS_Boards/zboard.php?id=Free_Lectures&no=1748 [복사]


출저= 때릴꺼야
*----------------------------------------------------------------------------------------------------------*

이 카테고리는 그동안 배웠던것이라던가 공부하면서 알게된 내용들을 중심으로 혹여 참고가 될 수 있을까 싶은 내용들을

모아둔 곳입니다. 따라서 이 글들을 대상이 되는 분들은.. 프로그래밍을 갓 시작했거나 개념이 마구마구 흔들리시는 분들
정도가 되겠습니다. 그러니 너무 욕하지는 말아주세요 =_=;;;



혹시 제가 잘못 알고 있는 부분들이라던가 궁금한 것이 있으면 쪽지 남겨주시거나 리플을 달아주시면 감사하겠습니다.

*----------------------------------------------------------------------------------------------------------*





이번 스터디 주제로는 알면 강력한 3항연산자에 대해 알아볼까 합니다.



C 표준에는 꽤 많은 연산자가 있는데 보통 우리가 쓰는 것은 주로 이항 연산자입니다. 단항 연산자도 많이 사용되긴 합니다만, 이항 연산자에 비하면 그리 많이 쓰는 편은 아니지요.

대표적인 단항연산자에는 증가(++)연산자와 감소(--)연산자가 있고, 대표적인 이항연산자에는 대입(=)연산자와 사칙연산자, 비교연산자 등이 있지요. 이러한 연산자들은 많이 사용을 하고 있기 때문에 따로 언급 할 필요는 없을 것 같습니다.



그러나 3항 연산자의 경우, 용도는 물론이고 개념조차 모르는 분들이 생각보다 많은 것으로 알고 있습니다. 안다고 해 봐야 C를 처음 배울때 연산자의 종류와 우선순위를 배우면서 외우는 정도에서 그치는 분들이 대부분이지요.



왜 그럴까요?

아마도 3항 연산자는 대체 가능한 코드를 만들 수 있기 때문에 그 용도를 잘 모르고 지나치기 쉬운 까닭일겁니다.



그렇다면 3항 연산자가 무엇이냐? 그리고 왜 그걸 굳이 배워야 하느냐?



3항연산자란 말 그대로 3개의 피연산자를 필요로하는 연산자입니다. 그리고 3항 연산자는 딱 한가지만 존재합니다.

[ ? : ] 로 구성이 된 연산자 이지요. 대개 아래와 같은 식으로 설명이 되곤 합니다.





condition ? exp1 : exp2;             // condition이 참일때 exp1을 실행하고 거짓일때 exp2를 실행한다.





설명만을 놓고 봤을땐 모든 프로그래밍 언어의 기초 중의 기초인 if/else 문을 사용하는 것과 다른게 뭘까?라는 정도 밖에는 생각하기 힘듭니다.



네 맞습니다. 그냥 보기에도 삼항 연산자는 if/else문의 축약판입니다. 실제로도 삼항 연산자의 ? 는 if 를 의미하지요.

위 식을 if/else로 풀어 본다면





if( condition )

    exp1;

else

    epx2;





와 비슷한 의미가 됩니다.



하지만 단지 그것뿐이라고 한다면 굳이 삼항 연산자를 써야만 할 필요는 없겠지요. 진정 삼항 연산자의 위력이 나타나는 것은 단순한 실행의 의미로서가 아니라, 조건에 따라 특정 값을 반환하고자 할 때 입니다.



가장 대표적인 사용 예가 두 수를 비교하여 큰값 또는 작은 값을 구하는 경우입니다.

이를 if/else로 구현할 경우에는





int max;



if(Num1>Num2)

    max = Num1;

else

    max = Num2;





간단하지요? if/else 구문으로 구성 할 수 있는 가장 짧은 코드입니다.

그런데 한번 생각 해 봅시다. 이런 식으로 쓸 수는 없는걸까요?





max = if(Num1>Num2)

             Num1;

         else

             Num2;





하지만, 아쉽게도 저런 방법은 불가능 하지요. if는 단순히 분기만을 지정해 줄 뿐 리턴값을 반환해 주지 않기 때문인데요, 그러나 삼항 연산자를 사용하면 더 짧은 코드가 가능합니다. 왜냐하면 삼항 연산자가 바로 위와 같은, 우리가 바라는 기능을 갖는 연산자이기 때문입니다.

위 코드는 이렇게 바꿀 수 있습니다





max = Num1>Num2 ? Num1 : Num2





삼항 연산자는 반환값이 존재한다는 이유만으로도 존재 가치가 충분해 집니다.



또 한가지 아주 좋은 예가 바로 피라미드 그리기입니다.

반복문을 배울때 주로 연습하게 되는 예제들인 여러가지의 피라미드들 중에서 아래와 같은 모양을 만든다고 했을때



*****

*****

*****

*****

*****



보통은 아래와 같은 코드를 작성하게 됩니다.





for( i=0; i<5; i++ )

{

    for( j=0; j<5; j++ )

    {

        if( j>i )

            printf( "*" );

        else

            printf( " " );

    }

    printf( "\n" );

}





굉장히 간단한 예제 이지요? 조금만 생각 해 보면 쉽게 짤 수 있는 코드 입니다.

자, 그럼, 여기서 삼항 연산자는 어디에 쓰길래 그러나? 라고 하시겠죠? 바로 실전에 들어갑니다.



위의 코드에서 우리는 printf( "*" ); 와 printf( " " ); 를 사용해서 별과 공백을 표시하도록 만들었는데요, 여기에 삼항 연산자를 사용하게 되면, 어떻게 될까요?





printf( j>i?"*":" " );





과연 잘 동작을 할까요? 실험 해 봅시다.





----------------------------------------------------------------------------------

for( i=0; i<5; i++ )

{

    for( j=0; j<5; j++ )

    {

        printf( j>i?"*":" " );

    }

    printf( "\n" );

}

----------------------------------------------------------------------------------

****
  ***
   **
    *

----------------------------------------------------------------------------------





에러 없이 잘 동작을 하고 있군요. 그리고 이런것도 가능합니다.





printf( cls?"[총점:%d]":"[평균:%d]", cls?total:aver );





위 코드는  클래스가 true라면 총점을, false라면 평균을 출력하도록 하는 예제 입니다. 그러나 좀 보기가 편하지는 않죠?

도대체 뭐에 맞춘 포멧인지도 모르겠고, 아무튼 읽기 편한 방법은 아닙니다. 그래서 이걸 조금 정리 해 보겠습니다.





printf( "[%s:%d]", cls?"총점":"평균", cls?total:aver );





일단 포멧은 포멧대로, 출력 변수들은 변수들 대로 따로 모아 두었습니다.

사실 위와 같은 경우에 사용하기엔 코드 줄 수를 줄이는 것 외엔 그다지 메리트가 없으므로 굳이 쓸 필요는 없습니다만, 만약 6~7개의 포멧이 한꺼번에 나오는데 그 중에 겨우 한두가지 정도만 조건에 따라 바뀌어야 한다던가, 겨우 변수 하나 때문에 if/else문을 나누어야만 하는 경우가 생길때 등은 매우 유용합니다.



예를들어 주소록 같은 프로그램에서 다음과 같은 양식으로 출력을 한다고 생각해봅시다.





| 이름 | 성별 | 나이 | 생일 | 전화번호 | 학교/직장 | 주소 |





대충 예상 되는 포멧은 아래와 같을겁니다.




( "| %s | %s | %d |  %d월 %d일 | %s | %s | %s |", name, sex, age, birthM, birthD, phone, job, addr );





이 요소들 중에서 이름과 나이, 생일, 전화번호, 학교/직장, 주소의 경우는 다 고유한 숫자나 문자로 기록을 해야겠지만, 성별의 경우는 남/여 단 두가지밖에 존재하지 않습니다. 다른 요소들은 어쩔 수 없이 다 문자나 숫자로 저장을 해야 한다고 해도, 성별까지 굳이 문자열(특히 한글은 2byte문자이기 때문에 문자열로 저장됨)로 저장하는 것은 굉장한 메모리 낭비가 됩니다. 그래서 주로 성별을 저장할 경우에는 boolen 값으로 저장을 하게 되는데, 이를 표현하고자 할때가 문제가 됩니다.



성별에 따라 (남자를 true라 했을때)





if( sex )
    printf( "| %s | 남 | %d |  %d월 %d일 | %s | %s | %s |", name, age, birthM, birthD, phone, job, addr );

else

    printf( "| %s | 여 | %d |  %d월 %d일 | %s | %s | %s |", name, age, birthM, birthD, phone, job, addr );





라고해서 if/else문으로 가르는 건 상당히 소모적으로 보이구요, 그렇다고해서





printf( "| %s |", name );

if( sex )

    printf( " 남 |" );

else

    printf( " 여 |" );

printf( " %d |  %d월 %d일 | %s | %s | %s |", age, birthM, birthD, phone, job, addr );





라고 조각내서 출력하자니, 이것도 이것 나름대로 웃깁니다.

그래서 이럴때 삼항 연산자를 쓰면 매우 간결하게 표현이 됩니다.





( "| %s | %s | %d |  %d월 %d일 | %s | %s | %s |", name, sex?"남":"여", age, birthM, birthD, phone, job, addr );





간단히 정리가 되었죠?



마지막으로 한가지 응용 한가지.

두수의 최대값을 구하는 코드는 위에 설명했으니 세 수 중 최대값을 구하는 코드는 어떻게 작성 할 수 있을까요?

이것 역시 삼항 연산자를 중복시키면 굉장히 간단히 끝납니다.

답을 보시기 전에 먼저 if/else문으로 세 수의 최대값을 구하는 코드를 작성해 보세요.

그리고 삼항 연산자를 사용해 구하는 코드를 작성 해 보신 후 답과 비교 해 보세요.





max = (Num1>Num2) ? (Num1>Num3)?Num1:Num3 : (Num2>Num3)?Num2:Num3;





실제로 고수들이 짜 놓은 코드들을 보면, 특히 루프가 다수 등장하고, 많은 비교를 필요로 하는 코드들을 잘 눈여겨 보시면 곳곳에 삼항 연산자가 쓰여있는 것을 확인 하실 수 있을겁니다.

이렇게 별것 아닌 것 같아 보이는 연산자 하나도, 모이면 어마어마한 차이를 낳게 되는것이랍니다.

많이 써 보세요. 그것이 바로 초보를 벗어나는 지름길이 됩니다.



삼항 연산자에 대한 소개는 여기까지 끝내기로 하고, 다음으로는 반복문에 대해서 알아볼까 합니다.

그럼 다음 스터디에서 뵙겠습니다.

  Hit : 18924     Date : 2011/05/01 11:36



    
1540   [자작] ssh / sftp 사용법 정리 (포트설정시)[1]     soohosin
02/15 20366
1539   D.H 의 HTML 강의 (1) 해킹의 기초[13]     DH_ 99
10/12 20133
1538   [자작]해킹하는데 C언어는 필요한가     dontknow
07/23 20071
1537   어셈블리어 강좌 5편     asdzxc301
12/13 19801
1536   cmos비밀번호 푸는 방법[25]     idl0521
12/29 19396
1535   [연습용 C자작] 스도쿠 소스[5]     Ilios
05/24 19239
1534   해킹당한 서버에서 확인해야할일[9]     소유
09/21 19169
1533   패스워드 알아내기 1[15]     geniusevil
12/15 19045
  [C기초] 12 - 삼항연산자(3항연산자)     sihun1113
05/01 18923
1531   네트워크 개념 휘어잡기 1[24]     소유
09/10 18628
1530   어셈블리어 총정리 강좌     asdzxc301
12/13 18609
1529   좋은 비밀번호란???[24]     소유
09/04 18396
1528   [펌] 리눅스 job, bg, fg에 관한 고찰[1]     qpt0707
04/06 18213
1527   [c언어] 문자열을 입력받아 거꾸로 출력하기[8]     H.R.T
12/15 17933
1526   sql 인젝션 공격기법[4]     subroutine
01/11 17865
1525   C언어로 만든 그래픽 프로그램[11]     승리의박성환
04/22 17857
1524   유치원 만화 크게보기[11]     소유
09/03 17710
1523   [자작] 한번 분석해본 보이스채팅 프로그램.[7]     푸른하늘
08/23 17698
     [공지] 강좌를 올리실 때는 말머리를 달아주세요^ㅡ^ [29] 멍멍 02/27 17578
1521   해커스랩 레벨 0 깨는 방법 - 시작하기[22]     불사
05/21 17368
[1][2] 3 [4][5][6][7][8][9][10]..[79]

Copyright 1999-2023 Zeroboard / skin by Hackerschool.org / Secure Patch by Hackerschool.org & Wowhacker.com