&& ||연산자와 & | 연산자에 대해 질문 드립니다~

alsrud의 이미지

연산자에 대해 문득 궁금한 게 생겨 질문 드립니다.
&연산자의 경우 &&와 달리 shor-circuiting을 제공하지 않아 앞의 조건과 상관없이 주어진 피연산자를 모두 연산하여 결과값을 도출한다고 알고 있습니다.

그런데 만약 if(2 && 4) 라는 조건식의 경우는
논리연산자로 생각하면 if(참 & 참) 이 되어 참이라는 연산 결과가 나오고
비트연산자로 생각하면
010
100
->000 이되어 if(거짓) 이라는 연산 결과가 나오게 되지 않나요?

&&나 ||연산자와 달리 &와 |연산자는 논리 연산자와 비트연산자의 경우를 따로 나누어서 취급을 해주어야 하는 것인가요? 이럴 경우 컴퓨터가 논리연산자인지 비트연산자인지 어떻게 구분을 하는지도 궁금합니다~

HDNua의 이미지

C 프로그래밍 언어를 사용한다고 가정하고 이야기를 진행하겠습니다.

&, |를 논리/비트 연산자로 나누어 취급을 한다는 게 무슨 말인지 잘 이해가 안 갑니다만
논리 and면 &&를, 비트 and면 &를 쓰면 됩니다. or의 경우도 마찬가지입니다.
왜냐하면 애초에 이 두 연산은 같은 and/or 기계어로 번역되지 않기 때문입니다.

C로 프로그램을 작성하면 기계어로 번역되니 이와 일대일 대응하는 어셈블리로 설명하겠습니다.
비트 논리곱, 비트 논리합은 MASM 기준에서 and, or라는 기계어로 번역됩니다.
(다른 언어도 비슷합니다. 아래 코드는 의사 코드이므로 실제와 약간 다릅니다)

...
// c = a & b;
and a, b    // a = a & b
mov c, a    // c = a
...
// c = a | b;
or a, b     // a = a | b
mov c, a    // c = a

하지만 논리 and/or의 결과는 보통 cmp/test 등의 비교 명령어와 상태를 저장하는 내부 플래그 변수(flag) 같은 것으로 번역됩니다.

...
// c = a && b;
cmp a, 0     // flag = (a == 0 ? 1 : 0)
jz lblFalse  // if (flag == 1) goto lblFalse
cmp b, 0     // flag = (b == 0 ? 1 : 0)
jz lblFalse  // if (flag == 1) goto lblFalse
mov c, 1     // c = 1
jmp end      // goto end
lblFalse:    // C의 레이블 구문과 같음
mov c, 0     // c = 0
end:         // 연산 종료
...
// 논리 or도 같음

따라서 컴퓨터는 논리 연산자, 비트 연산자를 서로 구분할 필요가 없습니다. 애초에 같은 것을 쓰지 않기 때문에요.

저는 이렇게 생각했습니다.

세벌의 이미지

&&는 논리연산자 &는 비트연산자입니다. &를 컴퓨터가 그때 그때 논리연산자 또는 비트연산자로 인식하는 게 아니고요.

raymundo의 이미지

java 에서 말씀하시는 것 같은데요. 자바에서는 &가 논리연산자로도 쓰이지요.

두 피연산자가 정수형이면 비트와이즈 연산자로, 두 피연산자가 boolean 형이면 논리연산자로 동작합니다. 이게 "어떻게 구분하느냐"의 답이고...

그런데 만일 자바 얘기라면 if ( 2 & 4 ) 직접 해보시면 컴파일이 아예 안 되는 걸 보셨을 텐데요. 자바에서는 boolean 이 와야 하는 곳은 명시적으로 boolean 이 와야지 정수값을 "0이면 거짓, 그 외에는 참"으로 사용할 수 없습니다. 그러니 애초에 그런 모호함에 대한 고민을 하실 필요도 없었지요.

자바도 아니고 딴 언어 말씀이시라면, 무슨 언어 얘긴지 적어주시는 게 좋겠네요.

