1. C language comments
In C, if you need to comment out a piece of code that may already exist in the/***/annotation form, you can use:
# If 0
Statements
# Endif
Comment out this code in this form (statements represents this code ). The reason for this is that the C language does not allow nested comments. That is to say, the content between the first/* and the first */symbol is regarded as comments, no matter how many/* symbols are in it.
2. Handling line breaks
# Include <stdio. h>
Int main ()
{
Int CH, I;
Ch = getchar ();
I = getchar ();
Printf ("% d \ n", CH, I );
Return 0;
}
Enter: A + enter key
What is the output?
Analysis: When we use the getchar () function to receive one character, we need to enter at least one character (unless only one enter key) and one enter key on the keyboard, in this way, the user typed two characters on the keyboard, that is, a real character and a line break (the ASCII code is 10 and the character is '\ n '). In this case, the output will output the ASCII code of A and the ASCII code of the line break. This is precisely because of this situation. If we need to receive the characters entered by the user from the keyboard, We need to automatically clear the line breaks behind them in the program, prevent this line break from being contaminated with the next input. The following is an example:
# Include <stdio. h>
Int main ()
{
Int CH, CA, CB;
Scanf ("% d", & Ch );
Scanf ("% d", & Ca );
CB = getchar ();
Printf ("% d \ n", CH, CA, CB );
Return 0;
}
Input: 12 + press ENTER + 34 + press Enter. What is the output value?
Analysis: the output is 12 34 10. The reason is similar to the preceding one, but scanf is intelligent. When receiving input, it will automatically match the type of the next input in stdin. When matching is received, it will receive, and if it does not match, it will be discarded, therefore, 34 can still be correctly received, but the last line break (generated by hitting the Enter key on the keyboard) will remain in stdin, so the getchar () function will finally receive CB.
3. note when reading characters
A common question is: Why is Ch declared as an integer and we actually need to use it to read characters (this should be especially noted when reading characters from the file )? The answer is that EOF is an integer value, which has more digits than the character type. Declaring ch as an integer can prevent the characters read from the input from being accidentally interpreted as EOF. At the same time, this means that the ch of the receiving character must be large enough to accommodate the EOF, Which is why ch uses an integer value. Characters are only small integers, so using an integer variable to hold character values does not cause any problems.
4. Three-letter words and escape characters
The C standard defines several three-letter words, which are the sequences of several characters and together represent another character. The three-letter word enables the C environment to be implemented in certain character sets without some necessary characters. The three-letter words and the characters they represent are listed here:
?? ([?? <{?? = #
??) ] ???> }?? /\
??! | ?? '^ ?? -~
For example, printf ("??) "); A] symbol is output.
Escape characters:
\? Use it when writing consecutive question marks to prevent them from being interpreted as three-letter words.
\ "Is used to indicate the double quotation marks inside a String constant.
\ 'Is used to represent character constants '.
\ Is used to indicate a backslash to prevent it from being interpreted as an escape character.
5. ANSI rules on data type size
Rules for the size of integers: A long integer must be at least the same length as an integer, and an integer must be at least the same length as a short integer.
Floating point size rules: Long Double must be at least the same length as double, while double must be at least the same length as float.
6. variable scope
The compiler can identify four different scopes: File Scope, function scope, code block scope, and prototype scope. The location of the identifier declaration determines its scope.
>>> Code block Scope
All statements between a pair of curly braces are called a code block. All variables 5, 6, 7, 9, and 10 in the code block scope. The form parameter 5 of the function also has the code block scope inside the function body. In addition, F declared in '9' is different from F declared in '6'. f declared in '9' is hidden in curly brackets.
>>> File Scope
Any identifier declared outside of all code blocks has a file scope, which indicates that these identifiers are accessible from where they are declared until the end of the source file. In 1 and 2, there is a file scope, and the function name defined in the file also has a file scope, because the function name itself does not belong to any code block, SO 4 also has a file scope.
>>> Prototype Scope
The prototype scope is only applicable to parameter names in the function prototype declaration, with 3 and 8 in this scope. In the prototype, the parameter name is not required.
>>> Function Scope
It is only applicable to statement labels, and statement labels are used for goto statements. Basically, the function scope can be simplified to a rule-all statement labels in a function must be unique.
7. Link Properties
There are three Link Attributes: external (external), internal (internal), and none (none ). The identifier (none) without a link property is always treated as a separate individual, that is, multiple declarations of the identifier are treated as independent entities. The identifier that belongs to the internal link attribute refers to the same entity in all declarations in the same original file, but multiple declarations in different source files belong to different entities. Finally, the identifier that belongs to the external link attribute represents the same object no matter how many times the object is declared and located in several source files.
Function Name and external variable default link attribute are external, while local variable default link attribute is none. Both the keyword extern and static are used to modify the link attribute of the identifier in the declaration. If a declaration has the external link attribute normally, adding the static keyword before it can change its link property to internal. Static changes the link property only when the default link property is external. The rule of the extern keyword is more complex. Generally, it specifies the external link attribute for an identifier so that you can access the entity defined at any other position. Example:
Static int I;
Int func ()
{
Int J;
Extern int K;
Extern int I;
......
}
Analysis: extern int K; this statement indicates that the subsequent part of the function can access the K variable entity defined in other source files. When the extern keyword is used for the first declaration of an identifier in the source file, it specifies that the identifier has the external link attribute. However, if it is used for the 2nd or later Declaration of the identifier, it does not change the link attributes specified by the 1st declaration. Therefore, the extern int I; statement does not modify the static attribute of I.
8. array name
In C, in almost all expressions using arrays, the value of the array name is a pointer constant, that is, the address of the first element of the array. Only in two cases, the array name is not a pointer constant: it is used as the calculation object of the sizeof operator; it is used as the operand of the single object operator.
9. pointer and subscript
Subscripts are never more efficient than pointers, but pointers are sometimes more efficient than subscripts.
Example 1:
Int array [10],;
For (A = 0; A <10; A ++)
Array [a] = 0;
To evaluate the subscript expression (array [a]), the compiler inserts an instruction in the program to obtain the value of A and multiply it by the length of the integer, this multiplication takes a certain amount of time and space. Let's look at the pointer format:
Int array [10], * AP;
For (AP = array; AP <array + 10; AP ++)
* Ap = 0;
Although there is no subscript here, there is still a multiplication operation. The value 1 must be multiplied by the length of the integer type and then added to the pointer. However, there is a major difference: each time a loop is executed, two identical numbers (1 and 4) are executed for multiplication ). The result of this multiplication is only executed once during compilation -- the program now contains an instruction to add 4 to the pointer. The program does not perform Multiplication During running. But the following two sections of code:
A = get_value ();
Array [a] = 0;
A = get_value ();
* (Array + a) = 0;
The code generated by the two sets of statements is no different. A may be any value and can be known at runtime. Therefore, both solutions require multiplication commands to adjust. This example shows that the pointer is the same as the lower mark.
10. Further Optimization of pointers
Void try1 ()
{
For (p1 = x, P2 = y; p1-x <size ;)
* P1 ++ = * P2 ++;
}
● This Code uses p1-x <size as the end point, but this judgment will be processed as division, because the value of the p1-x is a pointer operation, the difference value must be divided by the size of a type. This actually takes a long time.
Void try2 ()
{
For (I = 0, P1 = x, P2 = y; I <size; I ++)
* P1 ++ = * P2 ++;
}
● This code re-uses the counter to control loop exit, which can eliminate division and shorten the length of the compiled code. But like the above Code, during code execution, P1 and P2 are generally re-copied to other registers before the operation starts.
Void try3 ()
{
Register int * P1, * P2;
Register int I;
For (I = 0, P1 = x, P2 = y; I <size; I ++)
* P1 ++ = * P2 ++;
}
● The optimization of this Code is to declare P1 and P2 as register variables, so that the steps for copying P1 and P2 values to other registers can be reduced after compilation.
Void try4 ()
{
Register int * P1, * P2;
For (p1 = x, P2 = y; P1 <& X [size];)
* P1 ++ = * P2 ++;
}
● & X [size] will be evaluated during compilation (because size is a numerical constant). This Code further removes counter I, and the compiled code is quite compact, almost the same efficiency as assembly code. This is also a convenient embodiment of the C language asymmetric boundary and the programming without checking the array boundary.
Sort out C and pointer 1