[c언어] 조건문에 대한 궁금증...

icabord의 이미지

안녕하세요.

기초적인 질문만 올리지만, 특히나 C언어 대한 궁금증을 올리려고 합니다.

보통 다중 for 문과 다중 if 문은 지양해야할 코딩습관 중 하나라고 들었습니다.

또한 || 연산은 좌에서 우로 연산이 됨으로 가장 우선적인 조건을 앞에 달았을 때, 연산 결과에 따라 뒤의 연산을 할 필요가 없기 때문에 효율적인 코딩습관 중 하나라고 들었습니다.

그런데 요즘 소스를 보다보니, 아래와 같은 소스가 있습니다.

if (A==1 || B==2) && ((C==4 && FuncA(i)) || (E==6 && FuncB(j))) .....
{
printf("???\n");
}

가장 우선시 해야할 A, B 값에 따라 굳이 뒤에 오는 값들을 볼 필요가 없을 수도 있기 때문에(더군다나 뒤의 연산이 함수인 경우) 속도면에서 효율적일 것 같습니다.

하지만 저기에서 조건이 하나 늘어날때 마다 스트레스 또한 늘어나게 되는데,

여기서 궁금한 점은 아래와 같은 식으로 조건을 간단히 하되 중복 조건문을 많이 두게 되면,

if (A==1 || B==2))
{
if ((C==4 && FuncA(i)) || (E==6 && FuncB(j)))
{
.....
printf("???\n");
}
}
else
;

효율이 많이 떨어지거나 잘못된 코딩 습관일까요?

속도면에서나 기타 다른 문제가 없다면 아래 방식으로 바꾸고 싶습니다.

조언 부탁드립니다.

clique의 이미지

속도 차이 거의 안납니다. 기껏해야 인스트럭션 몇 개일 테고요, 컴파일러가 최적화 해서 똑같을 수도 있겠군요. 그러나 가독성 면에서는 훨씬 나아 보입니다.

jick의 이미지

두 경우 컴파일러가 해야 할 일은 정확히 같습니다.

if (A && B) { ... }
A가 참일 경우에만 B를 계산, B가 참이면 코드 수행.

if (A) { if (B) { ... } }
A가 참일 경우에만 B를 계산, B가 참이면 코드 수행.

자, 똑같죠?

||, && 연산이 "효율적"이라고 하는 것은, 뒤의 수식을 경우에 따라 계산할 필요가 없으면 안 하기 때문에 *무조건 둘 다 계산하는 것보다* 효율적이라는 의미지, 정확히 같은 방식으로 계산하는 다중 if 문보다 효율적이라는 얘기가 아니죠.

마찬가지로 다중 if문을 삼가라는 얘기는 코드를 가급적 리팩터링해서 별도의 함수로 빼든가 해서 아예 다중 if문이 나타나지 않으면 더 좋다는 얘기지, 다중 if문에서 하는 로직과 똑같은 로직을 한줄에 우겨넣으면 더 보기 좋다는 뜻이 아니죠. (그러니까 사과와 오렌지를 비교하고 계신 겁니다.)

가독성은 주관적이지만, 조건을 지나치게 길게 쓰는 것보다는 if 문을 여러 겹으로 쓰는 게 일반적으로 가독성이 좋을 겁니다.

whitenoise의 이미지

제 경우는 80 칼럼 안에서 적당히 해결할 수 있을 정도의 조건식은 indentation으로 처리를 합니다.
관련 있는 부분은 한곳에 모아놓는게 좋아서 if 중첩보다 선호합니다만, 각자 스타일 따라 호불호가 갈릴 수 있을 거 같습니다.
--------

if (   ( A == 1 || B == 2 )
    && (   ( C == 4 && FuncA(i) )
        || ( E == 6 && FuncB(j) ) ))
{
    printf("???\n");
}

조건식에 사용된 변수 또는 함수명이 길거나 depth가 깊어져서 한눈에 안들어올 정도이고, 중요한 조건식이라 readability가 최우선일 경우라면, 아예 conditional expression을 의미 단위로 잘라 적당한 이름의 함수로 만들어버립니다. 함수 이름만 잘 정하면 이게 readability는 젤 좋아보이네요.

/* Conditions */
#define isCond1(x,y)    ( (x) == 1 || (y) == 2 )
#define isCond2(x,y)    ( (x) == 4 && FuncA(y) )
#define isCond3(x,y)    ( (x) == 6 && FuncB(y) )
 
if (    isCond1(A,B)
    && (   isCond2(C,i)
        || isCond3(E,j) ) )
{
    printf("???\n");
}
vacancy의 이미지


스트레스가 무슨 의미로 사용되었는지 모르겠네요.

두 구현은 jick님 말씀대로
대부분의 컴파일러에서 똑같은 컴파일 결과를 냅니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.