Who says C language is very simple? These 14 C language puzzles are hard to cry

Time:2021-10-25

This article shows 14 C language puzzles and answers. The code should be clear enough, and there are quite a few examples that we may meet in our daily work. Through these puzzles, I hope you can understand C language better.

If you don’t look at the answers, do you know if you are sure to answer each puzzle? Let’s try.

 

1. The following program does not necessarily output “Hello STD out”. Do you know why?

#include

#include

int main()

{

while(1)

{

fprintf(stdout,”hello-std-out”);

fprintf(stderr,”hello-std-err”);

sleep(1);

}

return 0;

}

Reference answer

Stdout and stderr are different device descriptors. Stdout is a block device, stderr is not. For a block device, it can be entered only when the following conditions are met: enter; Buffer full; Flush is called. Stderr does not.

2. The following program looks normal and uses a comma expression for initialization. Unfortunately, this procedure is problematic. Do you know why?

#include

int main()

{

int a = 1,2;

printf(“a : %dn”,a);

return 0;

}

Reference answer

This program will get compilation errors (syntax errors). Comma expression is true, but in initialization and variable declaration, comma is not the meaning of 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?

#include

int main()

{

int i=43;

printf(“%dn”,printf(“%d”,printf(“%d”,i)));

return 0;

}

Reference answer

The program will output 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 characters output.

 

4. What will the following program output?

#include

int main()

{

float a = 12.5;

printf(“%dn”, a);

printf(“%dn”, (int)a);

printf(“%dn”, *(int *)&a);

return 0;

}

Reference answer

The program output: “0 12 1095237632”.

The reason is that the floating-point number is 4 bytes, 12.5f is converted to binary: 01000001001000000000000000000000000000, hexadecimal: 0x41480000, decimal: 1095237632. Therefore, I believe you know why the second and third outputs.

For the first one, why 0 is output, we need to know the memory layout of float and double, as follows:

• float: 1-bit sign bit (s), 8-bit exponent (E), 23 bit mantissa (m, 32 bits in total).

• double: 1-bit sign bit (s), 11 bit exponent (E), 52 bit mantissa (m, 64 bits in total).

Then, we also need to know that printf will directly convert float to double due to type mismatch. Note that the memory binary of float and double in 12.5 is completely different. Don’t forget to use the reverse byte order under the x86 chip, and the high byte and low word bits should be reversed. So:

• float version: 0x41480000 (in memory: 00 00 48 41).

• double version: 0x4029000000000000 (in memory: 00 00 29 40).

Our% d requires a 4-byte int. for the memory layout of double, we can see that the first four bytes are 00, so the output is naturally 0. This example shows us that printf is not type safe, which is why C + + is cited as cout.

5. Next, let’s look at a cross compilation. Can the following two files be compiled? If yes, what is the result?

//file1.cint arr[80];

//file2.cextern int *arr;

int main()

{

arr[1] = 100;

printf(“%dn”, arr[1]);

return 0;

}

Reference answer

The program can be compiled, but there will be errors when running. Why? The reason is that declaring an array externally with extern int * arr in another file does not get the actual expected value because their types do not match. So the pointer doesn’t actually point to that array.

Note: a pointer to an array is not equal to an array.

Modify: “extern int arr []”.

6. What is the output of the following program? And explain why? (note that the program does not output “B is 20”)

#include

int main()

{

int a=1;

switch(a)

{

int b=20;

case 1:

printf(“b is %dn”,b);

break;

default:

printf(“b is %dn”,b);

break;

}

return 0;

}

Reference answer

When compiling the program, a warning: unreachable code at beginning of switch statement may appear. We thought that after entering the switch, the variable B will be initialized. In fact, it is not, because the switch case statement will directly skip the initialization of variable B. Therefore, the program will output a random memory value.

 

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

#include

int main()

{

char str[80];

printf(“Enter the string:”);

scanf(“%s”,str);

printf(“You entered:%sn”,str);

return 0;

}

Reference answer

The question is very simple. The potential problem with this program is that if the user enters more than 80 characters, there will be an array out of bounds problem, and your program is likely to crash.

8. What does the following program output?

#include

int main()

{

int i;

i = 10;

printf(“i : %dn”,i);

printf(“sizeof(i++) is: %dn”,sizeof(i++));

printf(“i : %dn”,i);

return 0;

}

Reference answer

If you think the output is: 10, 4, 11. Then you’re wrong.

