8000 Words! Essential Knowledge of Data Storage and Program Writing in C Language for Microcontrollers!

8000 Words! Essential Knowledge of Data Storage and Program Writing in C Language for Microcontrollers!

Article Word Count: 8000 Content Quality Index:⭐⭐⭐⭐⭐

01Five Major Memory Areas

The memory is divided into five areas: heap, stack, free storage area, global/static storage area, and constant storage area.

1. Stack Area: FIFO refers to the storage area for variables allocated by the compiler when needed and automatically cleared when not needed. The variables inside are usually local variables, function parameters, etc.

2. Heap Area: This refers to memory blocks allocated by new, which the compiler does not manage for release; it is controlled by our application. Generally, one new corresponds to one delete. If the programmer does not release it, the operating system will automatically reclaim it after the program ends.

3. Free Storage Area: This refers to memory blocks allocated by malloc, etc. It is very similar to the heap, but it ends its life with free.

4. Global/Static Storage Area: Global variables and static variables are allocated in the same memory area. In earlier C languages, global variables were divided into initialized and uninitialized; in C++, this distinction no longer exists, and they occupy the same memory area.

5. Constant Storage Area: This is a special storage area that contains constants that cannot be modified (of course, you can modify them through improper means, and there are many methods).

Memory is mainly divided into code segment, data segment, and stack. The code segment contains program code and belongs to read-only memory. The data segment stores global variables, static variables, constants, etc. The heap stores variables created by malloc or new, while other variables are stored in the stack. The space between the heap and stack is variable. The memory of the data segment will be released only after the program execution is complete. When calling a function, the entry address of the function is first found, then space is allocated in the stack for the function’s parameters and temporary variables, a copy of the actual parameters is passed to the formal parameters, and then a push operation is performed. After the function execution is complete, a pop operation is performed. Character constants are generally placed in the data segment, and the same character constant will only be stored once.

02Storage Areas of C Language Programs

1. The C language code (text file) forms an executable program (binary file) through three stages: compilation, assembly, and linking. The compilation process generates assembly programs from C language text files, the assembly process generates binary machine code from assembly programs, and the linking process combines the binary machine code files generated from various source files into one file.

2. Programs written in C language, after compilation and linking, will form a unified file composed of several parts. During program execution, several other parts will also be generated, each representing different storage areas:

1) Code Segment (Code or Text)

The code segment consists of the machine code executed in the program. In C language, the execution of program statements after compilation forms machine code. During program execution, the CPU’s program counter points to each machine code in the code segment and is executed sequentially by the processor.

2) Read-Only Data Segment (RO Data)

The read-only data segment contains some data used by the program that will not be changed. The use of this data is similar to table lookup operations. Since these variables do not need to be changed, they can simply be placed in read-only memory.

3) Initialized Read-Write Data Segment (RW Data)

Initialized data refers to variables declared in the program that have initial values. These variables need to occupy storage space and must be located in a readable and writable memory area during program execution, with initial values for reading and writing during program operation.

4) Uninitialized Data Segment (BSS)

Uninitialized data refers to variables declared in the program but not initialized. These variables do not need to occupy storage space before the program runs.

5) Heap

Heap memory only appears during program execution and is generally allocated and released by the programmer. In the presence of an operating system, if the program does not release it, the operating system may reclaim memory after the program (e.g., a process) ends.

6) Stack

Stack memory only appears during program execution. Variables used inside functions, function parameters, and return values will use stack space, which is automatically allocated and released by the compiler.

8000 Words! Essential Knowledge of Data Storage and Program Writing in C Language for Microcontrollers!

3. The code segment, read-only data segment, read-write data segment, and uninitialized data segment belong to static areas, while the heap and stack belong to dynamic areas. The code segment, read-only data segment, and read-write data segment will be generated after linking, while the uninitialized data segment will be allocated during program initialization, and the heap and stack will be allocated and released during program execution.

4. C language programs are divided into image and runtime states. The image formed after compilation and linking will only contain the code segment (Text), read-only data segment (RO Data), and read-write data segment (RW Data). Before the program runs, the uninitialized data segment (BSS) will be dynamically generated, and during program execution, the heap (Heap) area and stack (Stack) area will also be dynamically generated.

1. Generally, in static image files, each part is called a section, while in runtime, each part is called a segment. If not detailed, they are collectively referred to as segments.

