With the previous foundation, this article only records some things that have not been noticed before and are worth learning.
Chapter 1
The author thinks that using # if 0... # endif is better than using/* and */, because the latter cannot be nested. However, it is not described.
Chapter 2
Three-letter word, with two question marks plus one symbol to represent another, is similar to the escape character. After reading some documents, its usage is related to the compiler and you can understand it to prevent the interpretation of string constants from being incorrect.
Copy codeThe Code is as follows :?? (==> [?? <==> {?? ==> #
??) ==>] ???> ==> }?? /==> \
??! ==>| ?? '=> ^ ?? -==> ~
For nested functions, the author suggests dividing them into several functions, so as not to use too many Tab indentation.
Chapter 3 data
For complex static usage, when it is used for function definition or variable declaration outside the code block, static is used to modify the connection attribute of the identifier, from external to internal, however, the storage type and scope of the identifier are not affected. The declared functions or variables can only be accessed in the declared source files. When it is used for variable declaration inside the code block, static is used to modify the storage type of the variable, from automatic variable to static variable, but the link property and scope of the variable are not affected. Variables declared in this way are created before the program is executed and exist throughout the entire execution period of the program, instead of being created each time the code block starts to be executed and destroyed after the code block is executed.
Chapter 5 Operators and expressions
Shift operation. When the number of digits to be moved is negative, the specific result is related to the compiler or undefined. For example, a <-5 may be shifted to 27 places.
For example, the operation efficiency of a + = 1 is higher than that of a = a + 1. Equivalent a [2*(y-6 * f (x)] = a [2*(y-6 * f (x)] + 1 compared with a [2*(y-6 * f (x)] + = 1, the latter does not need to calculate the subscript repeatedly.
The form of sizeof x is allowed. Sizeof () does not evaluate the expression, so a in sizeof (a = B + 1) is not assigned a value.
Only-> is used to access the members pointing to the structure pointer.
Chapter 6 pointer
Uninitialized pointers may cause errors. Int * a; * a = 12, which modifies the content of the address pointed by a and the result is unpredictable.
Although the return value of NULL pointer is a common technique of C when a search element is not found, it violates the principles of Software Engineering: "It is dangerous to express two different meanings with a single value, because it is easy to find out which one is its true intention in the future ". The security policy returns two values, indicating whether the status value is successful and the element value found when the search is successful.
Chapter 7 Functions
The function prototype declaration without parameters should be written like this: int func (void); the purpose is not to be confused with the old style declaration.
Recursive solutions are clearer than non-recursive solutions. When it is difficult to implement a complex problem in iterative form, the conciseness of recursive implementations can compensate for the overhead it brings. Fibonacci is a common recursive example, but there are a lot of redundant computing and the overhead is too large. In fact, it is not like iterative implementation.
Copy codeThe Code is as follows: iterative Implementation of Fibonacci
Long maid (int n)
{
Long result;
Long previus_result;
Long next_older_result;
Result = previus_result = 1;
While (n> 2 ){
N-= 1;
Next_older_result = previus_result;
Previus_result = result;
Result = previus_result + next_older_result;
}
Return result;
}
Use of the variable parameter list: the header file stdarg. h, which declares a type of va_list and three macros va_start, va_arg, and va_end. Use the va_list type variables with these macros to access the parameter values. The function declares a var_arg variable used to access the undetermined part of the parameter list. It is initialized through va_start. The first parameter is the name of the va_list variable, and the second parameter is the last parameter with a name before the ellipsis. During initialization, The var_arg variable points to the variable parameter section 1st. Va_arg accepts two parameters: va_list and the type of the next parameter in the parameter list. Va_arg returns the parameter value and points var_arg to the next variable parameter. After the access is complete, call va_end.Copy codeThe Code is as follows: # include <stdarg. h>
Float average (int n_values ,...)
{
Va_list var_arg;
Int count;
Float sum = 0;
/* Prepare variable access parameters */
Va_start (var_arg, n_values );
/* Add a value from the variable parameter list */
For (count = 0; count <n_values; count + = 1 ){
Sum + = va_arg (var_arg, int );
}
/* Complete processing of variable parameters */
Va_end (var_arg );
Return sum/n_values;
}
Macros of variable parameters cannot determine the number and type of parameters, which may increase the default parameter type. The solution to these two problems is to use named parameters, that is, there is always a name parameter in the Variable Parameter List.
Chapter 8 array
Int array [10]; int * ap = array + 2; after that, ap [0] is valid in C, which is equivalent to array [2], ap [-1] is also legal, that is, array [1].
When pointers are more efficient than Arrays: ap ++ of the for loop is more efficient than array [a] = 0 in the loop body. The multiplication calculation of the former is only once, 1 is used to multiply the length of the data type, and the latter needs to calculate each time.
Copy codeThe Code is as follows:/* use an array */
Int array [10],;
For (a = 0; a <10; a + = 1)
Array [a] = 0;
/* Use Pointer */
Int array [10], * ap;
For (ap = array; ap <array + 10; ap ++)
* Ap = 0;
The initialization time of an array, especially a large array, may be considerable. Therefore, when the array Initialization is partial to a function or code block, you should consider whether it is worthwhile for the program to reinitialize it each time. If no, declare the array as static.
Use pointers to access multi-dimensional arrays. For example, if the int matrix [3] [10] array is declared as int * mp = matrix, it is incorrect because matrix is not a pointer to an integer, instead, it is a pointer to an integer array. Int (* p) [10] = matrix is acceptable. p points to the first row of matrix and implements row-by-row access to the array. To access each element one by one, use int * pi = & matrix [0] [0] Or int * pi = matrix [0] to point it to the first element. Int (* p) [] = matrix; is incorrect. Its value is adjusted according to the length of the empty array. This error cannot be captured by the compiler. Function parameters are similar.
The multi-dimensional array is initialized explicitly. Only the first dimension can be computed, and other dimensions cannot be omitted.
Chapter 9 strings, characters, and bytes
Exercise caution when using the unsigned number: strlen returns the unsigned number, so if (strlen (x)-strlen (y)> = 0)... is always true. In this case, you should write it as if (strlen (x)> = strlen (y)... or convert it into int using forced type conversion.
Strtok stores the local state information of the function it processes, so it cannot be used to parse two strings at the same time.
The string function ends with a NULL Byte. If you want to process non-string data without this restriction, you can use another set of related functions: memcpy, memmove, memcmp, memchr, and memset.
Chapter 10 structure and Union
Parameters are structured functions, and passing pointers is more efficient than passing values. This is because the latter needs to create a copy of the structure. F (type_struct * s) {s-> x}; the call is f (& s ). If the number of accesses to members of this structure exceeds three times, the declared register variable is more effective. To avoid improper modification, you can declare the parameter as const and assign the return value to the original structure (or one of its members ).
The bit segment is a special structure that specifies the member length.
Chapter 2 advanced pointer topic
The use of callback functions can solve the problem similar to that of unknown data types. This is the first time that callback functions are recognized systematically.
Chapter 4 pre-processor
To eliminate the risk of multiple inclusion, write the following content in each header file:
Copy codeThe Code is as follows: # ifndef _ HEADRNAME_H
# Define _ HEADRNAME_H 1
/* All the stuff that you want in the header file */
# Endif
When _ HEADRNAME_H is included for the first time, it is defined as 1. If it is included again, it is ignored. You can write it as # define _ HEADRNAME_H. However, try to avoid multiple inclusion.
Chapter 4 Input/Output Functions
Freopen is used to open (or re-open) a specific FILE stream. prototype: FILE * freopen (char const * filename, char const * mode, FILE * stream ), the last parameter is the stream to be opened. First, it tries to close the stream, and then re-open the stream with the specified file and mode. If it fails, NULL is returned, and the third parameter is returned.
Ungetc returns the character previously read to the stream so that it can be re-read later. Here is a character processing example in C programming language. When fseek, fsetpos, or rewind changes the stream position, all returned characters are discarded.
The difference between gets and puts and fgets and fputs is that when gets reads a row of input, it is not a line break at the end of the buffer storage. When puts writes a string, it adds a linefeed to the output after writing the string. In addition, gets does not determine the buffer length, which may cause danger.
Feof checks whether the stream is at the end of the file. ferror reports the error status of the stream. clearerr resets the error mark of the specified stream.
Tmpfile creates a temporary file to save data and is deleted when the program ends. The temporary file name is created by tmpnam.
Chapter 1 Standard function library
Volatile is a type modifier designed to modify variables accessed and modified by different threads, preventing the compiler from "optimizing" the program in a way that may modify the meaning of the program.
Vprintf, vfprintf, and vsprintf are used to print the variable parameter list. The function is similar to the corresponding prinft function, but the parameter is a variable parameter list arg.
Getenv gets the environment variable. If it is found, the pointer is used to return the environment variable; otherwise, NULL is returned.
Locale is a set of specific parameters. Each country may be different. The objective is to enhance the universality of C in the world, which is not described in detail.
For Chapter 17 typical abstract data types and the runtime environment in Chapter 18th, the former is familiar, and the latter is closely integrated with the compilation, just a rough look. This book is just over.