The third one is wrong. The first one is 10. There is no problem. The second one is 4. There is no problem, because an int on a 32-bit machine has 4 bytes. But why doesn’t the third one output 11? Still 10? The reason is that sizeof is not a function, but an operator. It seeks the size of the type of I + +, which can be completed before the program runs (at compile time). Therefore, sizeof (I + +) is directly replaced by 4, and there will be no expression of I + + at run time.

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

#include

#include

#define SIZEOF(arr) (sizeof(arr)/sizeof(arr[0]))

#define PrintInt(expr) printf(“%s:%dn”,#expr,(expr))

int main()

{

/* The powers of 10 */

int pot[] = {

0001,

0010,

0100,

1000

};

int i;

for(i=0;i

return 0;

}

Reference answer

If you have any questions about the printint macro, you can take a look at the information. However, the problem of this example is not here. The output of this example will be: 1, 8, 641000. In fact, it’s very simple. In C / C + +, the 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 output of this question is 100. Why? The problem is “y = y”/p; “Yes, we thought” Y /(p) “However, we did not add spaces and parentheses, and the result” Y “/P “in”/“Is interpreted as the beginning of the annotation. Therefore, this is also the beginning of the whole nightmare.

 

11. What is the output below?

#include

int main()

{

int i = 6;

if( ((++i < 7) && ( i++/6)) || (++i <= 9));

printf(“%dn”,i);

return 0;

}

Reference answer

This question is not a simple test of prefix + + or anti affix + +. This question mainly tests the short-circuit evaluation of & & and |.

Short circuit evaluation: for (condition 1 & & condition 2), if “condition 1” is false, the expression of “condition 2” will be ignored. For (condition 1 | condition 2), if “condition 1” is true, the expression of “condition 2” is ignored.

So, I believe you will know the answer to this question.

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

#include

int main()

{

int a=3, b = 5;

printf(&a[“Ya!Hello! how is this? %sn”], &b[“junk/super”]);

printf(&a[“WHAT%c%c%c %c%c %c !n”], 1[“this”],2[“beauty”],0[“tool”],0[“is”],3[“sensitive”],4[“CCCCCC”]);

return 0;

}

Reference answer

This example is legal, and the output is: “Hello! How is this? Super that is c!”

This example mainly shows an alternative usage. The following two usages are the same:

• “hello”[2]

• 2[“hello”]

If you know: a [i] is actually(a + I) that is(I + a), so it should not be difficult to understand if it is written as I [a].

13. What does the following program output? (suppose: enter “Hello, world”)

#include

int main()

{

char dummy[80];

printf(“Enter a string:n”);

scanf(“%[^r]”,dummy);

printf(“%sn”,dummy);

return 0;

}

Reference answer

The output of this example is “Hello, Wo”. The “%” in scanf is a hindrance, which means that it ends when it meets the character R.

14. The following program attempts to use “bit operation” to complete the “multiply 5” operation, but there is a bug in this program. Do you know what it is?

#include

#define PrintInt(expr) printf(“%s : %dn”,#expr,(expr))

int FiveTimes(int a)

{

int t;

t = a<<2 + a;

return t;

}

int main()

{

int a = 1, b = 2,c = 3;

PrintInt(FiveTimes(a));

PrintInt(FiveTimes(b));

PrintInt(FiveTimes(c));

return 0;

}

Reference answer

The problem with this problem is the expression “t = a < < 2 + A;” in the function fivetimes. For the bit operation a < < 2, the priority is lower than addition, so the expression becomes “t = a < < (2 + a)”, so we can’t get the value we want.

The procedure is amended as follows:

int FiveTimes(int a)

{

int t;

t = (a<<2) + a;

return t;

}

The above is my share. If you have any questions, please leave a message in the comment area.

Transferred from: http://coolshell.cn/articles/945.html

 

Finally, if you want to be a programmer and want to master programming quickly, join quicklyLearn Penguin circle

There are senior professional software development engineers to answer all your doubts online ~ introduction to programming language “so easy”

Programming learning books:

 

Programming learning video:

 

Recommended Today

Swift advanced (XV) extension

The extension in swift is somewhat similar to the category in OC Extension can beenumeration、structural morphology、class、agreementAdd new features□ you can add methods, calculation attributes, subscripts, (convenient) initializers, nested types, protocols, etc What extensions can’t do:□ original functions cannot be overwritten□ you cannot add storage attributes or add attribute observers to existing attributes□ cannot add parent […]