2. After compilation and linking, the C language will generate the code segment (TEXT), read-only data segment (RO Data), and read-write data segment (RW Data). At runtime, in addition to the above three areas, there will also be uninitialized data segment (BSS) area, heap (heap) area, and stack (Stack) area.

03Segments of C Language Programs

1. Classification of Segments

Each target code generated from a source program will contain all the information and functions that the source program needs to express. The generation of each segment in the target code is as follows:

1) Code Segment (Code)

The code segment is produced by each function in the program, and each statement in the function will ultimately be compiled and assembled into binary machine code.

2) Read-Only Data Segment (RO Data)

The read-only data segment is produced by the data used in the program. The characteristic of this part of the data is that it does not need to be changed during execution, so the compiler will place the data in the read-only part. Some syntax in C language will generate read-only data segments.

2. Read-Only Data Segment (RO Data)

The read-only data segment (RO Data) is produced by the data used in the program. The characteristic of this part of the data is that it does not need to be changed during execution, so the compiler will place the data in the read-only part. The following situations will generate read-only data segments.

1) Read-Only Global Variables

Defining a global variable const char a[100] = “abcdefg” will generate a read-only data area of size 100 bytes, initialized with the string “abcdefg”. If defined as const char a[] = “abcdefg”, without specifying the size, it will generate 8 bytes of read-only data segment based on the length of the string “abcdefg”.

2) Read-Only Local Variables

For example: defining a variable const char b[100] = “9876543210” inside a function; its initialization process is the same as that of global variables.

3) Constants Used in the Program

For example: using printf(“informationn”), which contains the string constant, the compiler will automatically place the constant “informationn” in the read-only data area.

Note: In const char a[100] = {“ABCDEFG”}, 100 bytes of data area are defined, but only the first 8 bytes (7 characters and the terminating character ‘0’) are initialized. In this usage, the actual remaining bytes are uninitialized, but they cannot be written in the program, and are actually of no use. Therefore, in the read-only data segment, it is generally necessary to do a complete initialization.

3. Read-Write Data Segment (RW Data)

The read-write data segment represents a part of the target file that can be read and written. In some cases, they are also referred to as initialized data segments. This part of the data segment and code, like the read-only data segment, belongs to the static area of the program but has specific characteristics.

1) Initialized Global Variables

For example: defining a global variable char a[100] = “abcdefg” outside of functions.

2) Initialized Local Static Variables

For example: defining static char b[100] = “9876543210” inside a function. Data and arrays defined with static in the function will be compiled into the read-write data segment.

Explanation:

The characteristic of the read-write data area is that it must be initialized in the program. If there is only a definition without an initial value, it will not generate a read-write data area but will be defined as an uninitialized data area (BSS). If a global variable (defined outside of functions) is added with the static modifier, written as static char a[100], it indicates that it can only be used internally in the file and cannot be used by other files.

4. Uninitialized Data Segment (BSS)

The uninitialized data segment is commonly referred to as BSS (Block Start by Symbol). Similar to the read-write data segment, it also belongs to the static data area. However, the data in this segment has not been initialized. Therefore, it will only be marked in the target file and will not actually be a segment in the target file; this segment will be generated during the initialization phase of execution. The size of the uninitialized data segment will not affect the size of the target file.

In C language programs, attention should be paid to the following issues regarding variable usage:

1) Variables defined within the function body are usually on the stack and do not need to be managed in the program; they are handled by the compiler.

2) Memory allocated by functions such as malloc, calloc, realloc is on the heap, and the program must ensure to free it after use; otherwise, memory leaks will occur.

3) All variables defined outside of function bodies are global variables, and variables with the static modifier, whether inside or outside of functions, are stored in the global area (static area).

4) Variables defined with const will be placed in the program’s read-only data area.

Explanation:

In C language, static variables can be defined: static variables defined within the function body are only valid within that function; static variables defined outside of all function bodies can only be used within that file and cannot be used in other source files; global variables without the static modifier can be used in other source files. These distinctions are concepts of compilation; if variables are not used as required, the compiler will report an error. Both static and non-static global variables will ultimately be placed in the program’s global area (static area).

04Usage of Segments in Programs

The global area (static area) in C language actually corresponds to the following segments:

Read-Only Data Segment: RO Data

Read-Write Data Segment: RW Data

Uninitialized Data Segment: BSS Data

Generally, directly defined global variables are in the uninitialized data area. If the variable is initialized, it is in the initialized data area (RW Data). Adding the const modifier will place it in the read-only area (RO Data).

