C language puzzles

Source: Internet
Author: User

We can see a lot of C-related things. For example, "language ambiguity" mainly tells you about unexpected errors and ambiguous things in C language. Who said C language is very simple, but it is not easy to tell everyone about C language through some code that seems to have never been written. "6 abnormal hello world" and "how to mess up C source code" tell everyone in an extreme way, don't think we can't write messy code ourselves, every programmer has the potential to mess up the code. Through these articles, I believe you have some knowledge about programming or the C language that you think is very simple. Yes, it's not easy. Have you ever underestimated programming and C language? Today, are we underestimating C ++ and Java? This article "C language puzzles" shows 14 questions and answers in C language. The Code should be clear enough, and I believe there are quite a few examples that we may see in our daily work. Through these questions, I hope you can better understand the C language. If you don't read the answer, do you know whether you are sure to answer each puzzle? Let's try it.

1. The following program does not necessarily output hello-std-out. Do you know why?

# Include # includeint main () {while (1) {fprintf (stdout, "hello-std-out"); fprintf (stderr, "hello-std-err "); sleep (1);} return 0 ;}
Reference answer: Is stdout and stderr the same as the device descriptor. Stdout is a block device, and stderr is not. Block devices are input only in the following situations. 1) return a carriage return, 2) the buffer is full, and 3) flush is called. But stderr does not.
2. The following program looks normal and uses a comma expression for initialization. Unfortunately, this program is faulty. You know why?

# Includeint main () {int a = 1, 2; printf ("a: % d", a); return 0 ;}
Reference answer: this program will get compilation errors (syntax errors). The comma expression is correct, but when initializing and declaring variables, the comma is not a comma expression. To modify the above program, you need to add parentheses: int a = (1, 2 );

3. What kind of output will the following program have?

# Define deint main () {int I = 43; printf ("% d", I ))); return 0 ;}
Reference answer: The program outputs 4321. Do you know why? To know why, you need to know what the return value of printf is. The return value of printf is the number of output characters.

4. What will the following program output?

# Define deint main () {float a = 12.5; printf ("% d", a); printf ("% d", (int) ); printf ("% d", * (int *) & a); return 0 ;}
Reference answer: The program output is as follows, 0 12 1095237632 is because: floating point number is 4 bytes, 12.5f is converted to binary: 01000001010010000000000000000000, hexadecimal: 0x41480000, decimal is: 1095237632. Therefore, the second and third outputs I believe everyone knows why. For the first one, why is the output 0? We need to understand the memory layout of float and double, as shown below:

Float: 1-bit sign bit (s), 8-bit index (e), 23-bit ending number (m, 32 digits in total)
Double: 1-bit sign (s), 11-bit index (e), 52-bit ending number (m, 64-bit in total)
Then, we also need to know that because the printf type does not match, the float will be directly converted to double. Note that the 12.5 float and double memory binary are completely different. Do not forget to use the reverse byte order in the x86 chip. The reverse direction is between the high byte and the low byte. Therefore:

Float: 0x41480000 (in memory: 00 00 48 41)
Double: 0x4029000000000000 (in memory: 00 00 00 00 00 00 29 40)
Our % d requirement is a 4-byte int. For the double memory layout, we can see that the first four bytes are 00, so the output is naturally 0. This example shows that printf is not of type security, which is why C ++ needs to be cited as cout.

5. Next, let's look at a cross-compilation task. Can the two files below be compiled? If yes, what is the result?

// File1.cint arr [80]; // file2.cextern int * arr; int main () {arr [1] = 100; printf ("% d", arr [1]); return 0 ;}
Reference answer: This program can be compiled, but an error occurs during running. Why? The reason is that using extern int * arr in another file to declare an array externally does not get the expected value because their types do not match. Therefore, the pointer does not actually point to the array. Note: A pointer to an array is not equal to an array. Modify: extern int arr []. (Refer to section 6.5.4.2 of ISO c language)

6. What is the output of the following program? And explains why? (Note that this program does not output "B is 20 ")

# Define deint main () {int a = 1; switch (a) {int B = 20; case 1: printf ("B is % d", B); break; default: printf ("B is % d", B); break;} return 0 ;}
Reference answer: during compilation, a warning: unreachable code at beginning of switch statement may appear. We thought that after entering the switch, variable B will be initialized, but it is not because the switch-case statement will directly skip the initialization of variable B. Therefore, the program outputs a random memory value.

7. What are the potential risks of the following procedures?

