C ++ 강사의 강의 노트를 읽고 다음과 같이 썼습니다.
- 들여 쓰기 사용 // 확인
- 연산자 우선 순위에 의존하지 않음-항상 괄호 사용 // 확인
- 항상 {} 블록을 사용 – 심지어 한 줄 //을 위해 하지 OK , 왜 ???
- 비교의 왼쪽에있는 Const 객체 // 확인
- > = 0 // 멋진 트릭 인 변수에는 부호없는 것을 사용하십시오.
- 삭제 후 포인터를 NULL로 설정-이중 삭제 보호 // 나쁘지 않음
세 번째 기술은 나에게 분명하지 않습니다. 한 줄을 { ... }
?
예를 들어,이 이상한 코드를 보자 :
int j = 0;
for (int i = 0 ; i < 100 ; ++i)
{
if (i % 2 == 0)
{
j++;
}
}
그것을 다음으로 대체하십시오 :
int j = 0;
for (int i = 0 ; i < 100 ; ++i)
if (i % 2 == 0)
j++;
첫 번째 버전을 사용하면 어떤 이점이 있습니까?
답변
i
증분 할 때도 수정 해 봅시다 j
:
int j = 0;
for (int i = 0 ; i < 100 ; ++i)
if (i % 2 == 0)
j++;
i++;
아뇨! 파이썬에서 나오면 괜찮아 보이지만 실제로는 다음과 같습니다.
int j = 0;
for (int i = 0 ; i < 100 ; ++i)
if (i % 2 == 0)
j++;
i++;
물론 이것은 어리석은 실수이지만 숙련 된 프로그래머조차도 할 수있는 실수입니다.
또 다른 좋은 이유 는 ta.speot.is ‘s answer 에서 지적합니다 .
내가 생각할 수 있는 세 번째 는 nested입니다 if
.
if (cond1)
if (cond2)
doSomething();
이제, 당신이 지금 원하는 가정 doSomethingElse()
할 때 cond1
(새로운 기능)이 충족되지 않습니다. 그래서:
if (cond1)
if (cond2)
doSomething();
else
doSomethingElse();
이는 else
inner와 연관 되기 때문에 분명히 잘못되었습니다 if
.
편집 : 이것은 약간의 관심을 받고 있기 때문에 내 견해를 분명히 할 것입니다. 내가 대답 한 질문은 다음과 같습니다.
첫 번째 버전을 사용하면 어떤 이점이 있습니까?
내가 설명 한 것. 몇 가지 이점이 있습니다. 그러나 “항상”규칙이 항상 적용되는 것은 아닙니다. 전 전적으로지지하지 않습니다
항상 {} 블록을 사용하십시오-한 줄이라도 // 안 좋아, 왜 ???
나는 항상{}
블록을 사용 한다고 말하는 것이 아닙니다 . 충분히 간단한 상태와 행동이라면하지 마십시오. 누군가 나중에 와서 코드를 변경하여 기능을 추가 할 수 있다고 생각되면 그렇게하십시오.
답변
이 코멘트를 사용하지 않는 경우와 실수로 변경 제어 흐름에 매우 쉽게 {
하고 }
. 예를 들면 다음과 같습니다.
if (condition)
do_something();
else
do_something_else();
must_always_do_this();
당신이 주석 경우 do_something_else()
한 줄의 코멘트와 함께, 당신은이 될 겁니다 :
if (condition)
do_something();
else
//do_something_else();
must_always_do_this();
컴파일되지만 must_always_do_this()
항상 호출되는 것은 아닙니다.
우리는 코드베이스에이 문제가 있었는데, 누군가 릴리스 전에 일부 기능을 매우 빠르게 비활성화하기 시작했습니다. 다행히도 우리는 코드 검토에서 그것을 잡았습니다.
답변
강사의 역량에 대해서는 의문의 여지가 있습니다. 그의 요점을 고려하면 :
- 확인
- 누구든지 정말로 쓰거나 읽을
(b*b) - ((4*a)*c)
래요? 일부 우선 순위는 분명하고 (또는 있어야 함) 여분의 괄호는 혼란에 추가됩니다. (반면, 필요하지 않다는 것을 알더라도 덜 명확한 경우에 괄호를 사용해야합니다.) - 일종의. 조건부 및 루프의 형식을 지정하는 데 널리 사용되는 두 가지 규칙이 있습니다.
if (cond) { 암호; }
과:
if (cond) { 암호; }
첫 번째로 나는 그에게 동의 할 것이다. 개구부
{
는 그렇게 보이지 않으므로 항상 존재한다고 가정하는 것이 가장 좋습니다. 그러나 두 번째로, 나는 (그리고 내가 함께 일한 대부분의 사람들은) 단일 진술에 중괄호를 생략하는 데 아무런 문제가 없습니다. (물론 들여 쓰기는 체계적이며이 스타일을 일관되게 사용하도록 제공했습니다. (그리고 매우 좋은 프로그래머는 읽기 쉬운 코드를 작성하여 첫 번째 형식을 지정할 때에도 중괄호를 생략했습니다.) - 아니요 .
if ( NULL == ptr )
가독성을 방해하기에는 못생긴 것들이 있습니다. 비교를 직관적으로 작성하십시오. (많은 경우 오른쪽에 일정한 결과가 나타납니다.) 그의 4 가지는 나쁜 조언입니다. 코드를 부 자연스럽게 만드는 것은 코드를 읽기 어렵게 만듭니다. - 아니요 .
int
특별한 경우를 제외하고 는 아무것도 없습니다 . 숙련 된 C 및 C ++ 프로그래머에게는unsigned
신호 비트 연산자를 사용합니다. C ++에는 실제 기본 유형 (또는 다른 효과적인 하위 범위 유형)이 없습니다.unsigned
승격 규칙으로 인해 숫자 값에는 작동하지 않습니다. 일련 번호와 같이 산술 연산이 의미가없는 숫자 값은 아마도 일 수 있습니다unsigned
. 그러나 잘못된 메시지를 보내기 때문에 반대 의견을 제시합니다. 비트 연산도 의미가 없습니다. 기본 규칙은 정수 유형이int
_unless_이고 다른 유형을 사용해야 하는 중요한 이유가 있다는 것입니다. - 아니요 . 이를 체계적으로 수행하는 것은 오해의 소지가 있으며 실제로 어떤 것도 보호하지 못합니다. 엄격한 OO 코드에서,
delete this;
(당신은 설정할 수 없습니다 종종 가장 흔한 경우가this
로NULL
), 그렇지 않으면, 대부분은delete
나중에 어쨌든 포인터를 액세스 할 수 있도록 소멸자에 있습니다. 그리고 그것을 설정하면NULL
다른 포인터가 떠 다니는 것에 대해 아무것도하지 않습니다. 체계적으로 포인터를 설정하면NULL
잘못된 보안 감각이 생겨 실제로 아무것도 사지 않습니다.
일반적인 참조에서 코드를 확인하십시오. Stroustrup은 예를 들어 첫 번째 규칙을 제외한 모든 규칙을 위반합니다.
다른 강사를 찾으십시오. 실제로 자신이 말하는 것을 아는 사람.
답변
다른 모든 답변은 강사의 규칙 3을 방어합니다.
내가 당신에게 동의한다고 말합시다. 규칙은 중복 적이고 나는 조언하지 않을 것입니다. 항상 중괄호를 추가하면 이론적으로 오류를 방지 하는 것이 사실입니다 . 다른 한편으로, 나는 실제 생활 에서이 문제를 겪어 본 적이 없습니다 . 다른 답변이 암시하는 것과는 달리, 일단 필요한 경우 중괄호를 추가하는 것을 잊지 않았습니다. 적절한 들여 쓰기를 사용하는 경우, 하나 이상의 명령문이 들여 쓰기되면 중괄호를 추가해야한다는 것이 즉시 명백해집니다.
“Component 10”의 답변은 실제로 이것이 실제로 오류를 일으킬 수있는 유일하게 가능한 사례를 강조합니다. 그러나 정규 표현식을 통해 코드를 교체하면 항상 막대한주의가 필요합니다.
이제 메달의 다른 쪽을 살펴 보자. 항상 중괄호를 사용 하는 것이 불리한가? 다른 대답은 단순히이 점을 무시합니다. 그러나이 있다 단점 : 그것은 수직 화면 공간을 많이 차지, 그리고 당신이 필요 이상으로 스크롤해야 할 의미하기 때문에이 차례로 코드를 읽을 수 있습니다.
처음에 많은 가드 절이있는 함수를 고려하십시오 (예, 다음은 나쁜 C ++ 코드이지만 다른 언어에서는 매우 일반적인 상황입니다).
void some_method(obj* a, obj* b)
{
if (a == nullptr)
{
throw null_ptr_error("a");
}
if (b == nullptr)
{
throw null_ptr_error("b");
}
if (a == b)
{
throw logic_error("Cannot do method on identical objects");
}
if (not a->precondition_met())
{
throw logic_error("Precondition for a not met");
}
a->do_something_with(b);
}
이것은 끔찍한 코드이며 다음이 훨씬 더 읽기 쉽다고 강력하게 주장합니다.
void some_method(obj* a, obj* b)
{
if (a == nullptr)
throw null_ptr_error("a");
if (b == nullptr)
throw null_ptr_error("b");
if (a == b)
throw logic_error("Cannot do method on identical objects");
if (not a->precondition_met())
throw logic_error("Precondition for a not met");
a->do_something_with(b);
}
마찬가지로 짧은 중첩 루프는 중괄호를 생략하면 이점이 있습니다.
matrix operator +(matrix const& a, matrix const& b) {
matrix c(a.w(), a.h());
for (auto i = 0; i < a.w(); ++i)
for (auto j = 0; j < a.h(); ++j)
c(i, j) = a(i, j) + b(i, j);
return c;
}
다음과 비교하십시오 :
matrix operator +(matrix const& a, matrix const& b) {
matrix c(a.w(), a.h());
for (auto i = 0; i < a.w(); ++i)
{
for (auto j = 0; j < a.h(); ++j)
{
c(i, j) = a(i, j) + b(i, j);
}
}
return c;
}
첫 번째 코드는 간결합니다. 두 번째 코드는 부풀어 오른다.
그리고 예, 이것은 이전 줄에 오프닝 버팀대를 놓음으로써 어느 정도 완화 될 수 있습니다 . 하지만 그 것이다 아직 어떤 중괄호가없는 코드보다 덜 읽을 수.
한마디로 : 화면 공간을 차지하는 불필요한 코드를 작성하지 마십시오.
답변
내가 작업중 인 코드베이스는 중괄호로 병적 혐오감을 가진 사람들에 의해 코드로 흩어져 있으며, 나중에 오는 사람들에게는 실제로 유지 보수성과 차이를 만들 수 있습니다.
가장 자주 문제가되는 예는 다음과 같습니다.
if ( really incredibly stupidly massively long statement that exceeds the width of the editor) do_foo;
this_looks_like_a_then-statement_but_isn't;
그래서 내가 와서 then-statement를 추가하고 싶을 때, 조심하지 않으면 쉽게 끝낼 수 있습니다.
if ( really incredibly stupidly massively long statement that exceeds the width of the editor) do_foo;
{
this_looks_like_a_then-statement_but_isn't;
i_want_this_to_be_a_then-statement_but_it's_not;
}
그것이 왜 당신은 이제까지 것, 디버깅 몇 혼란 분 ~ 소요 일초 괄호를 추가하고 최소한 당신을 저장할 수있는 점을 감안 하지 감소 – 모호한 옵션으로 이동? 나에게 거짓 경제처럼 보인다.
답변
내 2c :
들여 쓰기 사용
명백하게
연산자 우선 순위에 의존하지 마십시오-항상 괄호를 사용하십시오
“항상” “항상”이라는 단어는 사용하지 않지만 일반적으로이 규칙이 유용하다는 것을 알 수 있습니다. 일부 언어 (Lisp, Smalltalk)에서는 문제가되지 않습니다.
한 줄이라도 항상 {} 블록을 사용하십시오
나는 그런 일을 한 번도하지 않고 한 가지 문제도 겪지 않았지만 그것이 어떻게 학생들에게 좋은지 알 수 있습니다. 그들이 전에 파이썬을 공부했다면.
비교의 왼쪽에있는 Const 객체
요다 조건? 아니요 괜찮아요. 가독성이 떨어집니다. 코드를 컴파일 할 때 최대 경고 수준을 사용하십시오.
> = 0 인 변수에는 부호없는 것을 사용하십시오.
확인. 재미 있지만 Stroustrup이 동의하지 않는다고 들었습니다.
삭제 후 포인터를 NULL로 설정-이중 삭제 방지
나쁜 충고! 삭제되었거나 존재하지 않는 객체를 가리키는 포인터가 없습니다.
답변
보다 직관적이고 쉽게 이해할 수 있습니다. 의도를 명확하게합니다.
그리고 그것은 새로운 사용자가 모르는 사이를 놓칠 수있는 경우 코드가 침입하지 않도록합니다 {
, }
새로운 코드 문을 추가하는 동안.