For example:

const char ro[] = “this is a readonly data”; // read-only data segment, cannot change the contents of the ro array, ro is stored in the read-only data segment.

char rw1[] = “this is global read-write data”; // initialized read-write data segment, can change the contents of the rw1 array. This is because the value is assigned, not the address of “this is global read-write data” given to rw1; the value of char rw1[] = “this is global read-write data”; // initialized read-write data segment, can change the contents of the rw1 array. This is because the value is assigned, not the address of “this is global read-write data” given to rw1; the value of the string constant is stored in the read-only data segment.

char bss_1[100]; // uninitialized data segment

const char *ptrconst = “constant data”; // “constant data” is placed in the read-only data segment, cannot change the value in ptrconst because it is an address assignment. ptrconst points to the address where “constant data” is stored, which is in the read-only data segment. However, the address value of ptrconst can be changed because it is stored in the read-write data segment.

Example Explanation:

int main()

{

short b; // b is placed on the stack, occupying 2 bytes

char a[100]; // needs to allocate 100 bytes on the stack, the value of a is its starting address

char s[] = “abcde”;

// s is on the stack, occupying 4 bytes, “abcde” itself is placed in the read-only data storage area, occupying 6 bytes. s is an address

// constant, cannot change its address value, i.e., s++ is incorrect.

char *p1; // p1 is on the stack, occupying 4 bytes

char *p2 = “123456”; // “123456” is placed in the read-only data storage area, occupying 7 bytes. p2 is on the stack, the content pointed to by p2 cannot be changed

// but the address value of p2 can be changed, i.e., p2++ is correct.

static char bss_2[100]; // local uninitialized data segment

static int c = 0; // local (static) initialized area

p1 = (char *)malloc(10 * sizeof(char)); // allocated memory area is in the heap

strcpy(p1, “xxx”); // “xxx” is placed in the read-only data storage area, occupying 5 bytes

free(p1); // use free to release the memory pointed to by p1

return 0;

}

Explanation:

1) The read-only data segment needs to include const type data defined in the program (e.g., const char ro[]), as well as data needed in the program such as “123456”. For the definitions of const char ro[] and const char *ptrconst, the memory they point to is located in the read-only data area, and the content they point to is not allowed to be modified. The difference is that the former does not allow modification of the value of ro in the program, while the latter allows modification of the value of ptrconst itself. For the latter, rewriting it in the following form will not allow modification of the value of ptrconst itself:

const char * const ptrconst = “const data”;

2) The read-write data segment includes already initialized global variables static char rw1[] and local static variables static char rw2[]. The difference between rw1 and rw2 is that rw1 is used in the function, while rw2 can be used throughout the file. For the former, the static modifier controls whether the rw1 variable can be accessed by other files. If it has the static modifier, it cannot be used in other C language source files. This impact is related to the characteristics of compilation and linking, but regardless of whether static is used, the variable rw1 will be placed in the read-write data segment. For the latter, rw2 is a local static variable placed in the read-write data area; if the static modifier is not used, its meaning will completely change, and it will be allocated in the stack space as a local variable, not a static variable.

3) The uninitialized data segment, represented by bss_1[100] and bss_2[200] in Example 1, represents uninitialized data segments in the program. The difference is that the former is a global variable that can be used in all files, while the latter is a local variable that can only be used within the function. The uninitialized data segment does not set the subsequent initialization values, so it must use values to specify the size of the area, and the compiler will set the length to be increased in BSS based on the size.

4) The stack space includes variables used internally in functions such as short b and char a[100], as well as the value of p1 in char *p1.

1) The memory pointed to by variable p1 is established in heap space, which can only be used internally in the program. However, heap space (e.g., memory pointed to by p1) can be passed as a return value to be processed by other functions.

2) The stack space is mainly used for the following three types of data storage:

a) Dynamic variables inside functions

b) Function parameters

c) Function return values

3) The main use of stack space is for dynamic variables inside functions, and the space for variables is allocated before the function starts and automatically reclaimed by the compiler after the function exits. Here is an example:

int main()

{

char *p = “tiger”;

p[1] = ‘I’;

p++;

printf(“%sn”, p);

}

Compilation will prompt: segmentation fault

Analysis:

char *p = “tiger”; the system allocates 4 bytes on the stack to store the value of p. “tiger” is stored in the read-only storage area, so the content of “tiger” cannot be changed. *p = “tiger” indicates address assignment, so p points to the read-only storage area. Therefore, changing the content pointed to by p will cause a segmentation fault. However, since p is stored on the stack, its value can be changed, so p++ is correct.

05Usage of const

1. Introduction:

const is a keyword in C language that restricts a variable from being changed. Using const can improve the robustness of the program to a certain extent. Additionally, understanding the role of const when viewing others’ code can help in understanding their programs.

2. const Variables and Constants

1) Variables modified by const have their values stored in the read-only data segment and cannot be changed. They are called read-only variables.

Its form is const int a = 5; here a can replace 5

2) Constants: They also exist in the read-only data segment, and their values cannot be changed. Their forms are “abc”, 5

3) const variables and const-limited content, let’s look at an example:

typedef char* pStr;

int main()

{

char string[6] = “tiger”;

const char *p1 = string;

const pStr p2 = string;

p1++;

p2++;

printf(“p1=%snp2=%sn”, p1, p2);

}

After compilation, the error prompt will be

error: increment of read-only variable ‘p2’

1) The basic form of using const is: const char m;

// restricts m from being changed

2) Replacing m in the first form, const char *pm;

// restricts *pm from being changed, of course, pm is variable, so p1++ is correct.

3) Replacing m in the first form, const newType m;

// restricts m from being changed, the problem with pStr is a new type, so p2 cannot be changed, and p2++ is incorrect.

4) const and pointers

In type declarations, const is used to modify a constant, with the following two forms:

1) const in front

const int nValue; // nValue is const

const char *pContent; // *pContent is const, pConst is variable

const (char *)pContent; // pContent is const, *pContent is variable

char *const pContent; // pContent is const, *pContent is variable

const char * const pContent; // both pContent and *pContent are const

2) const at the back is equivalent to the above declarations

int const nValue; // nValue is const

char const *pContent; // *pContent is const, pContent is variable

(char *) const pContent; // pContent is const, *pContent is variable

char* const pContent; // pContent is const, *pContent is variable

char const* const pContent; // both pContent and *pContent are const

Explanation: Using const with pointers is a common confusion in C language. Here are two rules:

1) Draw a line along the * symbol; if const is on the left side of *, it is used to modify the variable pointed to by the pointer, i.e., the pointer points to a constant; if const is on the right side of *, it modifies the pointer itself, i.e., the pointer itself is constant. You can use this rule to see the actual meaning of the above declarations, and it will be clear at a glance.

2) For const (char *); since char * is a whole, it is equivalent to a type (like char), so this restricts the pointer to be const.

06data,idata,xdata,pdata,code

From the perspective of data storage types, the 8051 series has on-chip and off-chip program memory, on-chip and off-chip data memory. The on-chip program memory is further divided into direct addressing and indirect addressing types, corresponding to code, data, xdata, idata, and pdata types set according to the characteristics of the 51 series. Using different memory will result in different program execution efficiency. When writing C51 programs, it is best to specify the storage type of variables, which will help improve program execution efficiency (this issue will be discussed in detail later). Unlike ANSI-C, it is only divided into SMALL, COMPACT, and LARGE modes, each corresponding to different actual hardware systems, which will also have different compilation results.

In the 51 series, the differences between data, idata, xdata, and pdata are:

data: refers to the fixed 128 RAM from 0x00-0x7f, which can be directly read and written using acc, the fastest speed, and the smallest generated code.

idata: refers to the fixed 256 RAM from 0x00-0xff, where the first 128 are identical to data’s 128, but accessed differently. idata is accessed in a pointer-like manner in C. The assembly statement is: mov ACC, @Rx. (An unimportant supplement: idata works well with pointer-style access in C)

xdata: external extended RAM, generally refers to external space from 0x0000-0xffff, accessed using DPTR.

pdata: the low 256 bytes of external extended RAM, read and written when the address appears in A0-A7, using movx ACC, @Rx for read and write. This is relatively special, and C51 seems to have a bug regarding this; it is recommended to use it sparingly. However, it also has its advantages, and the specific usage belongs to intermediate issues, which will not be discussed here.

What is the role of unsigned char code table[] code in microcontroller C language?

The role of code is to tell the microcontroller that the data I defined should be placed in ROM (program storage area), and cannot be changed after being written. It is actually equivalent to the addressing MOVX in assembly (it seems), because C language cannot describe in detail whether it is stored in ROM or RAM (registers), so this statement is added in software to replace the assembly instruction. The corresponding data means it is stored in RAM.

