'for' 루프에서 1씩 증가할 때 != 대신 > (<)를 사용해야 하는 기술적 이유가 있습니까?
안 요.for
뭇매를 맞다
for (int i = 0; 5 != i; ++i)
{}
>
★★★★★★★★★★★★★★★★★」<
!=
의 일 경우for
니면면 관례 ?? ????
while (time != 6:30pm) {
Work();
}
6시 31분...젠장, 이제 집에 갈 다음 기회는 내일이야! :)
이는 더 강력한 제한이 위험을 완화하고 이해하기가 더 직관적이라는 것을 보여준다.
네, 이유가 있어요.다음과 같이 루프에 대해 (일반적인 오래된 인덱스 기반)를 쓰는 경우
for (int i = a; i < b; ++i){}
합니다.a
★★★★★★★★★★★★★★★★★」b
(즉, (반복, ""이 없는 경우a > b
「」을 는, 「무한」이, 「무한」을 사용했을 경우는 「무한」이 됩니다.i == b;
를 참조해 주세요.
한편, 반복자라면,
for (auto it = begin; it != end; ++it)
어떤 도 '반복자'를 때문입니다.operator!=
, 모든 ", ", "를 지정할 수 있는 operator<
.
루프에 대해서도 범위 베이스
for (auto e : v)
단지 화려한 설탕이 아니라 잘못된 코드를 쓸 수 있는 가능성을 현저히 줄여줍니다.
뭐 이런 거 할 수 있어요.
for(int i = 0; i<5; ++i){
...
if(...) i++;
...
}
, 「」는 「」입니다.i!=5
불평등을 하는 것이 더 하다.이것은 불평등을 확인하는 것이 더 안전하다.
가독성에 대해 편집합니다.불평등 형태는 훨씬 더 자주 사용된다.따라서, 이것은 특별히 이해할 것이 없기 때문에 읽는 것이 매우 빠르다(작업이 일반적이기 때문에 두뇌의 부하가 감소한다).그래서 독자들이 이러한 습관을 사용하는 것은 멋진 일이다.
Newson이 Ian Newson으로 수 .!=
를 들면예를 들어.
for (double x=0; x!=1; x+=0.1) {}
0 수 없기 루프됩니다. 카운터는 1.01을 놓칩니다.★★★★★★★★★★★★★★★★ <
료됩니니다다
(단, 0.9999를 얻을 수 있는지 여부는 기본적으로 정의되지 않은 동작이라는 점에 유의하십시오.마지막으로 받아들인 번호로 간주됩니다.이것은 가정보다 작은 종류의 경우입니다.또는 1.0000000000000001에서 이미 종료되었습니다.
기술적인 이유는 없습니다.그러나 리스크의 경감, 유지 보수성, 코드의 이해의 향상 등이 있습니다.
<
★★★★★★★★★★★★★★★★★」>
강한 이 있다!=
대부분의 경우 동일한 목적을 달성합니다(모든 실제적인 경우라고 말할 수 있습니다).
여기 중복된 질문이 있습니다; 그리고 한가지 흥미로운 답변이 있습니다.
그리고 마지막으로, 이것은 방어적 프로그래밍이라고 불리며, 이는 프로그램에 영향을 미치는 현재와 미래의 오류를 피하기 위해 항상 가장 강력한 경우를 취한다는 것을 의미합니다.
방어 프로그래밍이 필요하지 않은 유일한 경우는 사전 및 사후 조건에 의해 상태가 증명된 경우이다(그러나 이것이 모든 프로그래밍 중 가장 방어적이라는 것을 증명한다).
를 . OpenMP를 사용합니다.!=
★★★★★★ 。
루프 조건은 강제 루프 불변입니다.
루프의 본체를 보고 있지 않다고 합니다.
for (int i = 0; i != 5; ++i)
{
// ?
}
에 「」가 있는 을 알 수 있습니다.i
않다5
.
for (int i = 0; i < 5; ++i)
{
// ?
}
에 「」가 있는 을 알 수 있습니다.i
5
.
두 번째는 첫 번째보다 훨씬 더 많은 정보죠?프로그래머의 의도는 거의 동일하지만 버그를 찾고 있다면 코드를 읽을 수 있는 자신감을 갖는 것이 좋습니다.그리고 두 번째는 이 불변성을 강제합니다.즉, 첫 번째 케이스에서 당신을 괴롭히는 버그는 두 번째 케이스에서는 발생하지 않습니다(예를 들어 메모리 손상을 일으키지 않습니다).
더잘 알 수. 코드 읽기를 줄이고<
!=
최신 CPU에서는 같은 시간이 걸리고 차이가 없습니다.
의 '' ''가i
루프 본체에서는 조작되지 않고 항상 1씩 증가하며 시작은 다음보다 짧습니다.5
다름이 없다.하지만 조작 여부를 알기 위해서는 각각의 사실을 확인해야 합니다.
이 사실들 중 일부는 비교적 쉽지만, 여러분은 틀릴 수 있습니다.그러나 루프 전체를 체크하는 것은 귀찮은 일입니다.
에는 C++로, C++로, C+로, C+로, C++로 쓸 수.indexes
뭇매를 맞다
for( const int i : indexes(0, 5) )
{
// ?
}
의 두 중 와 같은 .for
컴파일러가 같은 코드로 최적화하는 것까지 루프가 발생합니다.하지만 여기, 당신은 알고 있습니다.i
할 수 본체에서는 조작할 수 없습니다.const
★★★★★★★★★★★★★★★★★★★★★★★★★★★
문맥을 이해하지 않고도 코드 행에서 더 많은 정보를 얻을 수 있을수록 무엇이 잘못되었는지 추적하기가 더 쉬워집니다. <
, 그 에 대한 가, 「정수 루프」의 경우는, 「정수 루프」의 경우, 「정수 루프」의 경우는, 그 행의 코드 상태에 대한 자세한 정보를 수 있습니다.!=
'는 '반복자'를 가장 할 때 입니다.!=
★★★★★★★★★★★★★★★★★★:
for(auto it = vector.begin(); it != vector.end(); ++it) {
// do stuff
}
인정: 실제로 저는 같은 글을 씁니다.range-for
:
for(auto & item : vector) {
// do stuff
}
은 '는 ' 비교'입니다.==
★★★★★★★★★★★★★★★★★」!=
.
이런 표현은
for ( int i = 0 ; i < 100 ; ++i )
{
...
}
의향을 보다 잘 표현하고 있다
for ( int i = 0 ; i != 100 ; ++i )
{
...
}
전자는 이 조건이 특정 범위의 배타적 상한에 대한 테스트이며, 후자는 출구 조건에 대한 이진 테스트임을 분명히 나타냅니다. 않은 수 .for
스테이트먼트 자체입니다.
수 .i
큰 값으로 되어 있습니다. 그냥 .!=
연산자는 끝없는 루프가 됩니다.
이러한 경우에 관계 비교를 사용하는 것은 다른 어떤 것보다도 인기 있는 습관입니다.반복자 범주 및 비교 가능성 등의 개념적 고려사항이 높은 우선순위로 고려되지 않았던 시대에 인기를 끌었다.
평등 비교는 비교되는 가치에 대한 요구 사항을 덜 부과하기 때문에 가능한 한 관계 비교 대신 평등 비교를 사용하는 것을 선호해야 한다고 말하고 싶다.EqualComparable이 되는 것은 LessThanComparable보다 덜 필요한 요건입니다.
에서 평등 또 다른 는 '동등 비교'를 입니다.unsigned
0
할 수 요.
for (unsigned i = 42; i != -1; --i)
...
위의 내용은 서명된 반복과 서명되지 않은 반복 모두에 동일하게 적용되지만 관계 버전은 서명되지 않은 유형으로 구분됩니다.
다른 많은 답변에서 알 수 있듯이, 엣지 케이스, 초기 상태, 의도하지 않은 루프 카운터 수정 등에 도움이 되는 != 대신 <를 사용하는 이유가 있습니다.
하지만 솔직히 인습의 중요성을 충분히 강조할 수는 없다고 생각합니다.이 예에서는 다른 프로그래머가 당신이 무엇을 하려는지 쉽게 알 수 있지만, 이중으로 해석할 수 있습니다.프로그래밍 중에 할 수 있는 일 중 하나는 가능한 한 모든 사람이 읽고 친숙하게 만드는 것입니다.따라서 필연적으로 누군가가 코드를 업데이트/변경해야 할 때 다른 코드 블록에서 무엇을 하고 있었는지 알아내는 데 많은 노력이 필요하지 않습니다. 하는 것을 !=
가 아니라 '이거'를<
만약 그게 큰 고리였다면, 난 네가 뭘 했는지 알아내려고 모든 걸 뒤져봤을 거야. 그건 시간 낭비야
형용사 "technical"은 언어 행동/쿼크 및 생성된 코드의 성능 등의 컴파일러 부작용을 의미합니다.
그 때문에, 대답은 「아니오(*)」입니다.(*)는, 「프로세서 메뉴얼을 참조해 주세요」입니다.엣지 케이스의 RISC 또는 FPGA 시스템을 사용하고 있는 경우는, 생성되는 명령과 그 코스트를 확인할 필요가 있습니다.의 현대식하고 있다면 .lt
,eq
,ne
★★★★★★★★★★★★★★★★★」gt
.
엣지 케이스를 사용하고 있는 경우는, 다음과 같습니다.!=
조작이 합니다(세 가지 조작이 필요합니다.cmp
,not
,beq
) 2 ( ) 2 2 ( )cmp
,blt xtr myo
이에도 RTM을 RTM을 사용하다
대부분의 경우, 포인터나 복잡한 루프를 사용하는 경우, 그 이유는 방어/강화입니다.고려하다
// highly contrived example
size_t count_chars(char c, const char* str, size_t len) {
size_t count = 0;
bool quoted = false;
const char* p = str;
while (p != str + len) {
if (*p == '"') {
quote = !quote;
++p;
}
if (*(p++) == c && !quoted)
++count;
}
return count;
}
예를 들어 반환값을 사용하여 증가분을 수행하고 사용자로부터 데이터를 받아들이는 경우가 있습니다.
#include <iostream>
int main() {
size_t len = 5, step;
for (size_t i = 0; i != len; ) {
std::cout << "i = " << i << ", step? " << std::flush;
std::cin >> step;
i += step; // here for emphasis, it could go in the for(;;)
}
}
이것을 시험해 보고 1, 2, 10, 999 값을 입력합니다.
이를 방지할 수 있습니다.
#include <iostream>
int main() {
size_t len = 5, step;
for (size_t i = 0; i != len; ) {
std::cout << "i = " << i << ", step? " << std::flush;
std::cin >> step;
if (step + i > len)
std::cout << "too much.\n";
else
i += step;
}
}
하지만 네가 원했던 건
#include <iostream>
int main() {
size_t len = 5, step;
for (size_t i = 0; i < len; ) {
std::cout << "i = " << i << ", step? " << std::flush;
std::cin >> step;
i += step;
}
}
, 도 있습니다.<
표준 컨테이너에서의 주문은 종종 에 의존하기 때문입니다.operator<
예를 들어 여러 STL 컨테이너의 해시는 다음과 같이 함으로써 동등성을 결정합니다.
if (lhs < rhs) // T.operator <
lessthan
else if (rhs < lhs) // T.operator < again
greaterthan
else
equal
한다면lhs
그리고.rhs
사용자 정의 클래스입니다.
if (lhs < rhs) // requires T.operator<
lessthan
else if (lhs > rhs) // requires T.operator>
greaterthan
else
equal
구현자는 두 가지 비교 기능을 제공해야 합니다.그렇게<
선호하는 운영자가 되었습니다.
이 구성을 사용하지 않는 이유 중 하나는 부동 소수점 숫자입니다. !=
숫자가 같아도 사실로 평가되는 경우는 거의 없기 때문에 플로트와 함께 사용하는 것은 매우 위험한 비교입니다. <
또는>
이 위험을 제거합니다.
모든 종류의 코드를 쓰는 방법에는 여러 가지가 있습니다(보통). 이 경우 두 가지 방법이 있습니다(<=와 >=를 세는 경우 세 가지).
이 경우, 사람들은 루프에서 예기치 않은 일(버그 등)이 발생해도 무한 루프(BAD)가 발생하지 않도록 하기 위해 >와 <를 선호합니다.예를 들어 다음 코드를 고려합니다.
for (int i = 1; i != 3; i++) {
//More Code
i = 5; //OOPS! MISTAKE!
//More Code
}
(i < 3)을 사용하면, 무한 루프로부터 안전합니다.이는 보다 큰 제한을 두기 때문입니다.
프로그램 전체를 셧다운하거나 버그 처리를 계속하거나 하는 것은 당신의 선택입니다.
도움이 됐으면 좋겠네요!
사용하는 가장 일반적인 이유<
인습입니다.더 많은 프로그래머는 이와 같은 루프를 "인덱스가 끝까지 도달할 때까지"가 아니라 "인덱스가 범위 내에 있는 동안"으로 생각합니다.할 수 있을 때 인습에 집착하는 것이 가치가 있다.
한편, 여기의 많은 답변은 다음과 같이 주장하고 있습니다.<
폼은 버그를 회피합니다.많은 경우 이것은 버그를 숨기는 데 도움이 된다고 생각합니다.루프 인덱스가 종료 값에 도달해야 하고, 그 값을 넘어 실제로 도달해야 하는 경우에는 예상치 못한 문제가 발생하여 오작동이 발생할 수 있습니다(또는 다른 버그의 부작용일 수도 있습니다).그<
이 버그의 검출이 지연될 가능성이 있습니다.그!=
는 스톨, 행업, 또는 충돌로 이어질 가능성이 높기 때문에 버그를 보다 빨리 발견하는 데 도움이 됩니다.버그가 빨리 발견될수록 수정 비용이 저렴해집니다.
이 규칙은 배열 및 벡터 인덱스에 고유합니다.거의 모든 유형의 데이터 구조를 통과할 때 반복기(또는 포인터)를 사용하여 끝 값을 직접 확인합니다.이 경우 반복기가 실제 종료 값에 도달하고 초과되지 않도록 해야 합니다.
예를 들어, 보통 C 문자열을 사용할 경우 다음과 같이 쓰는 것이 일반적입니다.
for (char *p = foo; *p != '\0'; ++p) {
// do something with *p
}
보다
int length = strlen(foo);
for (int i = 0; i < length; ++i) {
// do something with foo[i]
}
우선 문자열이 매우 길면 두 번째 형식이 느려집니다.strlen
스트링을 통과하는 또 하나의 패스입니다.
C++ std:: 스트링을 사용하면 길이가 즉시 사용 가능하더라도 범위 기반 루프, 표준 알고리즘 또는 반복기를 사용할 수 있습니다.반복기를 사용하는 경우 관례상!=
보다는<
예를 들어 다음과 같습니다.
for (auto it = foo.begin(); it != foo.end(); ++it) { ... }
마찬가지로 트리, 목록 또는 디큐를 반복할 때는 인덱스가 범위 내에 있는지 확인하는 대신 늘 포인터 또는 기타 감시 기능을 감시해야 합니다.
이 관행을 따르는 데는 두 가지 이유가 있는데, 이는 프로그래밍 언어가 결국 (다른 언어들 중에서) 사람에 의해 읽힐 언어라는 사실과 관련이 있다.
(1) 약간의 용장성자연어에서는 보통 오류 정정 코드와 같이 필요한 것보다 더 많은 정보를 제공합니다.여기서 추가 정보는 루프 변수가i
(여기서 용장성을 어떻게 사용했는지 알 수 있습니까?"loop variable"을 읽고 'loop variable'의 의미를 모르거나 변수 이름을 잊어버린 경우i
"모든 정보를 가지고 있습니다")는 루프 중에 5보다 작을 뿐만 아니라 5보다 작습니다.용장성으로 가독성이 향상됩니다.
(2) 조약언어에는 특정 상황을 표현하는 특정한 표준 방법이 있습니다.만약 당신이 어떤 것을 말하는 확립된 방식을 따르지 않는다면, 당신은 여전히 이해할 수 있을 것이지만, 당신의 메시지를 받는 사람에 대한 노력은 더 커집니다. 왜냐하면 어떤 최적화는 효과가 없기 때문입니다.예:
뜨거운 매쉬에 대해 말하지 마세요.난이도를 밝혀주세요!
첫 번째 문장은 독일어 숙어를 문자 그대로 번역한 것이다.두 번째는 일반적인 영어 숙어이며, 주요 단어들은 동의어로 대체된다.결과는 이해할 수 있지만, 이해하는데는 이보다 훨씬 더 오랜 시간이 걸립니다.
빙빙 돌리지 마세요.그냥 문제를 설명해요!
이것은 영어 관용어보다 첫 번째 버전에서 사용된 동의어가 상황에 더 잘 맞는 경우에도 사실이다.프로그래머가 코드를 읽을 때도 비슷한 힘이 작용합니다. '이러니'도 요.5 != i
★★★★★★★★★★★★★★★★★」5 > i
표준적인 환경에서 작업하고 있지 않는 한, 이상한 표현입니다.i != 5
★★★★★★★★★★★★★★★★★」i < 5
이런 은 아마 이 있으면 기억하기 일 거예요.5 == i
가 발생하기 쉬운 「」.i == 5
.
예를 들어 루프 변수가 본문 내부에서 (의도 없이) 변경되는 경우보다 작거나 큰 연산자를 사용하는 방법이 있습니다.
- 부정은 코드를 이해하기 어렵게 만든다.
<
★★★★★★★★★★★★★★★★★」>
이지만 1글자는 입니다.!=
개
리스크를 경감한다고 하는 다양한 유저에 가세해, 다양한 표준 라이브러리 컴포넌트와의 상호작용에 필요한 기능의 과부하도 경감합니다.를 들어,을 「」에할 수 .std::set
'키로 사용합니다.std::map
알고리즘과 ""를 사용합니다std::less
대부분의 알고리즘은 엄밀하게 약한 순서만 필요로 하기 때문에 객체를 비교합니다. 때문에 이렇게 것이 .<
'가 아닌 ''!=
물물론물물물물물이 ( )
, 그 뒤에 가 없습니다.5!=i
소리가 안 나요.
제생는 in in in를 사용해서!=
하지 않습니다.인덱스를 또는 입니다.따라서 합니다(「」의 경우).이는 for 루프가 반복 인덱스를 증가 또는 감소하기 때문입니다.따라서 반복 인덱스가 경계를 벗어날 때까지 반복하도록 루프를 설정합니다( ).!=
(
에, 가 생기기 .!=
부터 알 수 있는 의 경우,이 바로 '하면 알 수 있다'가 아니라 '증감하면 알 수 있다'는입니다.!=
<>>==>
용됩니니다다
언급URL : https://stackoverflow.com/questions/31455629/is-there-a-technical-reason-to-use-instead-of-when-incrementing-by-1-in
'programing' 카테고리의 다른 글
vuex 작업 Vue.js에서 개체 어레이를 정렬할 수 없습니다. (0) | 2022.08.07 |
---|---|
LD_PRELOAD에서 gdb를 사용하는 방법 (0) | 2022.08.07 |
register Natives() 메서드는 무엇을 합니까? (0) | 2022.08.07 |
Java에서의 휘발성 vs 스태틱 (0) | 2022.08.07 |
webpack 또는 browserify를 사용하지 않고 .vue 파일을 .js 파일로 컴파일합니다. (0) | 2022.08.07 |