A few C pen questions
Q: What are the returned values of printf and scanf?
int main() { int i = 43; int n = printf("%d\n",i); printf("%d\n",n); return 0;}
A: The printf function returns 3 because it outputs three characters: '4', '3', and '\ n.
Printf returns the number of characters that are successfully output to STDOUT. If an error occurs, a negative number is returned.
Scanf returns the number of successfully assigned variables. If an error occurs, EOF
Q: Since fgetc is a character that receives input, the returned value is char or unsigned char. Why is int used?
A: This is mainly because the mark of file termination or file read/write errors is specified as EOF, that is,-1. Unsigned char cannot get the value-1 at all. If char is used as the return value, it cannot distinguish the 0xFF character and EOF because both values are considered as-1 by char, therefore, it cannot be returned.
Q: What does this program want to output all elements in the array but not get the desired result?
#include
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0])) int array[] = {23,34,12,17,204,99,16}; int main() { int d; for(d=-1;d <= (TOTAL_ELEMENTS-2);d++) printf("%d\n",array[d+1]); return 0; }
A: run the above program and there is no output in the result. The reason for this result is that the return value of sizeof is an unsinged int, therefore, when comparing int d and TOTAL_ELEMENTS values, the values are converted to unsigned int for comparison. As a result,-1 is converted into a very large value, so that the for loop does not meet the conditions. Therefore, if the sizeof operator returns an unsigned int, ambiguity similar to the preceding occurs.
Q: The output result of the following program is:
#include
#define f(a,b) a##b #define g(a) #a #define h(a) g(a) int main() { printf("%s\n", h(f(1,2))); printf("%s\n", g(f(1,2))); return 0; }
A: In the macro of C language, # is used to stringize the macro parameters following it (Stringfication ). # Is called a concatenator to connect two tokens into one.
When you see this program, you may think that the two printf outputs the same result, but the answer is not like this. The output of this question is 12 and f (1, 2). Why? Because this is a macro, the unlocking of the macro is not from the inside out as the function execution. # Replace the parameter on the right with the overall string. Even another macro is not expanded. Therefore, g (f (1, 2)-> "f (1, 2 )". For h (f (1, 2), since h (a) is a non-# Or # normal macro, You need to first expand its parameter a, that is, expand f (1, 2) to 12, then, the h (a) macro is replaced with h (12), the macro is replaced with g (12), and the macro is replaced with "12 ".
Q: If our a address is 0Xbfe2e100 and it is a 32-bit server, what will this program output?
#include
int main(){ int a[5]; printf("%x\n", a); printf("%x\n", a+1); printf("%x\n", &a); printf("%x\n", &a+1); return 0;}
A:
The first printf statement is bfe2e100.
The second printf statement may be bfe2e101. That's wrong. a + 1, the compiler will compile it into a + 1 * sizeof (int). int Is 4 bytes in 32 bits, so it is added with 4, that is, bfe2e104.
The third printf statement may be your biggest headache. How do we know the address of? Don't I know? Or bfe2e100. Isn't it a = &? How is this possible? Save your own? Maybe many people think that pointers and arrays are the same thing, so you are wrong. If it is int * a, there is no problem, because a is a pointer, so & a is the pointer address, a and & a are different. But this is an array. a [], so & a is actually compiled into & a [0].
The fourth printf statement is natural, that is, bfe2e104. Or not, because & a is an array and is considered as int (*) [5], so sizeof (a) is 5, that is, 5 * sizeof (int ), that is, bfe2e114.
Q: Why is the result of the following code always incorrect?
#include
int main(){ int a = 2; if(a & 1 == 0) printf("a & 1 == 0"); else printf("a & 1 != 0"); return 0;}
Why output "a & 1! = 0 "?
A: This is because = has A higher priority than the bitwise AND operator &. therefore, the actual code for a & 1 = 0 is a & (1 = 0), that is, a & 0. Of course, the result is not as expected. (Priority: = and! = Higher than & higher than ^ | higher than & higher than | ). Priority from high to low: Arithmetic Operators, displacement operators, Relational operators, bit Operations & ^ |
Q: What is the output of the following code?
int main(){ int i = 6; if( ((++i < 7) && ( i++/6)) || (++i <= 9)); printf("%d\n",i); return 0;}
A: 8. This question mainly deals with the short-circuit evaluation of & |. 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.
Q: sizeof can be followed by an expression. The code below shows why I ++ is invalid?
#include
int main(){ int i = 1; sizeof(i++); printf("%d\n", i); return 0;}
Running result: 1
A: Because sizeof is the value of the compilation period, if it is followed by the expression, the expression is not calculated, but the type of the basic expression gets the space it occupies.
Q: 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\n",#expr,(expr))int FiveTimes(int a){ int t; t = a<<2 + a; return t;}int main(){ int a = 1; PrintInt(FiveTimes(a)); return 0;}
A: The problem 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: "t = (a <2) + ;"
Q: Why is the final result of bitwise operator operation inconsistent with expectation in the following code?
#include
int main(){ unsigned char c = 0xfc; unsigned int i = ~c; printf("%x\n",i); return 0;}
Running result: 0xffffff03
According to the above Code ,~ C should get 0x03, so the result should be 0x03. How can it be the above result?
A: This is because bitwise operations are upgraded to integer operations. The above variable c is unsigned, in progress ~ During bitwise operation, it is first upgraded to an integer, that is, 0x000000fc, and then obtained 0xffffff03 through the inverse operation. Therefore, the value obtained by I is this. Similarly, if c is of the char type, the integer value is 0 xfffffffc, And the inverse value is 0x03. In fact, the variable is promoted in many ways. For example, when short is computed, It is upgraded to int before continuing the calculation.
Q: What are the following errors or effects after the program is executed:
#define MAX 255int main(){ unsigned char A[MAX]; unsigned chat i; for (i = 0; i <= MAX; i++) A[i] = i;}
A: MAX = 255, the subscript range of array A is: 0 .. MAX-1, subscript out of bounds. When I cyclically reaches 255, A [255] = 255 is executed in the loop. This statement is correct but returns for (I = 0; I <= MAX; I ++) statement, because the value of the unsigned char is in the range of [0,255], I ++ is 0 again, and the infinite loop goes on.
Note: char is a byte with a value range of [-128,127] and unsigned char with a value range of [0,255].
Q: There are two integer variables, a and B. You don't need to use "if", "? : "," Switch ", or other judgment statements. How can we get the big and small ones?
A: Major: (a + B) + abs (a-B)/2
Minor: (a + B)-abs (a-B)/2
Q: Define a macro to compare the sizes of two numbers a and B. The statements greater than, less than, and if cannot be used.
A: You can determine the two symbols after the subtraction, and the 32-bit integer minus the symbol bit:
#define MAX(a,b) ((((a)-(b))&(1<<31))?(b):(a))
Q: Define a macro and calculate the offset of a variable in a struct to struct.
A:#define OFFSET(struct, member) ((unsigned int)&((struct *)0)->member)
Q: calculate the number of K to the power of 2, which is the smallest of not less than x:
int pow2_ceil(unsigned int x){ x--; x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; x++; return x;}
Flexible bit operations can effectively improve the efficiency of program running:
1. Set bit5 of x to 1, and the other BITs remain unchanged: x |=( 1 <5 );
2. Set bit5 of x to 0, and the other BITs remain unchanged: x & = ~ (1 <5 );
3. Determine if bit5 of x is 1 (x & (1 <5 ))! = 0? 1:0;
4. Determine if a number is an even number: (num & 1) = 0? 1:0;
The role of the volatile keyword in C: a variable defined as volatile may be changed unexpectedly, so that the compiler will not assume the value of this variable. Precisely, the optimizer must carefully re-read the value of this variable every time when using this variable, rather than using the backup stored in the register.
The following are examples of volatile variables:
1). Hardware registers of parallel devices (for example, Status Registers)
2). Non-automatic variables that will be accessed in an interrupt service subroutine (Non-automatic variables, automatic variables are auto or register variables)
3) variables shared by several tasks in a multi-threaded application: the volatile keyword tells the compiler not to hold temporary copies of variables. Please refer to the following situation: thread A copies the variable into the Register, and then enters the loop. It checks whether the value of the Register meets certain conditions repeatedly. It expects the value of the variable to be changed by line B. In this case, when the B thread changes the value of the variable, the changed value does not affect its value in the register. So thread A enters an endless loop.