2010-04-10 2 views
5

저는 학교에있을 때 컴퓨터 과학 교사 중 한 명이 "불평등"과 같은 부정적 요소가 아니라 상태의 '진실성'또는 '평등'을 확인하는 것이 더 낫다고 가르쳤습니다.조건문에서 '진실성'또는 '평등성'을 확인하는 연습은 실제로 의미가 있습니까?

자세히 설명해주십시오. - 표현식이 참인지 거짓인지를 확인하여 조건 코드를 작성할 수 있다면 '진실성'을 확인해야합니다.

예 : 숫자가 홀수인지를 알아 내기 -이 두 가지 방법으로 수행 할 수 있습니다

if (num % 2 != 0) 
{ 
    // Number is odd 
} 

또는

if (num % 2 == 1) 
{ 
    // Number is odd 
} 

(더 나은 예를 들어 표시된 대답을 참조하십시오.)

코딩을 시작할 때 나는 num % 2 == 0이 숫자가 고른 것을 의미하는 것으로 알고 있으므로를 넣었습니다. 이상한지 확인하려면을 참조하십시오. 그러나 그는 '조건을 확인하지 마라. 가능할 때마다 '진실성'또는 '평등'을 점검하는 관행을 가져야합니다. 그리고 그는 두 번째 코드를 사용하도록 권장했습니다.

나는 어느 쪽이든 반대하지 않지만 단지 알고 싶었습니다. 어떤 차이가 있습니까? '기술적으로 출력물은 동일합니다'라고 회신하지 마십시오. 우리 모두 알고 있습니다. 그것은 일반적인 프로그래밍 연습인가 아니면 다른 사람에게 설교하는 자신의 프로그래밍 연습입니까?

참고 : 아무 이유없이 C#/C++ 스타일 구문을 사용했습니다. 내 질문은 VB에서 IsNot, <> 연산자를 사용할 때도 똑같이 적용됩니다. 따라서 '!' 연산자는 단지 하나의 문제입니다. 문제는 아닙니다.

+0

위키에 관한 질문 일 수 있습니까? – slugster

답변

6

문제는 나중에 프로젝트에서 더 많은 조건이 추가 될 때 발생합니다. 현재 작업하고있는 프로젝트 중 하나가 시간이 지남에 따라 꾸준히 조건을 수집했습니다. 그런 다음 해당 조건 중 일부가 struts 태그로 이동 한 다음 JSTL에 ...) - 하나의 부정적인 것은 읽기가 어렵지 않지만, 5+는 악몽이다. 특히 누군가가 모든 것을 재구성하고 무효화하기로 결정한 경우. 다시 한 달

if (authorityLvl!=Admin){ 
doA(); 
}else{ 
doB(); 
} 

확인하고이 될 것 : 어쩌면 새로운 프로젝트에, 당신은 쓸 것이다

아직도
if (!(authorityLvl!=Admin && authorityLvl!=Manager)){ 
doB(); 
}else{ 
doA(); 
} 

아주 간단하지만, 다른 초 걸립니다.
이제 썩어서 5 ~ 10 년을 더주십시오.
(x % 2! = 0)은 확실히 문제가되지 않지만, 위의 시나리오를 피하는 가장 좋은 방법은 학생들이 부정적인 조건을 일반적으로 사용하지 말 것을 가르치는 것입니다. 판단을 내리기 전에 - 정비 문제가 될 수 있다고 말하는 것만으로는 충분한 동기가 아닐 것입니다. 부록으로

는 코드를 작성하는 더 좋은 방법은 다음과 같습니다