Programs can be simply divided into code (program) area and data (data) area. The code area cannot be changed during execution, while the data area stores global variables and temporary variables, which need to be constantly changed. The CPU reads instructions from the code area and processes data from the data area. Therefore, it does not matter what medium the code area is stored on. For example, earlier computer programs were stored on cards; the code area can also be placed in ROM, RAM, or flash (but running speed is much slower, mainly because reading flash takes more time than reading RAM). Therefore, the general practice is to place the program in flash and then load it into RAM for execution; the DATA area has no choice but to be placed in RAM, as it cannot be modified if placed in ROM.

How to use bdata?

If the program requires 8 or more bit variables, it is inconvenient to assign values to 8 variables at once (for example, to illustrate its convenience, please ponder it in applications for deeper understanding). You cannot define a bit array, so there is only one method:

char bdata MODE;

sbit MODE_7 = MODE^7;

sbit MODE_6 = MODE^6;

sbit MODE_5 = MODE^5;

sbit MODE_4 = MODE^4;

sbit MODE_3 = MODE^3;

sbit MODE_2 = MODE^2;

sbit MODE_1 = MODE^1;

sbit MODE_0 = MODE^0;

8 bit variables MODE_n are defined.

This is the definition statement, a special data type of Keilc. Remember it must be sbit.

It cannot be bit MODE_0 = MODE^0;

The assignment statement must be written like this; C language will treat it as an XOR operation.

Flash, relative to RAM in the microcontroller, belongs to external storage. Although its structural position is installed in the microcontroller, xdata is actually placed outside relative to RAM, while flash is exactly outside RAM.

inta variable defined in internal RAM, xdata inta defined in external RAM or flash, uchar code a defined in flash.

uchar code duma[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x40, 0x00}; // common cathode segment selection for the digital tube, values to be taken from port P2.

If defined uchar aa[5], the contents of aa[5] are stored in the data storage area (RAM), and the values of each array element can be modified during the program execution. After power off, the data in aa[5] cannot be saved.

If defined uchar code bb[5], the contents of bb[5] are stored in the program storage area (such as flash), and can only be changed when the program is burned; during program execution, the values of bb[5] cannot be modified, and the data in bb[5] will not disappear after power off.

07Differences Between Heap and Stack in C Language

After compilation and linking, the binary image file formed by the C language program consists of stack, heap, data segment (composed of three parts: read-only data segment, initialized read-write data segment, uninitialized data segment, i.e., BSS), and code segment, as shown in the figure below:

8000 Words! Essential Knowledge of Data Storage and Program Writing in C Language for Microcontrollers!

1. Stack Area: Automatically allocated and released by the compiler, storing function parameter values, local variables, etc. Its operation is similar to a stack in data structures.

2. Heap Area: Generally allocated and released by the programmer. If the programmer does not release it, it may cause memory leaks. Note that the heap is different from the stack in data structures; it is similar to a linked list.

3. Program Code Area: Stores the binary code of the function body.

4. Data Segment: Composed of three parts:

1) Read-Only Data Segment:

The read-only data segment contains some data used by the program that will not be changed. The use of this data is similar to table lookup operations. Since these variables do not need to be changed, they can simply be placed in read-only memory. Generally, const-modified variables and string constants used in the program will be stored in the read-only data segment.

2) Initialized Read-Write Data Segment:

Initialized data refers to variables declared in the program that have initial values. These variables need to occupy storage space and must be located in a readable and writable memory area during program execution, with initial values for reading and writing. Generally, these are already initialized global variables and already initialized static local variables (static-modified initialized variables).

3) Uninitialized Segment (BSS):

Uninitialized data refers to variables declared in the program but not initialized. These variables do not need to occupy storage space before the program runs. Similar to the read-write data segment, it also belongs to the static data area. However, the data in this segment has not been initialized. The uninitialized data segment will only be generated during the initialization phase of execution, so its size will not affect the size of the target file. Generally, it consists of uninitialized global variables and uninitialized static local variables.

Differences Between Heap and Stack

1. Allocation Method

(1) Stack: Automatically allocated by the system. For example, declaring a local variable int b in a function; the system automatically allocates space for b on the stack.

