C language is simple, easy to use and flexible, can directly access the physical address, and efficient bit calculation. The generated object file is of high quality and high execution efficiency, but this is relatively speaking, or about 15% lower than assembly language efficiency. Data processing, especially image processing ability, portability is good.

The keyword

ANSI C has 32 keywords and 9 control statements. Make up a doggerel as usual. While signed for return, unsigned case continue default. register goto auto union, do short long struct. void typedef switch extern, volatile char double const. if break static int, enum sizeof else float.

In C99, inline RESTRICT _Bool _Complex _Imaginary is added. Later, C11 added 7 keywords _Alignas _Alignof _Atomic _Static_assert _Noreturn _Thread_local _Generic. All these keywords should be understood. Also know the typical application scenarios.

When you encounter problems, it is very important to ask big gods. It is suggested to chat with this group and discuss with seniors. You will also get a lot of help. Can also exchange learning experience, technical problems, you can get PDF books source code, tutorials and so on for free use

The data structure

C provides users with rich data structures and allows users to customize complex data structures. The data structure provided by C language is presented in the form of data types, which are classified as follows:

Basic types of

Numeric type Character type Enumeration type

Structural type

Array type Structure type Union type

Pointer types

Data can be divided into constants and variables. It is customary to use uppercase letters to represent constants and lowercase letters to represent variables. Value types note the range of numbers. A character constant is a character enclosed in single quotes. Special character constants starting with a “\” are also allowed. An enumerated type is a primitive data type, not a constructed type, because it can no longer be decomposed into any primitive type. In compilation, enumeration elements are treated as constants, so they are called enumeration constants. They are not variables and cannot be assigned. An array is a collection of ordered data. Each element in the array belongs to the same data type, and a unified array name and subscript are used to uniquely determine the elements in the array. A structure is a data structure provided by C language. Its general form is as follows:

Struct name {member list} list of variable names;

In general, macros can be used to obtain the offset within the structure:

#undef offsetofstruct #define offsetofstruct(TYPE, ELEMENT) ((size_t) &((TYPE *)0)->ELEMENT) #endif

Union is also a derived type with the same syntax and structure, except that its members share storage space. A federation defines a set of alternative values that share a block of memory.

The memory address of a variable is called a pointer to that variable, which is the essence of C and is described separately below.

C also provides a variety of operators, including the following 34:

Arithmetic: +, -, /, ++ relations: >, <, ==,! = such as logic, &&, | |,! Such as: > >, < <, ~ assignment: the equal sign (=) and extended the assignment operator (+ =, =, = / =) pointer: *, &

Expressions are formed by concatenating operands with various operators.

Pointer to the

Pointers are at the heart of C, and their flexibility and length derive from Pointers. Pointers provide a mechanism for dynamic memory manipulation, enhanced support for data structures, and hardware access. A pointer is a variable that holds a memory address. When you define a pointer, you must specify the type of variable it points to. Any pointer is a variable of some type. When a pointer is used to access an area of memory to which the pointer points, the type to which the pointer points determines what the compiler will treat the contents of that area of memory as. Note that the type of a pointer (that is, the type of the pointer itself) and the type to which the pointer points are two concepts.

A void pointer is a pointer variable that does not specify which type of data it points to. A void pointer can point to any type of data, and can be assigned to a void pointer directly from any type of pointer. However, if you need to assign the value of a pointer to a pointer of another type, a cast is required. Const precedes the type of a pointer definition statement to indicate that the object to which it points is a constant.

A pointer variable can point to another pointer, a pointer to a pointer. Function code in the program also occupies memory space. Each function has an address, so Pointers can also point to functions. Pointers to function addresses are called function Pointers. In short, there is no limit to what Pointers can point to. They can be variables, array elements, dynamically allocated memory blocks, and functions. Correctly understand pointer and function pointer declarations, such as :(void () ()) 0) (); Note the difference between *p() and (*p)(). The former means that the function returns a pointer type and the latter means that p is a pointer to the function.

Typical use of Pointers: direct access to system memory

Reference function

Construct chained data structures

Reference dynamically allocated data structures

Implementing a reference call

Passing array parameters

Access and iterate over data elements

Stand for string

Alias as other values

function

A large program can be divided into several small program modules, each module used to implement a specific function, this module is called a function. A C program may consist of a main function and several subfunctions. The main function calls other functions, and other functions can also call each other. The same function can be called any number of times by one or more functions.

From the user’s point of view, functions can be divided into library functions and custom functions. From the function itself, can be divided into two parameters and no parameters. During parameter passing, values and addresses are passed as needed, that is, parameters and arguments. The parameter in a function is allocated a memory unit only when a function call occurs. At the end of the call, the memory unit occupied by the parameter is also freed.