userHasAuthority = (authorityLvl==Admin); 
if (userHasAuthority){ 
doB(); 
else{ 
doA(); 
} 

지금 미래 코더는 추가 할 가능성이 높다 "|| authorityLvl == 관리자", userHasAuthority는로 이동하기 쉬운입니다 메서드를 사용하고 조건부가 재구성 된 경우에도 단 하나의 부정적인 값만 갖습니다. 또한 De Morgan의 법칙을 적용하는 동안 실수로 실수로 보안 침입을 막을 사람은 아무도 없습니다.Bevan에 회신

+0

은 맑은 하늘에서 번개처럼 - 매우 명확하게 설명합니다 - 특히 두 번째 코드입니다. 내가 읽은 가장 좋은 이유. (내가 충분한 rep : D를 얻을 때 +1) – Senthil

0

나는 내 수업에서도 똑같은 것을 들었던 것을 기억합니다. 항상 긍정적 인 조건을 확인하기보다는 항상 더 직관적 인 비교를 사용하는 것이 더 중요하다고 생각합니다.

0

정말 대단히 중요한 문제입니다. 그러나이 의미에서 검사하는 것이 부정적인 이유는 이진 비교에서만 작동한다는 것입니다. 예를 들어 3 진수 시스템의 일부 특성을 검사하는 경우 제한적입니다.

1

필자는 핑킹 (!) 문자가 눈에 띄지 않을 때 읽는 것과 관련이 있다고 사람들에게 말했습니다.

정기적으로 읽기 속도가 너무 느리기 때문에 습관적으로 "스킴 읽기"코드를 사용하면 코드를 잘못 이해할 수 있으므로 !을 쉽게 놓칠 수 있습니다.

누군가가 실제로 모든 코드를 실제로 읽으면 아무런 문제가 없습니다.

비슷한 목적으로 ! 대신에 == false을 쓰는 매우 훌륭한 두 개발자가 있습니다.

내 마음 속의 핵심 요소는 코드 (코드 또는 코드)를 유지하는 사람에게 효과가있는 것과 관련이 있습니다. 코드가 다른 누구에게도 보이지 않거나 유지 관리되지 않으면 개인 변덕에 따르십시오. 코드를 다른 사람이 관리해야하는 경우 도로 중앙에 더 잘 조종하는 것이 좋습니다. 사소한 (사소한!) 절충안을 사용하면 나중에 다른 사람이 일주일에 한 번 디버깅을 할 수 있습니다.

업데이트 : 더 고려, 나는 아직도 더 많은 유지 보수를 줄 것이다 별도의 술어 기능과 조건을 고려해 제안 :

if (isOdd(num)) 
{ 
    // Number is odd 
} 
+0

안녕하세요! 나는 다른 누군가의 코드를 읽을 때 꽤 많은'!'을 보지 못했다. 특히 코드가'if (! (some-condition))'와 같은 경우. 그것은 나에게 일어나지 않았다! : D – Senthil

+0

업데이트 정보 - 정확하게 술어가 무슨 뜻인지는 모르겠지만 isOdd() 함수가 조건을 포함 할 것으로 추측하고 있습니다. 그렇습니까? – Senthil

+0

+1 술어 기능을 위해 ... 나는 그것을 끊임없이 수행하며 가독성을 크게 향상시킨다. – helpermethod

2

내가 이전 교수에 동의합니다 - 해당 없음 상태 검사 특정 NOT 조건을 확인하는 한 괜찮습니다. 그것은 실제로 그의 기준에 부합합니다 : 여러분은 가치가 무언가가 아니라는 것이 참이라는 것을 점검 할 것입니다.

나는 그가 의미하는 것을 grok합니다. 대부분 실제 조건은 NOT 조건보다 크기가 훨씬 작기 때문에 더 작은 값 집합을 검사 할 때 쉽게 테스트 할 수 있습니다.

+0

"진정한"조항 만 실행되기 때문에 항상 진실 인 무언가를 항상 확인하고있을 것입니다. D 그건 내가 의미했던 것이 아니고 그의 기준이 아니기 때문입니다. 와우, 혼란스러워지고 있습니다! – Senthil

1

당신은 여전히 ​​이런 것들에 대해서 조심해야 : NUM % 2가 동일 할 수있는 언어 나 구현 납입 -1에 따라 다음 부정적이고 홀수

if (num % 2 == 1) 
{ 
    // Number is odd 
} 

합니다. 그 메모에서 적어도 수표의 구문을 단순화하면 위조 여부를 확인하는 데 아무런 문제가 없습니다. 또한,! =를 사용하면 모든 것보다 더 분명합니다! 괄호로 섞일 수있다.

if (num % 2 == 1 || num % 2 == -1) 
{ 
    // Number is odd 
} 

분명히 그냥 예입니다

은 당신이해야 할 것 진위를 확인하십시오. 요점은 부정을 사용하면 수표를 더 적게 사용하거나 수표의 구문을 분명하게 만드는 경우 분명히 갈 방법입니다 (위의 예와 같이). 진실 여부를 확인하기 위해 자신을 잠그는 것은 갑자기 조건문을 더 읽기 쉽게 만들어주지는 않습니다.

+0

@ 에반 : 홀수 번호는 내 마음에 온 첫 번째 예일뿐입니다. 모든 가능한 경우를 생각하지 않았습니다. 그러나 나는 독자가 내가이 질문에서 무엇을 말하려고하는지 이해하기를 바랍니다. – Senthil

+0

나는 이해한다. 나는 진실을 확인하는 동안 2 개의 수표가 관련 될 수있는 반면, 거짓의 경우를 확인하는 것과 같은 경우에는 1 개의 수표를 포함한다고 말하고 있습니다. 거짓 사례를 확인하는 것이 더 바람직합니다. –

0

(이 댓글을에 적합하지 않은) :

네 말이 맞아. !foo이 항상 foo == false과 같지는 않습니다. 이 예를 자바 스크립트로 보도록하겠습니다.

var foo = true, 
    bar = false, 
    baz = null; 

foo == false; // false 
!foo;   // false 
bar == false; // true 
!bar;   // true 
baz == false; // false (!) 
!baz;   // true 
0

이 특정 사례에서는 교사와 동의하지 않습니다. 어쩌면 그는 포지티브가 괜찮을 때, 나무를 보지 못했다는 이유로 네거티브를 피하기 위해 일반적으로 좋은 교훈을 얻었을 것입니다.

여기에 문제가 있습니다. 오늘, 당신이 그에게 듣고로 코드를 설정 :

// Print black stripe on odd numbers 
int zebra(int num) { 
    if (num % 2 == 1) { 
    // Number is odd 
    printf("*****\n"); 
    } 
} 

다음 달, 당신은 다시 보면 (아마도 그가 너무 당신이 싫어하는을 가르치고) 당신이 마법 상수를 좋아하지 않아 결정한다. 따라서 코드를 변경하십시오.

#define ZEBRA_PITCH 2 
[snip pages and pages, these might even be in separate files - .h and .c] 
// Print black stripe on non-multiples of ZEBRA_PITCH 
int zebra(int num) { 
    if (num % ZEBRA_PITCH == 1) { 
    // Number is not a multiple of ZEBRA_PITCH 
    printf("*****\n"); 
    } 
} 

세계는 괜찮아 보입니다. 출력은 변경되지 않았으며 회귀 테스트가 통과됩니다.

하지만 아직 끝나지 않았습니다. 검은 줄무늬가 흰색 줄무늬보다 두꺼운 돌연변이 얼룩말을 원합니다. 몇 달 전부터 코드를 원래 코드로 작성 했으므로 흰색 스트립이 비 - 짝수가 아닌 곳에 코드가 검은 색 줄무늬를 인쇄합니다. 그래서 당신이해야 할 일은 2로 나누는 대신 3을 나누는 것입니다. 권리? 음 :

#define DEFAULT_ZEBRA_PITCH 2 
[snip pages and pages, these might even be in separate files - .h and .c] 
// Print black stripe on non-multiples of pitch 
int zebra(int num, int pitch) { 
    if (num % pitch == 1) { 
    // Number is odd 
    printf("*****\n"); 
    } 
} 

이봐,이게 뭐야? 이제 대부분 검은 색이 될 것으로 예상되는 곳에는 하얀색 얼룩말이 있습니다.

여기에서 문제는 숫자를 생각하는 것입니다. 숫자가 "이상하다"는 것은 짝수가 아니기 때문에 또는 2로 나눌 때 나머지가 1이기 때문에? 때로는 문제 도메인이 하나의 환경 설정을 제안 할 수도 있습니다. 그런 경우에는 "부정 테스트를하지 마십시오"와 같은 단순한 규칙을 고수하기보다는이 관용구를 표현하는 코드를 작성하는 것이 좋습니다.