(2) Heap: Must be allocated by the programmer (calling malloc, realloc, calloc), specifying the size, and released by the programmer. It is easy to produce memory leaks.

eg: char *p;

p = (char *)malloc(sizeof(char)); // However, p itself is on the stack.

2. Size Limitations

1) Stack: In Windows, the stack is a data structure that expands towards lower addresses, which is a contiguous memory area (its growth direction is opposite to that of memory). The size of the stack is fixed. If the allocated space exceeds the remaining space of the stack, it will prompt overflow.

2) Heap: The heap is a data structure that expands towards higher addresses (its growth direction is the same as that of memory), which is a non-contiguous memory area. This is because the system uses a linked list to store free memory addresses, which is naturally non-contiguous, and the traversal direction of the linked list is from low address to high address. The size of the heap is limited by the effective virtual memory in the computer system.

3. System Response:

1) Stack: As long as the stack space is greater than the requested space, the system will provide memory for the program; otherwise, it will report an exception indicating stack overflow.

2) Heap: First, it should be known that the operating system has a linked list that records free memory addresses. When the system receives the program’s request, it will traverse this linked list to find the first heap node with space greater than the requested space, then delete that node from the free list and allocate that space to the program. Additionally, for most systems, the size of the allocated memory will be recorded at the starting address of this memory space, so that the free statement in the code can correctly release this memory space. Moreover, the size of the found heap node may not exactly equal the requested size; the system will automatically place the excess part back into the free list.

Note: For the heap, frequent new/delete will inevitably cause non-contiguous memory space, leading to a lot of fragmentation, which reduces program efficiency. For the stack, this problem does not exist.

4. Allocation Efficiency

1) Stack is automatically allocated by the system, which is fast. However, the programmer cannot control it.

2) Heap is allocated by malloc, which is generally slower and prone to fragmentation, but is the most convenient to use.

5. Storage Content in Heap and Stack

1) Stack: When a function is called, the first thing pushed onto the stack is the address of the next statement in the main function, followed by the parameters of the function, which are pushed onto the stack from right to left, and then the local variables in the function. Note: Static variables are not pushed onto the stack.

When the current function call ends, local variables are popped first, followed by parameters, and finally the stack pointer points to the address where the first value was stored, which is the next instruction in the main function, and the program continues execution from that point.

2) Heap: Generally, a byte is used at the head of the heap to store the size of the heap.

6. Access Efficiency

1) Heap: char *s1 = “hellowtigerjibo”; is determined at compile time.

2) Stack: char s1[] = “hellowtigerjibo”; is assigned at runtime; using arrays is generally faster than using pointers, as pointers require an intermediate transfer in the underlying assembly, while arrays are read directly from the stack.

Supplement:

The stack is a data structure provided by the machine system, and the computer will provide support for the stack at the bottom level: allocating dedicated registers to store the address of the stack, and there are dedicated instructions for pushing and popping the stack, which determines that the efficiency of the stack is relatively high. The heap, on the other hand, is provided by the C/C++ function library, and its mechanism is very complex. For example, to allocate a block of memory, the library function will search for available memory of sufficient size in the heap memory according to a certain algorithm (the specific algorithm can refer to data structures/operating systems). If there is not enough space (possibly due to too much memory fragmentation), it may call system functions to increase the memory space of the program data segment, thus having the opportunity to allocate sufficient memory, and then return it. Obviously, the efficiency of the heap is much lower than that of the stack.

7. Allocation Methods:

1) The heap is dynamically allocated, with no static allocation of the heap.

2) The stack has two allocation methods: static allocation and dynamic allocation. Static allocation is completed by the compiler, such as the allocation of local variables. Dynamic allocation is performed by the alloca function, but the dynamic allocation of the stack is different from the heap. Its dynamic allocation is performed by the compiler, requiring no manual implementation.

Disclaimer: This article is sourced from the internet, and the copyright belongs to the original author. If there are any copyright issues, please contact for deletion.

8000 Words! Essential Knowledge of Data Storage and Program Writing in C Language for Microcontrollers!

1

“5000 Words of Dry Goods, This is How the Experts Optimize Microcontroller Programs” 111 experts have learned, click to join…

2

“5000 Words of Dry Goods, Understand the Memory of Embedded Operating Systems” 322 experts have learned, click to enter…

Every day, progress a little bit8000 Words! Essential Knowledge of Data Storage and Program Writing in C Language for Microcontrollers!

Leave a Comment