C언어의 콤마 연산자에 대해서...

gurumong의 이미지

for(i=1,j=1;j<10,i<10;j++)
{
...
}

친구가 작성한 이 코드를 보고 문법에 틀린게 아닌가 생각이 들었는데
왜냐하면 콤마 연산자는 두 문장을 이어주는 역활을 하는것인데
for문에 들어갈 조건식에 사용되면 의미상으로 전체 수식이 참인지, 거짓인지 구별하지 못할꺼라고 생각했거든요
그런데 정상적으로 작동을 하더라구요

이렇게 사용하는것이 정말로 문법에 어긋나는것이 아닌가요?
친구 말로는 이렇게 콤마로 연결되어있으면 or(||)와 같이 작동한다고 하더라구요

C 언어 문법책이 많은건 아니지만 이걸 알고나서 책을 다 뒤져봐도
이런 콤마의 사용과 기능이 나와있지 않아서 좀 의구심이들어서...T.T
조언좀 부탁드립니다

gamdora의 이미지

문법에 어긋나지는 않지만 친구분의 말은 틀렸습니다.

|| 연산자와 전혀 다르게 평가합니다.

expr1, expr2의 값은 expr2의 값과 같습니다.

expr1의 값은 무시되지요.

전웅의 이미지

> for(i=1,j=1;j<10,i<10;j++)
> {
> ...
> }
>
> 친구가 작성한 이 코드를 보고 문법에 틀린게 아닌가 생각이 들었는데
>

문법은 틀리지 않았지만, 의도한 "의미"상 틀렸습니다.

> 왜냐하면 콤마 연산자는 두 문장을 이어주는 역활을 하는것인데

두 문장을 연결해 주는 역할이 아니라, 두 수식을 연결해 하나의 수식으로
만들어 주는 역할을 합니다.

> for문에 들어갈 조건식에 사용되면 의미상으로 전체 수식이 참인지, 거짓인지 구별하지 못할꺼라고 생각했거든요
> 그런데 정상적으로 작동을 하더라구요
>

그럴리가요.

> 이렇게 사용하는것이 정말로 문법에 어긋나는것이 아닌가요?
> 친구 말로는 이렇게 콤마로 연결되어있으면 or(||)와 같이 작동한다고 하더라구요
>

친구분이 틀렸습니다.

a, b 와 같은 수식이 있을 때 행동은 a 를 평가하고 그 결과를 "무시"하고
b 를 평가하는 식으로 동작합니다. 쉼표 연산자로 여러 수식이 연결되어
있을 경우 수식의 결과는 마지막 피연산자로 주어진 수식의 결과가 됩니다.
따라서 마지막 수식이 아닌 수식들은 값을 변경하는 등의 side effect 를
가지지 않는 이상 무의미합니다.

보여주신 j<10, i<10 에서도 j 가 10 미만인지 판단한 결과는 "무시"되어
버리고 i<10 의 결과만이 전체 결과를 좌지우지합니다. 따라서 for 문의
제어 수식으로 j<10, i<10 을 써 준 것은 i<10 만 써준 것과 다를 바
없습니다. 친구분 말씀대로 logical OR 의 역할을 한다면 아래 코드는
j == 10 시점에 종료 되어야 하지만 실상은 그렇지 않다는 것을 확인하실
수 있습니다.

~$ cat > t.c
#include &lt;stdio.h&gt;;
 
int main(void)
{
    int i, j;
 
    puts("will this stop?\n");
    for (i=0, j=0; j&lt;10, i&lt;10; j++)
        printf("%d\n");
 
    return 0;
}
 
~$ gcc t.c
~$ ./a.out
will this stop?
 
0
1
2
3
4
5
6
7
8
9
10
11
12
...

--
Jun, Woong (woong at icu.ac.kr)
Web: http://www.woong.org (서버 공사중)

--
Jun, Woong (woong at gmail.com)
http://www.woong.org

bootmeta의 이미지

comma 연산자는 원래 한 표현식(expression)이 있어야하는 곳에서 2개 이상 표현식을 쓰려고 할때 사용합니다.
comma 연산자로 묶인 표현식들은 좌측 표현식부터 차례로 평가(evaluation) 후 마지막 가장 우측 표현식의 결과값이 return 됩니다.전체 표현식의 결과값이 됩니다.( 전웅님 충고 감사합니다.)

연산자 우선 순위에 따라 결과 값이 달라지므로 주의깊게 사용해야 합니다.

 x = (y = 4, 5);
결과    x == 5, y == 4
 x = y = 4, 5;
결과    x == 4, y == 4

전웅의 이미지

> comma 연산자는 원래 한 표현식(expression)이 있어야하는 곳에서 2개 이상 표현식을 쓰려고 할때 사용합니다.
> comman 연산자로 묶인 표현식들은 좌측 표현식부터 차례로 평가(evaluation) 후 마지막 가장 우측 표현식의 결과값이 return 됩니다.

기술적으로 틀린 내용은 없습니다만, "용어" 선택상 "return 되다" 는 보통
함수의 결과값을 (암시적이든 아니든) return 이라는 문장을 통해 반환할
때 사용하는 표현이므로, "... 가장 우측 표현식의 결과값이 전체 수식의
결과가 됩니다" 정도의 표현이 좋지 않을까 생각합니다.

흔히, sizeof 연산자가 사용되는 형태가 함수 호출과 비슷해 몇몇
책에서조차 "피연산자의 크기가 return 된다"는 식의 표현을 사용하고
있는데, 이 역시 아래 예에서 볼 수 있듯이 sizeof 가 수식 내에서
사용되는 연산자임을 분명히 하기 위해 "return 된다"는 표현을 피해야
하는 경우에 해당된다고 봅니다.

int i;
 
printf("%lu\n", (unsigned long) sizeof i);

--
Jun, Woong (woong at icu.ac.kr)
Web: http://www.woong.org (서버 공사중)

--
Jun, Woong (woong at gmail.com)
http://www.woong.org

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.