C-Sprache – Speicherverwaltung und Lebenszyklus

1. Speicherzuweisung in der C-Sprache

Referenz 1

1.1 Speicherpartitionen

1. Der von einem C/C++-kompilierten Programm belegte Speicher ist in die folgenden Teile unterteilt:

  • Stapelbereich (Stack ): Wird vom Compiler automatisch zugewiesen und freigegeben und für Laufzeitfunktionen gespeichert.Lokale Variablen, Funktionsparameter, Rückgabedaten, Rückgabeadresse usw.. Seine Funktionsweise ähnelt dem Stapel in der Datenstruktur.

     1.临时创建的局部变量和const定义的局部变量存放在栈区
     2.函数调用和返回时,其入口参数和返回值存放在栈区。
    
  • Heap-Bereich (Heap) : Wird im Allgemeinen automatisch vom Programmierer zugewiesen. Wenn der Programmierer ihn nicht freigibt, kann es am Ende des Programms zu einer Wiederverwertung des Betriebssystems kommen. Seine Zuordnung ähnelt einer verknüpften Liste, die sich vom Heap in der Datenstruktur unterscheidet.

    1. 堆区由程序员分配内存和释放。
    2.堆区按内存地址由低到高方向生长,其大小由系统内存/虚拟内存上限决定,
    速度较慢,但自由性大,可用空间大。
    
  • Globaler Bereich (statischer Bereich ): Speichert globale Variablen und statische Daten. Es wird vom System nach Programmende freigegeben. Der globale Bereich ist in einen initialisierten globalen Bereich (Daten) und einen nicht initialisierten globalen Bereich (BSS) unterteilt . Globale Variablen und statische lokale Variablen werden zusammen gespeichert.Initialisierte globale Variablen und statische lokale Variablen befinden sich in einem Bereich (Daten).Nicht initialisierte globale Variablen und nicht initialisierte statische lokale Variablen befinden sich in einem anderen angrenzenden Bereich. (bss), initialisiert mit 0.

    .bss段
    1.未初始化的全局变量和未初始化的静态变量存放在.bss段。
    2.初始化为0的全局变量和初始化为0的静态变量存放在.bss段。
    3.bss段不占用可执行文件空间,其内容由操作系统初始化
    
    .data段
    1.已初始化的全局变量存放在.data段。
    2.已初始化的静态变量存放在.data段。
    3.data段占用可执行文件空间,其内容由程序初始化。
    
  • Konstanter Bereich (Textkonstantenbereich) : Speichert konstante Zeichenfolgen, die Zeichenfolge „ABCD“ usw., die vom System nach Programmende freigegeben werden.

    常量区
    1.字符串、数字等常量存放在常量区。
    2.const修饰的全局变量存放在常量区。
    3.程序运行期间,常量区的内容不可以被修改。
    
  • Codebereich : Speichert den Binärcode des Funktionskörpers (Klassenmitgliedsfunktion und globaler Bereich).

Fügen Sie hier eine Bildbeschreibung ein

#include<stdio.h>
int a;//全局区中的bss 区,用0初始化,存放未初始化全局变量和未初始化static变量
int b=1;//全局区中的data区,存放初始化全局变量和初始化static变量
static int n;//全局区中的bss 区,用0初始化,存放未初始化全局变量,加static未初始化也在bss区
static int o=1;//全局区中的data区,存放初始化全局变量和初始化static变量
const int j;//全局区中的bss 区,用0初始化,存放未初始化全局变量,加const未初始化也在bss区
const int k=1;//常量区,加const的初始化了的全局变量放在常量区
const int l=1;//常量区,加const的初始化了的全局变量放在常量区

int functiona()//函数名代表函数的地址,在代码区
{
    
    }
int functionb()//函数名代表函数的地址,在代码区
{
    
    }