# Shortdeint main () {char str [80]; printf ("Enter the string:"); scanf ("% s", str); printf ("You entered: % s ", str); return 0 ;}
Reference answer: This question is very simple. The potential problem with this program is that if you enter more than 80 characters in length, there will be an array out-of-bounds problem, and your program will be able to crash.
8. What is the output of the following program?

# Includeint main () {int I; I = 10; printf ("I: % d", I); printf ("sizeof (I ++) is: % d ", sizeof (I ++); printf ("I: % d", I); return 0 ;}
Reference answer: If you think the output is respectively, 10, 4, 11, then you are wrong. The error is in the third place. The first is 10, and there is no problem. The second is 4, there is no problem because an int on a 32-bit machine has four bytes. But why is the third output not 11? Actually 10? The reason is that sizeof is not a function, but an operator, which calculates the size of the I ++ type. This is a task that can be completed before the program runs (during compilation). Therefore, sizeof (I ++) is directly replaced by 4, and there will be no I ++ expression at runtime.

9. What is the output value of the following program?

# Include # define SIZEOF (arr) (sizeof (arr)/sizeof (arr [0]) # define PrintInt (expr) printf ("% s: % d ", # expr, (expr) int main () {/* The powers of 10 */int pot [] = {0001,001 0, 0100,100 0}; int I; for (I = 0; I <SIZEOF (pot); I ++) PrintInt (pot [I]); return 0 ;}
Reference answer: Well, if you have a problem with the macro PrintInt, you can take a look at the fourth example in language ambiguity. However, the problem in this example is not here. The output in this example will be:, which is actually very simple. In C/C ++, all numbers starting with 0 are octal.

10. What is the output of the following program? (Definitely not 10)

# Include # define PrintInt (expr) printf ("% s: % dn", # expr, (expr) int main () {int y = 100; int * p; p = malloc (sizeof (int); * p = 10; y = y/* p;/* dividing y by * p */; PrintInt (y ); return 0 ;}
Reference answer: the answer to this question is 100. Why? The problem lies in y = y/* p;. we originally thought of y/(* p). However, we did not add spaces and parentheses, result/* in y/* p is interpreted as the beginning of the annotation. This is also the beginning of the nightmare.

11. What is the output below?

# Includeint main () {int I = 6; if (++ I <7) & (I ++/6 )) | (++ I <= 9); printf ("% d", I); return 0 ;}
Reference answer: This question is not simply about prefix ++ or suffix ++. This question is mainly about short-circuit evaluation of & and |. Short-circuit evaluation: For (condition 1 & condition 2), if "condition 1" is false, the expression of "condition 2" is ignored. For condition 1 | condition 2, if condition 1 is true, the expression of condition 2 is ignored. So I believe you will know what the answer to this question is.

12. Is the following C program legal? If yes, what is the output?

# Includeint main () {int a = 3, B = 5; printf (& a ["Ya! Hello! How is this? % S "], & B [" junk/super "]); printf (& a [" WHAT % c! "], 1 [" this "], 2 [" beauty "], 0 [" tool "], 0 [" is "], 3 [" sensitive "], 4 ["CCCCCC"]); return 0 ;}
Reference answer: This example is valid and the output is as follows:

Hello! How is this? Super That is C!
This example shows an alternative usage. The following two usage methods are the same:

"Hello" [2] 2 ["hello"]
If you know that a [I] is actually * (a + I) or * (I + a), it is not hard to understand if I [a] is written.

13. What is the output of the following program? (Assume: Input Hello, World)

# Includeint main () {char dummy [80]; printf ("Enter a string:"); scanf ("% [^ r]", dummy ); printf ("% s", dummy); return 0 ;}
Reference answer: the output in this example is "Hello, Wo". "% [^ r]" in scanf is a stem. It means that the character r is over.

14. The following program tries to use the bitwise operation to perform the multiplication 5 operation. However, this program has a BUG. Do you know what it is?

# Include
# Define PrintInt (expr) printf ("% s: % d", # expr, (expr ))
Int FiveTimes (int)
{
Int t;
T = a <2 +;
Return t;
}

Int main ()
{
Int a = 1, B = 2, c = 3;
PrintInt (FiveTimes ());
PrintInt (FiveTimes (B ));
PrintInt (FiveTimes (c ));
Return 0;
}

Reference answer: the question in this question is that the expression "t = a <2 + a;" in the FiveTimes function has a lower priority than the addition method for a <2, therefore, this expression becomes "t = a <(2 + a)", so we cannot get the value we want. The program is modified as follows:

Int FiveTimes (int a) {int t; t = (a <2) + a; return t ;}
(Full text)

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.