쉼표 연산자의 적절한 사용법은 무엇입니까?
이 코드를 봤어요.
if (cond) {
perror("an error occurred"), exit(1);
}
왜 그런 짓을 한 거야?왜 그냥 안 돼?
if (cond) {
perror("an error occurred");
exit(1);
}
당신의 예에서는 그것은 전혀 이치에 맞지 않습니다.라고 쓰면 도움이 되는 경우가 있다.
if(cond)
perror("an error occured"), exit(1) ;
--그러면 곱슬곱슬한 치열 교정기는 필요 없습니다.하지만 이건 재앙을 부르는 거야
쉼표 연산자는 참조가 1개만 허용하는 위치에 두 개 이상의 식을 넣는 것입니다.이 경우 사용할 필요가 없습니다.또한 while loop 등 다른 경우에는 도움이 될 수 있습니다.
while (a = b, c < d)
...
여기서 while 루프의 실제 "평가"는 마지막 식에만 의해 제어됩니다.
이것은, 몇개의 예를 들면, 보다 잘 이해할 수 있습니다.
첫 번째: 다음 식을 고려합니다.
x = ++j;
다만, 일시적으로 디버깅 값을 할당할 필요가 있는 경우는, 쓸 수 있습니다.
x = DEBUG_VALUE, ++j;
번째 째째::
마,
.for()
- - loop 예 :
for(i = 0, j = 10; i < N; j--, i++)
// ^ ^ here we can't use ;
번째 째번::
또 하나의 예(실제로 이것을 하는 것은 흥미로울지도 모른다)
if (x = 16 / 4), if remainder is zero then print x = x - 1;
if (x = 16 / 5), if remainder is zero then print x = x + 1;
또한 한 번에 실행할 수도 있습니다.
if(x = n / d, n % d) // == x = n / d; if(n % d)
printf("Remainder not zero, x + 1 = %d", (x + 1));
else
printf("Remainder is zero, x - 1 = %d", (x - 1));
PS: 때때로 사용하는 것이 위험하다는 것을 아는 것도 흥미로울 수 있습니다.,
교환입니다.예를 들어 Strtok 사용법 질문에서 코드가 작동하지 않습니다. 실수로 OP가 함수의 이름을 쓰는 것을 잊었습니다.tokens = strtok(NULL, ",'");
썼습니다.tokens = (NULL, ",'");
는 발생하지 , ' 오류'라는 표현은 합니다.tokens = ",'";
그의 프로그램에 무한 루프를 일으켰습니다.
콤마 연산자의 주요 용도는 난독화입니다.독자가 예상하는 두 가지 작업을 수행할 수 있습니다.가장 빈번한 사용 중 하나인 상태에 부작용을 추가하는 것이 이 범주에 속한다.단, 유효하다고 생각되는 경우가 몇 가지 있습니다.
을 제시하기 것: K&의 두 :for
에서는 이런 할 수 .std::transform
, 「」std::copy
반복기와 반복기와 동시에 증가합니다.)while
루프의 마지막에 다른 스테이트먼트로 증분합니다.이 경우 두 개의 문장이 아닌 쉼표를 사용하는 것은 의미가 없습니다.)
initializer 리스트의 입력 파라미터의 데이터 검증도 생각할 수 있습니다.
MyClass::MyClass( T const& param )
: member( (validate( param ), param) )
{
}
은 (다, 다, 다)라고 가정합니다.validate( param )
뭔가 잘못되면 예외가 발생합니다.)특히 괄호가 더 필요하기 때문에 이 용도는 그다지 매력적이지 않지만, 다른 방법이 많지 않습니다.
마지막으로, 저는 가끔 이 컨벤션을 보았습니다.
ScopedLock( myMutex ), protectedFunction();
에, 「명칭」의 수 있습니다ScopedLock
말하면, 않지만,하는 것을 본 또, 그 에, 「를, 「중괄호」를 붙여서, 「중괄호」를 , 「중괄호」를 붙이는 도 있습니다 그리고 그것을 확실히 하기 위해 여분의 교정기를 추가하는 대안.ScopedLock
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
콤마 연산자의 정규 케이스는 드물지만 존재합니다.예를 들어 조건부 평가 내에서 어떤 일이 일어나기를 원하는 경우입니다.예:
std::wstring example;
auto it = example.begin();
while (it = std::find(it, example.end(), L'\\'), it != example.end())
{
// Do something to each backslash in `example`
}
또한 하나의 표현식만 배치할 수 있지만 두 가지 작업을 수행할 수 있는 장소에서도 사용할 수 있습니다.예를 들어, 다음 루프는 for 루프의 세 번째 컴포넌트에서 x 및 y를 증분합니다.
int x = 0;
int y = some_number;
for(; x < y; ++x, --y)
{
// Do something which uses a converging x and y
}
그것을 사용하려고 하지 말고, 만약 그것이 적절하다면, 그것을 사용하는 것을 두려워하지 말고, 다른 사람이 그것을 사용하는 것을 보더라도 당황하지 마라.별도의 문장이 아닐 이유가 없는 두 가지가 있는 경우 쉼표 연산자를 사용하는 대신 별도의 문장으로 만드십시오.
쉼표 연산자를 사용하면 원하는 식을 그룹화할 수 있습니다.
예를 들어 다음과 같은 경우에 도움이 될 수 있습니다.
// In a loop
while ( a--, a < d ) ...
하지만 당신의 경우에는 그것을 사용할 이유가 없습니다.헷갈릴 것 같은데...바로 그거야...
당신의 경우, 그것은 단지 곱슬곱슬한 괄호를 피하기 위한 것입니다.
if(cond)
perror("an error occurred"), exit(1);
// =>
if (cond)
{
perror("an error occurred");
exit(1);
}
쉼표 연산자 설명서에 대한 링크입니다.
조건이 참 또는 거짓일 때 두 개 이상의 명령을 실행하려는 경우 여행 일정 운영자에게 유용할 수 있습니다.단, 쉼표 연산자 왼쪽에서 오른쪽 평가 규칙(괄호 안)으로 인해 반환 값이 가장 오른쪽 표현이라는 점에 유의하십시오.
예:
a<b?(x=5,b=6,d=i):exit(1);
연산자()의 실제 용도는 거의 없는 것 같습니다.
Bjarne Stroustrup, C++의 설계와 진화
쉼표 사용의 대부분은 위키피디아 기사 쉼표_operator#Uses에서 확인할 수 있습니다.
boost::assign을 사용했을 때 발견한 흥미로운 사용법이 있습니다.여기서 연산자는 연산자가 콤마로 구분된 값의 리스트로 동작하도록 신중하게 오버로드되어 벡터 객체의 끝에 푸시할 수 있습니다.
#include <boost/assign/std/vector.hpp> // for 'operator+=()'
using namespace std;
using namespace boost::assign; // bring 'operator+=()' into scope
{
vector<int> values;
values += 1,2,3,4,5,6,7,8,9; // insert values at the end of the container
}
안타깝게도, 프로토타이핑에 널리 쓰였던 위의 용도는 컴파일러가 Uniform Initialization을 지원하기 시작하면 이제 구식으로 보일 것입니다.
그럼 이제 다시 한 번
연산자()의 실제 용도는 거의 없는 것 같습니다.
Bjarne Stroustrup, C++의 설계와 진화
당신의 경우 쉼표 연산자는 곱슬곱슬한 괄호를 피할 수 있었기 때문에 무용지물이지만, 글쓴이가 이미 넣었기 때문에 그렇지 않습니다.그래서 그것은 쓸모없고 혼란스러울 수 있다.
그boost::assign
는 다음과 같은 구문을 실현하기 위해 콤마 연산자의 과부하를 크게 합니다.
vector<int> v;
v += 1,2,3,4,5,6,7,8,9;
언급URL : https://stackoverflow.com/questions/17902992/what-is-the-proper-use-of-the-comma-operator
'IT이야기' 카테고리의 다른 글
Vuex 이거.하위 구성 요소에 $store가 정의되지 않았습니다. (0) | 2022.06.10 |
---|---|
포인터에 대한 포인터와 일반 포인터 (0) | 2022.06.10 |
VueJ 2.0 - 소품 업데이트 시 컴포넌트를 잠글 수 없음 (0) | 2022.06.10 |
바이너리 모드와 텍스트 모드로 작성된 파일의 차이 (0) | 2022.06.10 |
stacktrace를 log4j로 전송하는 방법 (0) | 2022.06.10 |