int main()
{ char *arr="\\0\1\8234\0"; int i=0;
while(arr[i])
{ switch(arr[i])
{
case '0': printf("is no"); break;
case '00': printf("is debugging\n"); break;
case 0: printf("It is Avishkar\n"); break;
case '\\': printf("This "); break;
case '\1': printf("t 开发者_运维百科s"); break;
case '8': printf("o s"); break;
case '2': printf("imp"); break;
case '3': printf("le as"); break;
case 2: case 3: case 4:
case 8: printf("This "); break;
default: printf(" it seems\n"); break;}
i++; } }
please explain the o/p ? i am not able to get it..
Breaking down the string initialization we have:
\\ == literal \ character \1 == octal representation of integer "1" \8 == technically invalid standard C, microsoft compilers will treat an unsupported (i.e. non-octal, non-escape, non-hex-specifier) character after a slash as if the slash were not present, so this is ascii '8' 2 == ascii '2' 3 == ascii '3' 4 == ascii '4' \0 == literal zero
arr[ 0 ] = '\\'; // literal backslash
arr[ 1 ] = '0'; // ascii '0'
arr[ 2 ] = 1; // integer 1
arr[ 3 ] = '8'; // using microsoft (non-portable) syntax
arr[ 4 ] = '2'; // ascii '2'
arr[ 5 ] = '3'; // ascii '3'
arr[ 6 ] = '4'; // ascii '4'
arr[ 7 ] = 0; // integer 0
The loop prints for each successive value of i:
i == 0: "This " i == 1: "is no" i == 2: "t s" i == 3: "o s" i == 4: "imp" i == 5: "le as" i == 6: "it seems"
literally:
This is not so simple as it seems
The trailing \0 is to cause the while( arr[ i ] ) to fail and the loop to stop when i == 7.
Although this will probably cause the compiler to complain on non-microsoft compilers.
\\
means just slash character. \1
means character with code 1. \8
is tricky - it would produce slash and 8
as \
expects octal and 8 is not a valid octal digit. Final \0
is redundant, since C constant strings automatically end in \0
, but it would produce character with code 0, which in C means the end of the string.
In general, in C string \xxx
where xxx
are octal digits means character with code xxx
- e.g. \12
means character with code 10 (octal 12
).
In general the \0 escape is the char value 0 -- the null terminator used to mark the end of a char*
style string. Literals like "foo" are automatically null terminated by the compiler; it is only when you construct a char array with initializer syntax (char foo[] = { 'a', 'b', 'c', '\0'};
) that you'd need to use \0 explicitly, for the most part. And in that case you could use the integer literal 0 as well (no quotes).
Most other occurrences of embedded nulls are context-specific. For example some Win32 API functions expect char
arrays that are null terminated to indicate separation between items in a list, and then double-null terminated to indicate the end of a list. This does not appear to be the case with your sample code.
Your sample code appears to be a bit of intentionally obfuscated code to just print a simple message. The \0 appears to be a red herring -- it is unnecessary. When arr[i] is '4' the code will print ' it seems\n' and increment i, so arr[i] is now the \0. This is equivalent to 0, which will cause the while loop to terminate, which would have happened anyway due to the implicit null terminator in the string.
N.B. the code uses some questionable things like the multi-character literal and \8 escape. I'm not sure it will function quite as intended.
From your code:
\\ - \ (Slash character)
\0 - 0 (Null-terminated character which simply appends '0')
Note: \0 is never a case statement, because when while(0)
it ends your loop.
What is escaped
char *arr="\\0\1\8234\0"; int i=0;
\\
is an escaped backslash. (The zero coming just afterward is not escaped.)\1
represents the character with octal ASCII code 1. (\8
is an invalid escape code; the popular GCC compiler ignores the backslash, but one should not depend on that behavior.)\0
represents a null byte, which is the character used to terminate a C string. The C compiler automatically adds another null byte at the end of the double-quoted string; in your case, it is unnecessary to include it explicitly.
Program flow
The program iterates over the characters in the string until it hits the first null byte, the marker of the string's end (while(arr[i]) { ... i++; }
). For each one, it compares it to several other values using a switch
statement.
Thus the program's output is "This is not so simple as it seems\n"
.
Lines never executed
This line is never executed, because control leaves the while
loop before then:
case 0: printf("It is Avishkar\n"); break;
Note that because the zero is not single-quoted as a character literal, it refers to the character code, not the actual character represented.
These lines are also not executed:
case '00': printf("is debugging\n"); break;
case 8: printf("This "); break;
The former uses a multi-character literal (not to be confused with a double quoted string), which has implementation-defined behavior. GCC packs the characters into an int
, so the resulting value is 12336 for that compiler. It is, of course, not equal to any character value that would be found in the string; see this compiler warning:
prog.c:7: warning: case label value exceeds maximum value for type
The latter refers to decimal ASCII code 8. As mentioned above, this is not the same as '8'
.
精彩评论