int main()
{
    
    	int c; //栈区
	int d=1;//栈区
	int e=2;//栈区
	const  int m=2;//栈区
	static int f;//全局区中的bss 区,用0初始化,存放未初始化全局变量和未初始化static变量
	static int g;//全局区中的bss 区,用0初始化,存放未初始化全局变量和未初始化static变量
	static int h=1;//全局区中的data区,存放初始化全局变量和初始化static变量
	static int i=1;
	int *p1 = malloc(4);    //已初始化局部指针变量p1
	int *p2 = malloc(4);    //已初始化局部指针变量p2
	printf("栈区—变量的地址\n");
	printf("未初始化局部变量c的地址为:%d\n已初始化局部变量d的地址为:%d\n已初始化局部变量e的地址为:%d\n",&c,&d,&e);
	printf("加const的初始化局部变量m的地址为:%d\n",&m);
	printf("已初始化局部变量指针p1的地址为:%d\n",&p1);
	printf("已初始化局部变量指针p2的地址为:%d\n",&p2);
	printf("\n");
	printf("全局区(bss)—变量的地址\n");
	printf("加static关键字未初始化局部变量f的地址为:%d\n加static关键字未初始化局部变量g的地址为:%d\n未初始化全局变量a的地址为:%d\n",&f,&g,&a);
	printf("加const的未初始化全局变量j的地址为:%d\n",&j);
	printf("static修饰的全局未初始化变量n的地址为n=%d\n",&n);
	printf("\n");
	printf("全局区(data)—变量的地址\n");
	printf("初始化全局变量b的地址为:%d\n加static关键字初始化局部变量h的地址为:%d\n加static关键字初始化局部变量i的地址为:%d\n",&b,&h,&i);
	printf("static修饰的全局初始化变量o的地址为o=%d\n",&o);
	printf("\n");
	printf("常量区的地址\n");
	printf("加const的初始化全局变量k的地址为:%d\n",&k);
	printf("加const的初始化全局变量l的地址为:%d\n",&l);
	printf("\n");
	printf("代码区的地址\n");
	printf("函数functiona的地址为:%d\n",functiona);
	printf("函数functionb的地址为:%d\n",functionb);
	printf("\n");
	printf("堆区的地址\n");
    printf("已初始化指针p1指向的地址为:%d\n",p1);
	printf("已初始化指针p2指向的地址为:%d\n",p1);
    /*未初始化的全局变量,static修饰的变量在bss区,会默认赋值为0*/
	printf("全局未初始化变量a的默认初始值为a=%d\n",a);
	printf("局部未初始化变量c的默认初始值为c=%d\n",c);/*局部变量不初始化分配值*/
	printf("静态未初始化变量f的默认初始值为f=%d\n",f);
	printf("const修饰的全局未初始化变量j的默认初始值为j=%d\n",j);
}

栈区—变量的地址
未初始化局部变量c的地址为:1703724
已初始化局部变量d的地址为:1703720
已初始化局部变量e的地址为:1703716const的初始化局部变量m的地址为:1703712
已初始化局部变量指针p1的地址为:1703708
已初始化局部变量指针p2的地址为:1703704

全局区(bss)—变量的地址static关键字未初始化局部变量f的地址为:4357200static关键字未初始化局部变量g的地址为:4357204
未初始化全局变量a的地址为:4357208const的未初始化全局变量j的地址为:4357700
static修饰的全局未初始化变量n的地址为n=4357196

全局区(data)—变量的地址
初始化全局变量b的地址为:4344368static关键字初始化局部变量h的地址为:4344376static关键字初始化局部变量i的地址为:4344380
static修饰的全局初始化变量o的地址为o=4344372

常量区的地址const的初始化全局变量k的地址为:4333596const的初始化全局变量l的地址为:4333600

代码区的地址
函数functiona的地址为:4198405
函数functionb的地址为:4198410

堆区的地址
已初始化指针p1指向的地址为:7474728
已初始化指针p2指向的地址为:7474728
全局未初始化变量a的默认初始值为a=0
局部未初始化变量c的默认初始值为c=-858993460
静态未初始化变量f的默认初始值为f=0
const修饰的全局未初始化变量j的默认初始值为j=0
Press any key to continue

Referenzartikel: Speicherzuweisung unter STM32

2. Umfang und Lebenszyklus von C-Sprachvariablen

2.1 Lokale Variablen

Merkmale:

1、在{}内部定义的变量就是局部变量。
2、只有执行到定义变量的这个语句,系统才会给整个变量分配空间。
3、当离开{}这个非静态局部变量自动释放,无法使用。
4、局部变量的作用域在当前{},离开此大括号,变量无法使用。
5、普通局部局部变量也叫自动变量auto。
6、不在同一作用域的变量可以同名。取的时候是就近原则。
7、普通局部变量不初始化默认为随机数
#include<stdio.h>
int a = 2;
int* p = &a;
int main()
{
    
    
	int a = 1;
	printf("局部变量a=%d\n",a);
	printf("全局变量a=%d\n",*p);
	printf("局部变量a的地址=%d\n",&a);
	printf("全局变量a的地址=%d\n", p);
}
局部变量a=1
全局变量a=2
局部变量a的地址=-2066614796
全局变量a的地址=1762771024

D:\VS\vsinstall\Project1\x64\Debug\Project1.exe (进程 12808)已退出,代码为 0
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

Beachten Sie, dass die Adresse der lokalen Variablen a hier lautet: die Adresse der lokalen Variablen a = -2066614796, da die Adresse als vorzeichenbehaftete Zahl ausgegeben wird. Die Adresse ist eine vorzeichenlose Zahl, und das höchste Bit der Adresse ist hier 1. Wenn sie also als vorzeichenbehaftete Zahl ausgegeben wird, sieht sie wie eine negative Zahl aus.
Sie können %u auch verwenden, um vorzeichenlose Dezimalzahlen auszugeben.