The function should be defined before it is called in the same file, otherwise the default return value is an integer. If the calling function is not in the same file as the called function, and the return value type is different, an error will be reported. If the parameters of the called function include types such as char, short, float, etc., the function must be declared in the file in which the function is called, with the parameter types enclosed in parentheses.

In essence, function notation is pointer notation, where the function name is evaluated to the address of the function, and function parameters are passed to the function.

A program stack is an area of memory that supports the execution of functions, usually shared with the heap, including the return address, local data store, parameter store, and stack and base Pointers (Pointers to the runtime management stack). When creating a stack frame, the system pushes the parameters to the frame in the reverse order of the declaration, and finally pushes the local variables.

Potential problems when returning Pointers from functions:

Returns an uninitialized pointer Returns a pointer to an invalid address Returns a pointer to a local variable returns a pointer but does not free memory Function Pointers can execute functions in an order not determined at compile time.

Void (*foo)() be careful when using function Pointers, as C does not check that arguments are passed correctly, and FPTR is recommended as a prefix. An array of function Pointers can select functions to execute based on certain criteria. A pointer passing a pointer allows the parameter pointer to point to a different memory address.

Memory storage

There are four storage types in C:

1. Auto can only be used to identify the storage type of local variables. For local variables, auto is the default storage type and no display declaration is required. Therefore, variables identified by auto are stored in the stack area.

2. Extern is used to declare global variables. If the global variable is not initialized, it will be stored in the BBS area and will automatically be assigned a value of 0 at compile time. If it has been initialized, it will be stored in the data area. A global variable, whether initialized or not, is initialized throughout the program’s lifetime. To save memory, extern is not allocated to a global variable defined in another file if it is declared in the current file.

3. After the variable of register is transferred from memory to CPU register, it will be resident in CPU register. Therefore, register will improve efficiency to a large extent, because it saves multiple instruction cycles in the process of variable transfer from memory to register.

Static is stored in the data area and its life cycle is the entire program. If it is a static local variable, its scope is a pair of {}, if it is a static global variable, its scope is the current file. Static variables that are not initialized are automatically initialized to 0. Static variables can only be initialized once.

When using memory, the requisition and the release should be paired. After the release, the pointer should be null. There are three common memory usage problems:

Wild pointer: after Free, the pointer is not null and continues to be used. Memory leak: Memory is not released after the application. Overflow: array index and memory access overflow

To avoid memory overrunning, it is necessary to check the valid value of the index of the array. The best string operation API should contain N, such as strncpy, strncat, etc. The size of the memory copy should be checked to avoid wild Pointers.

If conditions permit, you can implement your own memory pool management by cutting the memory pool in bytes (for example, an integer multiple of 8 bytes). For each allocated memory address space, special values are initialized at the start and end locations, and then a separate thread is used to scan every valid block in the memory pool at short intervals to defragment the memory.

When allocating space to store strings dynamically (malloc), remember that the string needs to be allocated an extra byte to hold the string ending ‘\0’.

compile

The C compilation process includes precompilation, parsing, code generation, optimization, assembly, and connection. The precompiler performs macro replacement, lexical analysis, and symbol table creation. Parsing involves semantic analysis, creating syntax trees. The code generator generates intermediate code, the optimizer takes care of instruction optimization, the assembler generates assembly code, and finally the linker generates object files and executables. The connector checks for the names of external objects in the target module and adds them to the loading module if there are no name conflicts.

Functions and initialized global variables (including initialized to 0) are strong symbols, and uninitialized global variables are weak symbols. The notation means that all reads and writes to the same name refer to the same block of memory, even though they are scattered in different.o files. For them, the following three rules are used:

There can only be one strong symbol with the same name, otherwise the compiler will report a “double definition” error. One strong symbol and multiple weak symbols are allowed, but the definition will select the strong symbol. When multiple weak symbols are the same, the linker selects the one that takes up the most memory.

Remember that the comparison operator == should not be miswritten as assignment symbol = and vice versa, which are quite different. Lexical analysis uses the greedy method from left to right, for example, a– b is equivalent to a– b, but not equivalent to a– b;

Precompilation usually in the C compilation system before the program is compiled, some special commands in the program are first “preprocessed”, and then the preprocessed results and source program are compiled together to get the object code, and the line starting with “#” becomes the preprocessor instruction.

Parameterized macros are very similar to functions in that they refer to functions as arguments in parentheses after the function name and require the number of arguments equal to the number of parameters, but there are differences:

Parameters are used differently. When a function is called, the argument expression is evaluated, and then the parameter is substituted. Macros do simple character substitution only. The processing mechanism is different. Function calls are processed while the program is running and memory is allocated; Macro expansion takes place at compile time, no memory units are allocated, no value passing occurs, and no value is returned

The requirements are different. When a function is defined, both arguments and parameters are defined as types. The macro – definition – free preprocessor provides conditional compilation. Different parts of the program can be compiled according to different conditions, resulting in different object code files, which is very useful for program transplantation and debugging. Conditional compilation takes three forms:

Codes1 #else codes2 #endif #ifdef codes3 #endif # ifNdef codes4 #else codes5 #endif

Header files Generally, library functions are invoked through header files. In many cases, source code is inconvenient (or not allowed) to be released to users, as long as headers and binary libraries are provided to users. Users only need to invoke library functions according to the interface declaration in the header file, regardless of how the interface is implemented. The compiler extracts the corresponding code from the library. Header files also enforce type safety checks. If an interface is implemented or used in a way that is inconsistent with the declaration in the header file, the compiler will point out the error. This simple rule can greatly reduce the burden of debugging and fixing errors.

Header files introduced with Angle brackets are looked up in the containing directory (which is set by the user when setting up the environment), not in the source directory. Double quotation marks are used to indicate that the file is searched in the current source directory. If it is not found, the file is searched in the included directory. During programming, users can select a command form according to the directory where their own files reside.

C programming framework is composed of header files, variable declarations, main functions and subfunctions. The ubiquitous helloWord in C looks like this:

#include
int main(a)
{
printf("Hello, World! \n");
return 0;
}
Copy the code

There are no variable declarations or subfunctions. Is it ok to have no main function? Or, instead of calling it main, is it okay to call it something else? This involves compilation specification, and main is the default call entry in C.

Most of those libraries in C have no main function. C language libraries are divided into static library (. A) and dynamic library (. So).

A static library is actually a collection of object files for the connector generation executable phase. The linker copies the code used in the function from the library file into the application, and once the connection is complete and the executable is generated, the static library is not required to execute the program. Dynamic libraries, also known as shared libraries, simply mark programs when they link, and then load the required libraries (modules) dynamically when the program starts running.

There are various implementations of the C standard library, including glibc, the most famous, uClibc for embedded Linux, and ARM’s own C standard library. Different libraries have different implementations and provide different functions, but there is a minimal subset that they all support, which is the most typical C library.

The C library consists of functions, type definitions, and macros declared in 15 header files, each representing a range of programming capabilities. It is said that the C standard library can be divided into three groups, and how to use them correctly and skillfully can distinguish three levels of programmers:

H > <locale.h> <setjmp.h> <signal. H > <stdarg.h>

In the C runtime data structure, the stack provides storage space for local variables, restore information for function calls, and temporary storage for calculating complex arithmetic expressions. Call records support procedure calls and record all the information needed to return to the call point after the call; Global variables include static variables, constants, etc.

BSS segment

Usually an area of memory used to hold uninitialized global variables in a program. The BSS segment is a static memory allocation.

A data segment is usually an area of memory used to store initialized global variables in a program. The data segment is a static memory allocation.

A code segment is usually an area of memory used to store the code that a program executes. The size of this area is determined before the program runs, and memory areas are usually read-only. Some architectures also allow code segments to be writable, that is, to modify the program. It is also possible to include read-only constant variables, such as string constants, in a code snippet. A program segment is an in-memory mapping of program code.

The heap is used to store memory segments that are dynamically allocated during the running of a process. Its size is not fixed and can be dynamically expanded or shrunk. When a process calls functions such as malloc/free to allocate memory, newly allocated memory is dynamically added to the heap (the heap is expanded)/freed memory is removed from the heap (the heap is shrunk).

A stack, also called a stack, holds local variables of a program (except variables declared static, which means that variables are stored in a data segment). In addition, the stack is used to pass parameters and return values when the function is called. Because of the first-in, first-out nature of the stack, it is particularly convenient to save/resume the call scene. Before entering the main function, the program has completed the allocation and initialization of data in memory, including data area, stack area and so on. This part of the code is not visible to developers and is part of the C standard runtime.

The stack plays an important role as a function is pushed and unloaded in the process of being called and called. Local variables, parameters, and return values of a function are stored in the stack area. After the function ends, the stack area is automatically released. The stack area acts as a temporary storage, which is a mechanism for the computer to utilize the memory space. It is not enough to understand the spatial distribution of the C runtime. It is better to understand how a compiled code is run and how functions in the library are linked to object code, especially the maintenance of a list of Pointers to functions, to have a feeling of complete control over the code.

Not a summary summary

C language not only can let us understand the related concepts of programming, also can let us understand the program works, for example, how the subsystems of the computer interaction, the program in memory is a kind of what kind of, the operating system and application “love/hate”, between these underlying knowledge will be great help for the programmer’s career.

C, hailed by some as the “language of God,” almost laid the foundation for the software industry and created many other languages. However, in view of the level is limited, it is difficult to lift heavy burdens lightly, the basic description in this article is just old code farmer’s broken words.

It is also very important to ask big gods when you encounter problems.I suggest joining this group to chatYou will also get a lot of help if you discuss with your predecessors. Can also exchange learning experience, technical problems, you can get PDF books source code, tutorials and so on for free use