cout은 무엇을합니까 <<“\ n”[a == N]; 하다?
다음 예에서 :
cout<<"\n"[a==N];
[]
옵션이에서 무엇을하는지에 대한 단서가 없지만 cout
의 값 a
이 같을 때 개행을 인쇄하지 않습니다 N
.
cout에서 [] 옵션이 수행하는 작업에 대한 단서가 없습니다.
이것은 실제로 cout
옵션 이 아니며 "\n"
, 문자열 리터럴 입니다. 문자열 리터럴은 n const char 형 배열을 가지며 , []
이 경우에는 다음을 포함하는 문자 배열에 대한 단순히 인덱스입니다.
\n\0
참고 \0
는 모든 문자열 리터럴에 추가됩니다.
==
중 하나에서 운영자 결과 참 또는 거짓 , 인덱스가 될 수 있도록 :
0
경우는 false 경우,a
하지와 동일하지N
의 결과\n
1
참이면a
같으면N
결과\0
이것은 다소 비밀스럽고 간단한 if
.
참고로 C ++ 14 표준 ( 가벼움은 초안이 실제 표준과 일치 함을 확인 함 )과 가장 가까운 초안은 문자열 리터럴 [lex.string] 섹션 에서 N3936 입니다 ( 강조 내 ) :2.14.5
문자열 리터럴 에는 "n const char 배열"유형이 있습니다 . 여기서 n은 아래 정의 된 문자열의 크기이며 정적 저장 기간 (3.7)을 갖습니다.
과:
필요한 연결 후, 번역 단계 7 (2.2)에서 '\ 0'이 모든 문자열 리터럴에 추가되어 문자열 을 스캔하는 프로그램이 끝을 찾을 수 있습니다.
섹션 4.5
[conv.prom] 내용 :
bool 유형의 prvalue는 false가 0이되고 true가 1이되는 int 유형의 prvalue로 변환 될 수 있습니다.
텍스트 스트림에 널 문자 쓰기
\0
텍스트 스트림에 null 문자 ( )를 쓰는 것은 정의되지 않은 동작 이라는 주장이 제기되었습니다 .
이것이 합리적인 결론 cout
이라고 말할 수있는 한, 27.4.2
[narrow.stream.objects] 에서 볼 수 있듯이 C 스트림의 관점에서 정의됩니다 .
cout 개체는 <cstdio> (27.9.2)에 선언 된 개체 stdout과 관련된 스트림 버퍼에 대한 출력을 제어합니다.
7.21.2
Streams 섹션의 C11 초안 표준은 다음과 같이 말합니다.
[...] 텍스트 스트림에서 읽은 데이터는 다음 경우에만 해당 스트림에 이전에 기록 된 데이터와 반드시 동일하게 비교됩니다. 데이터는 인쇄 문자와 제어 문자 가로 탭 및 줄 바꾸기로만 구성됩니다.
및 인쇄 문자 에 포함되는 7.4
문자 처리 <ctype.h> :
[...] 제어 문자라는 용어는 문자를 인쇄하지 않는 로케일 특정 문자 집합의 구성원을 나타냅니다 .199) 모든 문자와 숫자는 인쇄 문자입니다.
각주와 함께 199
:
7 비트 US ASCII 문자 집합을 사용하는 구현에서 인쇄 문자는 값이 0x20 (공백)에서 0x7E (물결표)까지입니다. 제어 문자는 값이 0 (NUL)에서 0x1F (US)까지의 값과 0x7F (DEL) 문자입니다.
마지막으로 null 문자를 보낸 결과가 지정되지 않았 음을 알 수 있으며 이것이 4
Conformance 섹션에서 정의되지 않은 동작임을 알 수 있습니다 .
[...] 정의되지 않은 동작은 "정의되지 않은 동작"이라는 단어 또는 명시적인 동작 정의의 생략으로이 국제 표준에서 달리 표시됩니다. [...]
또한 다음과 같은 C99 이론적 근거 를 살펴볼 수 있습니다 .
텍스트 스트림 I / O에서 보존해야하는 문자 세트는 C 프로그램 작성에 필요한 문자입니다. 의도는 표준이 C 번역기가 최대한 이식 가능한 방식으로 작성되도록 허용해야한다는 것입니다. 백 스페이스와 같은 제어 문자는이 목적에 필요하지 않으므로 텍스트 스트림에서의 처리는 필수가 아닙니다.
cout<<"\n"[a==N];
cout에서 [] 옵션이 수행하는 작업에 대한 단서가 없습니다.
에서 C ++ 연산자 우선 순위 테이블 , operator []
보다 귀속 엄격한 operator <<
, 당신의 코드에 해당하므로 :
cout << ("\n"[a==N]); // or cout.operator <<("\n"[a==N]);
또는 다른 말로하면, operator []
직접 아무것도하지 않습니다 cout
. 문자열 리터럴의 인덱싱에만 사용됩니다."\n"
예를 들어 for(int i = 0; i < 3; ++i) std::cout << "abcdef"[i] << std::endl;
화면의 연속 된 행에 문자 a, b 및 c를 인쇄합니다.
때문에 문자열 리터럴 에 C++
있습니다 항상 널 문자 (종료 '\0'
, L'\0'
, char16_t()
, 등), 문자열 리터럴 "\n"
인 const char[2]
문자를 유지 '\n'
하고'\0'
메모리 레이아웃에서 이것은 다음과 같습니다.
+--------+--------+
| '\n' | '\0' |
+--------+--------+
0 1 <-- Offset
false true <-- Result of condition (a == n)
a != n a == n <-- Case
따라서 a == N
가 참이면 (1로 승격 됨) 표현식은 "\n"[a == N]
결과가 '\0'
되고 '\n'
결과가 거짓이면 결과가됩니다.
다음과 기능적으로 유사 (동일하지 않음)
char anonymous[] = "\n";
int index;
if (a == N) index = 1;
else index = 0;
cout << anonymous[index];
valueof "\n"[a==N]
is '\n'
or '\0'
typeof "\n"[a==N]
is const char
If the intention is to print nothing (Which may be different from printing '\0'
depending on platform and purpose), prefer the following line of code:
if(a != N) cout << '\n';
Even if your intention is to write either '\0'
or '\n'
on the stream, prefer a readable code for example:
cout << (a == N ? '\0' : '\n');
It's probably intended as a bizarre way of writing
if ( a != N ) {
cout<<"\n";
}
The []
operator selects an element from an array. The string "\n"
is actually an array of two characters: a new line '\n'
and a string terminator '\0'
. So cout<<"\n"[a==N]
will print either a '\n'
character or a '\0'
character.
The trouble is that you're not allowed to send a '\0'
character to an I/O stream in text mode. The author of that code might have noticed that nothing seemed to happen, so he assumed that cout<<'\0'
is a safe way to do nothing.
In C and C++, that is a very poor assumption because of the notion of undefined behavior. If the program does something that is not covered by the specification of the standard or the particular platform, anything can happen. A fairly likely outcome in this case is that the stream will stop working entirely — no more output to cout
will appear at all.
In summary, the effect is,
"Print a newline if
a
is not equal toN
. Otherwise, I don't know. Crash or something."
… and the moral is, don't write things so cryptically.
It is not an option of cout
but an array index of "\n"
The array index [a==N]
evaluates to [0] or [1], and indexes the character array represented by "\n"
which contains a newline and a nul character.
However passing nul to the iostream will have undefined results, and it would be better to pass a string:
cout << &("\n"[a==N]) ;
However, the code in either case is not particularly advisable and serves no particular purpose other than to obfuscate; do not regard it as an example of good practice. The following is preferable in most instances:
cout << (a != N ? "\n" : "") ;
or just:
if( a != N ) cout << `\n` ;
Each of the following lines will generate exactly the same output:
cout << "\n"[a==N]; // Never do this.
cout << (a==N)["\n"]; // Or this.
cout << *((a==N)+"\n"); // Or this.
cout << *("\n"+(a==N)); // Or this.
As the other answers have specified, this has nothing to do with std::cout
. It instead is a consequence of
How the primitive (non-overloaded) subscripting operator is implemented in C and C++.
In both languages, ifarray
is a C-style array of primitives,array[42]
is syntactic sugar for*(array+42)
. Even worse, there's no difference betweenarray+42
and42+array
. This leads to interesting obfuscation: Use42[array]
instead ofarray[42]
if your goal is to utterly obfuscate your code. It goes without saying that writing42[array]
is a terrible idea if your goal is to write understandable, maintainable code.How booleans are transformed to integers.
Given an expression of the forma[b]
, eithera
orb
must be a pointer expression and the other; the other must be an integer expression. Given the expression"\n"[a==N]
, the"\n"
represents the pointer part of that expression and thea==N
represents the integer part of the expression. Here,a==N
is a boolean expression that evaluates tofalse
ortrue
. The integer promotion rules specify thatfalse
becomes 0 andtrue
becomes 1 on promotion to an integer.How string literals degrade into pointers.
When a pointer is needed, arrays in C and C++ readily degrade into a pointer that points to the first element of the array.How string literals are implemented.
Every C-style string literal is appended with the null character'\0'
. This means the internal representation of your"\n"
is the array{'\n', '\0'}
.
Given the above, suppose a==N
evaluates to false
. In this case, the behavior is well-defined across all systems: You'll get a newline. If, on the other hand, a==N
evaluates to true
, the behavior is highly system dependent. Based on comments to answers to the question, Windows will not like that. On Unix-like systems where std::cout
is piped to the terminal window, the behavior is rather benign. Nothing happens.
Just because you can write code like that doesn't mean you should. Never write code like that.
참고URL : https://stackoverflow.com/questions/30888851/what-does-cout-na-n-do
'IT Share you' 카테고리의 다른 글
Mac OSX Java 터미널 버전이 잘못되었습니다. (0) | 2020.12.03 |
---|---|
Selenium WebDriverException을 수정하는 방법 : 연결하기 전에 브라우저가 종료 된 것 같습니다. (0) | 2020.12.03 |
Buildr, Gradle 또는 Maven 3을 기다리시겠습니까? (0) | 2020.12.03 |
NSTextField에서 Enter-Key를 눌렀을 때 액션을 실행합니까? (0) | 2020.12.02 |
가시성 : 숨김 및 표시 간의 성능 차이 : 없음 (0) | 2020.12.02 |