C language is too simple? How many of these 14 C language puzzles can you answer correctly?

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

If you don't look at the answers, do you know if you can answer each puzzle with confidence? Let's try it.

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 will only be entered in the following situations: a carriage return is encountered; the buffer is full; flush is called. And stderr doesn't.

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


#include
int main()
{
      int a = 1,2;
      printf("a : %d\n",a);
      return 0;
}

reference answer

This program will get compile error (syntax error). Comma expressions are true, but commas are not the meaning of comma expressions when initializing and declaring variables. This point needs to be distinguished. To modify the above program, you need to add parentheses: "int a = (1,2);".

What will be the output of the following program?


#include
int main()
{
      int i=43;
      printf("%d\n",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.

What will the following program output?


#include
int main()
{
      float a = 12.5;
      printf("%d\n", a);
      printf("%d\n", (int)a);
      printf("%d\n", *(int *)&a);
      return 0;
}

reference answer

The program output: "0 12 1095237632".

The reason is: the floating point number is 4 bytes, 12.5f converted to binary is: 01000001010010000000000000000000, hexadecimal: 0x41480000, decimal: 1095237632. Therefore, I believe everyone knows why the second and third outputs are.

For the first one, why it outputs 0, we need to understand the memory layout of float and double, as follows:

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

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

Then, we also need to understand that printf will directly convert float to double because of the 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, the high-order byte and the low-order word should be reversed. so:

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

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

And our %d requirement is 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++ uses cout.

Next, let's look at another cross-compilation thing. Can the following two files be compiled? If it can pass, what is the result?


//file1.cint arr[80];
//file2.cextern int *arr;
int main()
{
      arr[1] = 100;
      printf("%d\n", arr[1]);
      return 0;
}

reference answer

The program compiles, but fails when run. why? The reason is that externally declaring an array with extern int *arr in another file doesn't get the actual expected value because their types don't match. So the pointer does not actually point to that array.

Note: A pointer to an array is not equal to an array

Modify: "extern int arr[]".

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 %d\n",b);
                  break;
            default:
                  printf("b is %d\n",b);
            break;
      }
      return 0;
}

reference answer

When the program is compiled, a warning: unreachable code at beginning of switch statement may appear. We thought that after entering the switch, the variable b would be initialized, but it is not, because the switch-case statement will directly skip the initialization of the variable b. So, the program will output a random memory value.

What are the potential dangers of the following procedure?


#include
int main()
{
      char str[80];
      printf("Enter the string:");
      scanf("%s",str);
      printf("You entered:%s\n",str);
      return 0;
}

reference answer

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

What is the output of the following program?


#include
int main()
{
      int i;
      i = 10;
      printf("i : %d\n",i);
      printf("sizeof(i++) is: %d\n",sizeof(i++));
      printf("i : %d\n",i);
      return 0;
}

reference answer

If you think the output is: 10, 4, 11 respectively. Then you are wrong.

The mistake is in the third one. There is no problem with the first one being 10, and there is no problem with the second one being 4, because an int has 4 bytes on a 32-bit machine. But why is the third output not 11? It's still 10? The reason is that sizeof is not a function, but an operator, which calculates the size of the type of i++, which can be completed before the program runs (at compile time), so sizeof(i++) is directly replaced by 4 , there will be no i++ expression at runtime.

What is the output value of the following program?

#include
#include

#define SIZEOF(arr) (sizeof(arr)/sizeof(arr[0]))
#define PrintInt(expr) printf("%s:%d\n",#expr,(expr))

int main()
{
/* The powers of 10 */
      int pot[] = {
      0001,
      0010,
      0100,
      1000
      };

      int i;
      for(i=0;i<SIZEOF(pot);i++)PrintInt(pot[i]);
      return 0;
}

reference answer

If you have problems with the PrintInt macro, you can take a look at the documentation. However, the problem in this example is not here, the output of this example will be: 1, 8, 64, 1000. In fact, it is very simple. In C/C++, numbers starting with 0 are octal.

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 lies in "y = y/*p;", we originally thought "y / (*p)", however, we did not add spaces and brackets, the result "/ in "y/*p" *" is interpreted as the start of a comment. So, this is also the beginning of the whole nightmare.

What is the output below?

#include
int main()
{
      int i = 6;
      if( ((++i < 7) && ( i++/6)) || (++i <= 9));
      printf("%d\n",i);
      return 0;
}

reference answer

This question is not simply about prefix ++ or inverse ++. This question mainly focuses on the short-circuit evaluation of && and ||.

The so-called short-circuit evaluation: For (condition 1 && condition 2), if "condition 1" is false, then the expression of "condition 2" will be ignored. For (condition1 || condition2), if "condition1" is true, the expression of "condition2" is ignored.

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

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


#include
int main()
{
      int a=3, b = 5;
      printf(&a["Ya!Hello! how is this? %s\n"], &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 equivalent:

• "hello"[2]

• 2["hello"]

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

What is the output of the following program? (Assumption: input "Hello, World")


#include
int main()
{
      char dummy[80];
      printf("Enter a string:\n");
      scanf("%[^r]",dummy);
      printf("%s\n",dummy);
      return 0;
}

reference answer

The output for this example is "Hello, Wo". The "%[^r]" in scanf is something that interferes with it, which means that it ends when the character r is encountered.

The following program tries to use "bit operation" to complete the "multiply by 5" operation, but there is a BUG in this program, do you know what it is?

#include
#define PrintInt(expr) printf("%s : %d\n",#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 question is the expression "t = a<<2 + a;" in the function FiveTimes. For the bit operation a<<2, the priority is lower than addition, so this expression becomes "t = a << (2+a)", so we can't get the value we want.

The program is amended as follows:

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

Pay attention to the B station number: Come on Xiaoyu, +q fan group: 725022484

Receive 300G high-quality programming materials for free

Guess you like

Origin blog.csdn.net/yx5666/article/details/129242436