C language variable storage order

Author: Zen and the Art of Computer Programming

1 Introduction

C language is a statically strongly typed programming language. The storage location of the variable (static/auto/register), the data type of the variable and its size and other attributes are specified when the variable is declared. The memory layout of the variable is determined at compile time. For junior programmers, understanding the storage order of variables is crucial to writing efficient and correct code. This article will elaborate on the storage order and characteristics of C language variables.

2.Basic concepts and terminology

2.1 Program running environment

Consider a calculator application that contains an input box to receive user input of numbers and a button to trigger the calculation process. When the user clicks the button, the calculator application first gets the number entered by the user and displays it on the screen. Then the results are calculated through the algorithm and displayed on the screen, and finally the user is prompted whether they need to continue the calculation. In order to improve the user experience, the program should respond to the user's operations as quickly as possible. So how to quickly respond to user operations? There are currently two main solutions:

  1. Optimize the program to reduce repeated operations and waste of resources.
  2. Use multi-threading or other asynchronous methods so that other tasks can be processed while the program is running.

In the first case, the performance of the program can be improved by minimizing unnecessary repeated calculations and saving system resources; while in the second case, relying on the asynchronous nature of the program, parallelism can be achieved through multi-core CPUs or IO devices. Calculate and process I/O requests. However, due to the differences between different hardware platforms and operating systems, it is still difficult to implement asynchronous computing. Therefore, how to improve the running speed of the program while ensuring the correctness of the program has become a topic that remains to be studied.

In short, the computer's fast computing power directly affects the running speed of the program. How to make full use of this ability is a question worth exploring.

2.2 Data structures and algorithms

Data structures and algorithms are very important contents in computer science. Algorithms provide a way to solve a specific problem and involve steps in which a computer processes large amounts of data, with each step performed using computer instructions. Data structure refers to the formal method of storing, organizing and managing data. Its purpose is to handle complex data collections more efficiently and support efficient lookups, access, and updates.

2.2.1 Stack

Stack, also known as stack, is a linear table structure that can only insert and delete data at one end. The latest added data is placed on the top of the stack, and the first deleted data is also the data on the top of the stack. The basic operations of the stack are push and pop.

The characteristics of the stack determine the application scenarios of the stack: function calling and recycling, expression evaluation, base conversion, bracket matching, program counter, recursive call stack, etc.

2.2.2 Queue

Queue, also known as FIFO (First In First Out), is a special linear list that can only add elements at the end of the queue and delete elements at the head of the queue. The first-in, first-out characteristic determines the application scenarios of the queue: message passing, multi-channel batch processing, process scheduling, etc.

2.2.3 Linked list

A linked list is a non-continuous storage structure composed of nodes. Each node stores data and a pointer to the next node. Linked lists have flexible structures and the ability to dynamically allocate memory. The advantage of a linked list is that nodes can be inserted or deleted anywhere in the linked list, and they can also be traversed easily. But the disadvantage is that the space occupied by the pointer field is too small, which adds additional overhead.

2.2.4 Tree

A tree is a data structure. It is a finite structure composed of n nodes or infinite nodes. These nodes are connected through edges or lines to form an organic structure. Trees can be divided into three types: an empty tree (empty tree), with only one root node (root tree), and behind the root node is a tree with m>0 children (internal nodes). Except for the root node, all nodes have one and only one parent node. The two main applications of trees are sorting, search, graph theory, etc.

2.2.5 Hash table

Hash Table is a technology that directly accesses records based on keywords. In other words, by mapping the key to a position in the array to access the record, the search time required is O(1) on average. Many query operations can take O(n) time, where n is the number of buckets in the hash table.

Hash tables are used in a wide range of applications, such as database indexes, caching technology, data classification, encryption algorithms, etc.

3. Storage order of C language variables

3.1 Variable storage order

The storage order of variables in C language is divided into two categories, static storage and dynamic storage. Staticly stored variables allocate memory during the compilation phase and have a life cycle until the end of the program, so their storage address is fixed. Dynamically stored variables allocate memory as needed during the running of the program, and their life cycle terminates as the program runs.

Automatic variables, static local variables and formal parameters are all stored statically. They are allocated memory during the compilation phase. The life cycle of the variables is from definition to the end of the program.

Dynamic variables, stack variables, register variables and global variables are dynamically stored. They dynamically allocate memory as needed during the running of the program. The life cycle of the variables is controlled by the program. If they exceed the scope, they will be automatically released.

1. Stack

When the program is executing and functions are called, some temporary variables may be saved in the stack. The variables in the stack exist in the context of the function call and will be released after the function is executed. Therefore, the stack is usually used to store temporary variables, such as parameters, local variables, return addresses, etc. The growth direction of the stack is from high addresses to low addresses. The stack automatically allocates and releases memory. As long as the function is called, a piece of memory is applied for on the stack, and then the variables can be saved in this memory area. The biggest advantage of the stack is that it is simple and easy to implement.

2. Heap

The heap is a portion of computer memory used to store dynamically allocated memory segments. The heap is used to store various data structure objects generated during program running, including temporary variables, arrays, records, files, etc. created during runtime. The heap allocates and releases memory dynamically, and memory is generally allocated and released manually at runtime. The growth direction of the heap is from low addresses to high addresses.

3. Literal constant area

The literal constant area is a memory segment of the program, which stores character constants in the program, such as strings, integers, real numbers, characters, etc. These data are fixed during program compilation, so their storage addresses do not change.

4. Static storage area

The static storage area is a memory specifically used to store static variables, including global variables, static local variables, constants, enumerations, etc. Its storage location is determined during program compilation, so its storage address will not change. Variables in the static storage area belong to automatic variables, static local variables and formal parameters.

5. Register

Registers are the computer's cache, used to temporarily store data processed by the processor. Registers are limited and can only hold part of the data at the same time. Therefore, when the processor needs to process a large amount of data, it must frequently read and write memory, which reduces efficiency. Therefore, under normal circumstances, the processor will temporarily store some of the processed data in the register, so that when the data is needed next time, it can save time by reading it directly from the register.

For local variables, if it is not referenced, the compiler will generally not save it in a register. However, in function calls, since the call parameters may be stored in registers, it may be necessary to allocate more registers to store local variables.

4. Example

#include <stdio.h>

int main() {
    int a; //自动变量
    static int b = 10; //静态局部变量
    const float PI = 3.14; //常量

    printf("内存分布:\n");
    printf("&a=%p\n", &a); //打印&a的地址
    printf("&b=%p\n", &b); //打印&b的地址
    printf("&PI=%p\n", &PI); //打印&PI的地址

    return 0;
}

The output is as follows:

内存分布:
&a=0x7ffd543aa444 
&b=0x7ffd543aa3e4 
&PI=0x7ffc19c9e2d4 

It can be seen that the distribution of the three variables , , aand in the memory is as follows:bPI

  1. &a: Represents athe address of the variable, which is calculated at runtime.
  2. &b: Represents bthe address of the variable, which is also calculated at runtime.
  3. &PI: Represents PIthe address of a constant. This address is fixed when the program starts and will not change.

Therefore, it can be seen that the variable storage order in C language follows the principle of last in first out, that is, static variables > automatic variables > stack variables > register variables > heap variables. Among them, stack variables and register variables are stored later and are released only at the end of the function call.

Guess you like

Origin blog.csdn.net/universsky2015/article/details/133504639