좋은 하루 되세요!

alsrud의 이미지


언어 종류를 안적었군요...
C언어 입니다.
HeadFirstC 라는 책을 보다가 p62에서 위와 같은 내용을 보았습니다~

Q: ||나 && 대신 |나 &를 안되나요?
A: 원하면 &와 |를 사용할 수 있습니다. &와 |연산자는 언제나 양쪽 조건을 모두 검사하지만, &&와 ||는 검사하지 않을 수도 있습니다.

Q: 그러면 &와 | 연산자는 왜 있나요?
A: 이 연산자는 논리 조건 검사하는 것 외에도 다른 일도 합니다. 값을 비트 단위로 연산합니다.

Q: 그게 무슨말인가요?
A: 예를들어 6 & 4는 4가 됩니다. 110과 100을 비트 단위로 논리곱을 구하면 100이 되기 때문입니다.

저도 &&와 ||는 논리연산자, &와|는 비트연산자로 알고 있었는데
책에서 위와같은 문답 정리를 보고 의문이 들어 올려보았습니다~

kukyakya의 이미지

이건 책에서 상관없는 주제를 애매하게 설명해놓은게 큰 것 같습니다.

&나 |와 같은 비트연산자는 단순히 비트 연산을 하는 것이고, if()나 while()에 들어가게 되면 비트연산 결과를 implicit하게 boolean으로 변환하는 것입니다.

&와 |가 논리 조건을 검사한다는 말은 왜 써놨는지 모르겠네요.

raymundo의 이미지

글쎄요, 저 책에서 무슨 의미로 적었는지 앞뒤를 더 보면 나올지 모르겠지만,
암튼 & 를 논리 연산자로 쓰려고 하면 본문에 쓴 대로 2&4가 0이 되어 거짓으로 간주되니
의도하지 않은 결과를 낼 가능성이 높습니다.

딱히 상황에 따라 2&4를 "참"으로 만들어주는 일은 없습니다.

좋은 하루 되세요!

klara의 이미지

책에도 '&와 | 는 논리 연산자'라는 표현은 없습니다.
다만 인자에 따라서는 논리 연산에 쓸 수도 있다는 거지요.
이때에는 값이 0 또는 1로 제한되어야 겠죠. (또는 C의 _Bool타입이나 C++의 bool타입)

&는 특정 우변값에 대해서 2의 거듭제곱으로 나눈 나머지를 구하는 나머지 연산에 쓰일 수도 있습니다.
그렇다고 &를 나머지 연산자라고 부르진 않습니다.

참고로 foo1()과 foo2()의 리턴값이 _Bool또는 bool일 때,

if (foo1() || foo2()) { ... }

라는 문장에서 foo1()의 결과에 따라서 foo2()는 실행 될수도 있고 안될 수도 있지만
if (foo1() | foo2()) { ... }

이건 foo1()과 foo2()가 모두 실행될 것을 보장합니다.
따라서 foo1()과 foo2()가 모두 실행되야 하는 경우에는 후자가 더 편하겠죠.

klara의 이미지

> &와 |연산자는 논리 연산자와 비트연산자의 경우를 따로 나누어서 취급을 해주어야 하는 것인가요?

여러분들이 적어주셨지만 논리 연산자는 논리 연산자고 비트 연산자는 비트 연산자입니다.
&와 |는 비트 연산자지 논리 연산자가 입니다. 원래 구분되어있는거지 &가 논리 연산자인 경우는 없습니다.
비트 연산자가 논리 연산자와 같은 값을 돌려줄 수 있는 것은 오직 1과 0이 인자인 경우 뿐입니다.
이건 마치 1 + 0도 1이고 1 - 0도 1이라고 이라고 해서 - 연산자가 + 연산자를 대신하는게 아닌 것과 같습니다.

alsrud의 이미지

많은 답변의견들 감사합니다 : )
덕분에 의문점이 해결되었습니다~

댓글 달기

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