C语言结构

一个进程在内存中的布局如图所示:

      

.text段(正文段)——保存程序所执行的程序二进制文件,CPU执行的机器指令部分;一个程序只有一个副本;只读,防止程序由于意外事故而修改自身指令。

.data段(数据段)——保存程序中所有已初始化的全局变量。

.bss段(非初始化数据段)——保存程序中所有未初始化的全局变量(其他段中还有很多乱七八糟的段,暂且不表)。

在程序的整个生命周期中,.data段和.bss段内的数据时跟整个程序同生共死的,也就是在程序完全结束之后这些数据才会寿终就寝。

当一个程序的全局变量被声明为static之后,它的中文名叫静态全局变量。静态全局变量和其他的全局变量的存储地点并没有区别,都是在.data段(已初始化)或者.bss段(未初始化)内,但是它只在定义它的源文件内有效,其他源文件无法访问它。所以,普通全局变量穿上static外衣后,它就变成了新娘,已心有所属,只能被定义它的源文件(新郎)中的变量或函数访问。

栈——增长方向:自顶向下增长,即是由高地址向低地址增长;自动变量以及每次函数调用时所需要保存的信息(返回地址;环境信息)。

堆——动态存储分配。

Static和堆栈的关系:

static在C里面可以用来修饰变量,也可以用来修饰函数。

先看用来修饰变量的时候。变量在c里面可分为存在全局数据区、栈和堆里。其实我们平时所说的堆栈是栈而不是堆,不要弄混。

int a ;

int main()

{

int b ;

Int* c = (int *)malloc(sizeof(int));

}

a是全局变量,b是栈变量,c是堆变量(动态分配空间)。

static对全局变量的修饰,可以认为是限制了只能是本文件引用此变量。有的程序是由好多.c文件构成。彼此可以互相引用变量,但加入static修饰之后,只能被本文件中函数引用此变量。

static对栈变量的修饰,可以认为栈变量的生命周期延长到程序执行结束时。一般来说,栈变量的生命周期由OS管理,在退栈的过程中,栈变量的生命也就结束了。但加入static修饰之后,变量已经不再存储在栈中,而是和全局变量一起存储。同时,离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用, 而且保存了前次被调用后留下的值。

static对函数的修饰与对全局变量的修饰相似,只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用。

时间: 2024-09-30 20:38:00

C语言结构的相关文章

C语言 结构体指针赋值 incompatible types when assigning to type 'char[20]' from type 'char *'

strcpy(pstudent->name, "guo zhao wei "); 为什么错误,该怎么写,(红色行) 追问 为什么不能直接赋值啊, 追答 用char nnnn[20]定义的,用strcpy 用char *ppp定义的,用=来赋值 C语言 结构体指针赋值 incompatible types when assigning to type 'char[20]' from type 'char *'

漫谈C语言结构体struct、公用体union空间占用

先用代码说话: #include<stdio.h> union union_data0{ int a ;//本身占用4个字节 char b ;//本身占用1个字节 int c ; }; union union_data1{ short a;//本身占用2个字节 char b[13];//本身占用13个字节 int c ;//本身占用4个字节 }; struct struct_data{ int a ;//int本身占用4个字节,偏移量为0 char b ;//char本身占用1个字节,偏移量为

GO语言结构体相等性

go语言结构体相等性是通过结构体成员的相等来判断的. 之前还在疑惑errors.New返回的结构体为什么会不相等,而且Read函数会返回io.EOF,很多例子代码都会把Read返回返回的error值来和io.EOF做比较,原来io.EOF是错误对象的指针,而不是错误对象本身.一个对象被实例化再多,他们的对象指针一定是不同的,这样就可以得知Read函数返回值和io.EOF比较的原因,因为比较的就是对象指针值,是纯数字的比较,这样也就区分了对象的不同实例.

C语言结构体,C语言结构体指针,java对象引用,传值,传地址,传引用

C语言结构体,C语言结构体指针,java对象引用,传值,传地址,传引用 传值 把实参的值赋值给行参 那么对行参的修改,不会影响实参的值 传地址 传值的一种特殊方式,只是他传递的是地址,不是普通的如int 那么传地址以后,实参和行参都指向同一个对象 传引用 真正的以地址的方式传递参数 传递以后,行参和实参都是同一个对象,只是他们名字不同而已 对行参的修改将影响实参的值 所谓变量是内存地址的一个抽象名字,在静态编译的程序中,所有变量名都会在编译时转换成内存地址,机器不知道变量名,只知道地址. C 语

C语言结构体(struct)常见使用方法(转)

本文转自 CSDN huqinweI987 基本定义:结构体,通俗讲就像是打包封装,把一些有共同特征(比如同属于某一类事物的属性,往往是某种业务相关属性的聚合)的变量封装在内部,通过一定方法访问修改内部变量. 结构体定义: 第一种:只有结构体定义 [cpp] view plaincopy struct stuff{ char job[20]; int age; float height; }; 第二种:附加该结构体类型的“结构体变量”的初始化的结构体定义 [cpp] view plaincopy

C语言结构体赋初值

C语言结构体赋初值,特别是结构体中含有数组成员是,最后一个逗号最好是不要多写.因为有些时候可能会出错.图中,红色的框框处.

读陈浩的《C语言结构体里的成员数组和指针》总结,零长度数组

原文链接:C语言结构体里的成员数组和指针 复制如下: 单看这文章的标题,你可能会觉得好像没什么意思.你先别下这个结论,相信这篇文章会对你理解C语言有帮助.这篇文章产生的背景是在微博上,看到@Laruence同学出了一个关于C语言的题,微博链接.微博截图如下.我觉得好多人对这段代码的理解还不够深入,所以写下了这篇文章. 为了方便你把代码copy过去编译和调试,我把代码列在下面: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <stdio.h>

c 语言 结构体

结构体初学者都有点小怕其实思维清晰之后你会发现结构体是个非常好的东西,嘿嘿. 第一,结构体的定义和初始化.别被书上大量的描述吓到 1.怎么定义结构体了例子如下,我们以构建一个包含学生姓名,年龄,Email为例子 1 struct 2 { 3 char name; 4 int age; 5 char Email; 6 }person; 现在我们定义就已经完成了,当然这是我最喜欢的范式,你们也可以在书上找到自己喜欢的. 2.怎么初始化了?结构体一般初始化都是以结构体数组的形式来的所以我们只说这个 t

Java 语言结构【转】

Java 语言结构 基础:包(Package).类(Class)和对象(Object) 了解 Java 的包(Package).类(Class)和对象(Object)这些基础术语是非常重要的,这部分内容将概要的介绍这些术语. 包(Package) Java 使用包来组织类,通常按照业务逻辑将类分组到不同的包中.比如:应用程序的所有图形界面可能被分组到 com.vogella.webapplication.views 包中. 通常的做法是使用公司域名的倒序作为顶层包,比如:公司的域名是 "4byt

C语言结构体的初始化

今天在工作时,看到了奇葩的结构体初始化方式,于是我查了一下C99标准文档和gcc的说明文档,终于搞清楚是怎么回事了. 假设有如下结构体定义: typedef struct { int a, b, c; } MyStruct; 那么结构体的初始化方式如下有三种: (1) C89的初始化方式 MyStruct test = {1, 2, 3}; 这种初始化的优点是语法简单,无需输入变量名:缺点是成员变量的初始化顺序必须与声明的一致,无法乱序初始化. (2) C99新增的初始化方式 MyStruct