2.2 Statische lokale Variablen

1、在{}内部定义的变量就是局部变量。
2、函数没有调用前就存在。
3、当离开{}这个静态局部变量不会自动释放,只有程序程序结束,static变量才自动释放。
4、局部变量的作用域在当前{},离开此大括号,变量无法使用。
5、不在同一作用域的变量可以同名。取的时候是就近原则。
6、如果局部变量不初始化,默认为0
7、值有执行到的时候才初始化,初始化语句只会执行一次,但可以赋值多次。
8、静态变量只能用常量初始化

Fügen Sie hier eine Bildbeschreibung ein
static int b = 2; die Anweisung wird nur einmal ausgeführt und b wird nicht freigegeben. Daher wird b beim ersten Eintreffen der Wert 3 und beim zweiten Eintreffen der Wert 4 zugewiesen.

#include<stdio.h>

void function()
{
    
    
	int a = 1;
	static int b = 2;
	b = a + b;
	printf("b=%d\n",b);
}
int main()
{
    
    
	function();
	//printf("静态局部变量b的值为:%d",b);
	printf("11111\n");
	function();
}

Fügen Sie hier eine Bildbeschreibung ein

2.3 Der Unterschied zwischen gewöhnlichen lokalen Variablen und statischen lokalen Variablen

1. Speicherzuweisung und -freigabe:

 1. 普通局部变量只有执行到定义变量的语句才分配空间。
 2.  静态局部变量在编译阶段(函数还没有执行),变量的空间已经分配。
 3. 普通局部变量离开作用域{},自动释放。
 4.  静态局部变量只有在整个程序结束才自动释放。

2.Initialisierung

1.普通局部变量不初始化,值为随机数。
2.静态局部变量不初始化,值为0。
3.静态局部变量初始化语句只有第一次执行时有效。
4.静态局部变量只能用常量初始化。

2.4 Gewöhnliche globale Variablen

1.在{}外面(函数外面)定义的变量为全局变量。
2.只有定义了全局变量,任何地方都能使用此变量。
3.如果使用变量时,在前面找不到此全局变量的定义,需要声明才能使用。
4.全局变量不初始化,默认赋值为0。
5.声明只针对全局变量,不针对声明多次。
6.全局变量在编译阶段已经分配空间,程序结束,自动释放。
7.全局变量只能定义一次,可以声明多次。
8.不同文件,普通全局变量只能定义一次,可以声明多次。
#include<stdio.h>
int c = 1;
void function()
{
    
    
	int a = 1;
	extern d;//声明
	//int c = 2;
	static int b = 2;
	b = a + b;
	//c = b;
	printf("b=%d\n",b);
	printf("c=%d\n",c);
	printf("d=%d",d);
}
int d = 3;//在funct()函数后面定义的全局变量,需要在前面声明才可以使用,或者定义在前面
int main()
{
    
    
	function();
	printf("11111\n");
	function();
}

```c
b=3
c=1
d=311111
b=4
c=1
d=3
D:\VS\vsinstall\Project1\x64\Debug\Project1.exe (进程 1240)已退出,代码为 0
按任意键关闭此窗口. . .
注意:如果全局变量定义了一个:int c = 1;则在函数体中如果没有定义相同名称的变量,
则取值全局变量定义的值。如果函数体中定义了相同名称的变量:int c = 2;则取局部变量的值。
C语言对全局变量的缺陷:
如果定义一个全局变量,没有赋值(初始化),无法确定是定义,还是声明。
如果定义一个全局变量同时初始化,这个肯定是定义。
如果声明一个全局变量,建议初始化,如果声明一个全局变量建议加extern关键字

2.5 Statische globale Variablen

1.静态全局变量和普通全局变量的区别就是作用域不一样。
2.extern关键字只适合普通全局变量
3.普通全局变量所有文件都能使用,别的文件不能使用。
4.静态全局变量只能在本文件中使用,别的文件不能使用。
5.不同的文件只能出现一个普通全局变量的定义。
6.一个文件只能有一个静态全局变量的定义,不同文件之间的static全局变量,就算名字相同,也是没有关系的两个变量

2.6 Gewöhnliche Funktionen und statische Funktionen (der Dateibereich ist unterschiedlich)

1.所有的文件只能有一次普通函数的定义。
2.一个文件可以有一个静态函数的定义
3.普通函数所有文件都能调用,前提是声明
4.静态函数只能在定义所在的文件中使用

Supongo que te gusta

Origin blog.csdn.net/qq_44772972/article/details/123622566
Recomendado
Clasificación