一直对堆栈的使用以及全局变量、静态全局变量、局部变量、静态局部变量、初始化的全局变量、未初始化的全局变量、初始化的局部变量、未初始化的局部变量理解的不是很清楚,今天抽个时间来总结以下这方面的知识:

1.首先心中要有一个内存分布图,最上面肯定是命令行和环境参数、往下依次是栈、堆、bss段、数据段、代码段

  • 是从上往下读的,所以栈放在最上面,栈里面一般存放的是局部变量,但是如果是static的静态局部变量那么其存储在全局初始化区中也就是数据段中,不管是初始化的局部变量还是未初始化的局部变量
  • 中存放的是程序员可操控的内存,一般用malloc()申请,用free释放().
  • bss段用来存放未初始化的全局变量和静态变量,(全局变量未初始化时默认为0的一段区域)
  • 数据段用来存放已经初始化的全局变量和静态变量
  • 代码段用来存放程序中的代码和常量

2.栈:通常指用来存放程序中用户临时创建的局部变量、函数形参、数组(局部变量未初始化则默认为垃圾值),不包括static声明的变量,static意味着在数据段中存放变量。栈可以看成时一个寄存、交换临时数据的内存区。它是由操作系统分配的,内存的申请与回收都由OS管理。。

3.用static声明局部变量:有时希望函数中的局部变量的值在函数调用后不消失而保留原值,这时就应该指定局部变量为“静态局部变量”用关键字static进行声明。

4。对静态局部变量的说明:

  • 静态局部变量属于静态存储类别,在惊天存储区中分配存储单元。在程序整个运行期间都不释放。而自动变量属于动态存储类别,占动态存储类别,占动态存储空间,函数调用结束后即释放。
  • 静态局部变量在编译时赋初值,即只赋值一次,而对自动变量付初值实在函数调用时进行,每调用一次函数重新给一次初值,相当于执行一次赋值语句。
  • 如果在定义局部变量时不赋初值的话,则对静态局部变量来说,编译时自动赋初值0,而对自动变量来说,如果不赋初值的话是要给不确定的值。

5.register变量

  • 为了提高效率,c语言允许将局部变量的值贩子啊cpu中的寄存器中,这种变量叫“寄存器变量”,用关键字register做声明

6.extern

  • 外部变量(即全局变量)是在函数的外部定义的,它的作用域为从变量定义处开始,到本程序文件的末尾。如果外部变量不在文件的开头定义,其有效的作用范围只限于定义处到文件终了。如果在定义点之前的函数想引用该外部变量,则应该在引用之前用关键字extern对该变量作“外部变量声明”。表示该变量是一个已经定义的外部变量。有了此声明,就可以从“声明”处起,合法地使用该外部变量#include

7.下面是对一个程序的举例说明

#include//全局区

int g_n1 = 1;//全局初始化区

char g_c2 ;   //全局未初始化区也就是bss段

void funtion()

{

int a = 1;

}

int main(void)

{

int nNum = 1;                                      //栈区

char cStr2[] = "123";                           //栈区

char *cStr1 = "hello";                          //cStr1在栈区,hello\0在常量区

static int nNum1 = 0;                          //全局初始化区

char *pCStr = (char *)malloc(10);       //分配10字节区域在堆区

strcpy(pCStr, "666");                           //666放在常量区

printf("程序代码区的地址\n");

printf("funtion=%08X\n", funtion);

printf("文字常量区 常量的地址\n");

printf("&cStr1=%08X\n", &cStr1);

printf("&pCStr=%08X\n", &pCStr);

printf("全局区变量的地址\n");

printf("&g_n1=%08X\n", &g_n1);

printf("&g_c2=%08X\n", &g_c2);

printf("&nNum1=%08X\n", &nNum1);

printf("栈区 变量的地址\n");

printf("&nNum=%08X\n", &nNum);

printf("&cStr2=%08X\n", &cStr2);

printf("堆区 空间的地址\n");

printf("pCStr=%08X\n", pCStr);

free(pCStr);//释放

system("pause");

return 0;

}

c中堆栈的理解的更多相关文章

  1. 【转】对ARM堆栈的理解

    对ARM堆栈的理解 堆栈严格来说应该叫做栈,栈(Stack)是限定仅在一端进行插入或删除操作的线性表.因此,对栈来说,可以进行插入或删除操作的一端端称为栈顶(top),相应地,另一端称为栈底(bott ...

  2. Java中堆栈的区别

    简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配. 当在一段代码块定义一个变量时,Java就在栈中为这个变量分 ...

  3. Linux 系统中堆栈的使用方法

    本节内容概要描述了Linux内核从开机引导到系统正常运行过程中对堆栈的使用方式.这部分内容的说明与内核代码关系比较密切,可以先跳过.在开始阅读相应代码时再回来仔细研究. Linux 0.12系统中共使 ...

  4. Fouandation(NSString ,NSArray,NSDictionary,NSSet) 中常见的理解错误区

    Fouandation 中常见的理解错误区 1.NSString //快速创建(实例和类方法) 存放的地址是 常量区 NSString * string1 = [NSString alloc]init ...

  5. linux中socket的理解

    对linux中socket的理解 一.socket 一般来说socket有一个别名也叫做套接字. socket起源于Unix,都可以用“打开open –> 读写write/read –> ...

  6. 谈谈我对Java中CallBack的理解

    谈谈我对Java中CallBack的理解 http://www.cnblogs.com/codingmyworld/archive/2011/07/22/2113514.html CallBack是回 ...

  7. JavaScript中的闭包理解

    原创文章,转载请注明:JavaScript中的闭包理解  By Lucio.Yang 1.JavaScript闭包 在小学期开发项目的时候,用node.js开发了服务器,过程中遇到了node.js的第 ...

  8. 网站开发进阶(三十四)编码中的setCharacterEncoding 理解

    编码中的setCharacterEncoding 理解 1.pageEncoding="UTF-8"的作用是设置JSP编译成Servlet时使用的编码. 2.contentType ...

  9. 关于zynq7 中MIO的理解

    关于zynq7 中MIO的理解 Zynq7000有54个MIO,分配在GPIO的Bank0和Bank1,属于PS部分,这些IO与PS直接相连,不需要添加引脚约束,MIO信号对PL部分是不可见的,对MI ...

随机推荐

  1. java环境变量配置方法

    原创文章,转载请注明出处. 这是本人2011-9-4记录的,现在把它放在博客上. windows xp下配置JDK环境变量: 1.安装JDK,安装过程中可以自定义安装目录等信息,例如我们选择安装目录为 ...

  2. beego生成 api 项目 && api 文档

    目标 生成 api 项目,并且自动生成db的mapper.module等:同时生成api文档 操作步骤 1.生成 api 项目,并且自动生成db全表的映射 bee api [projectName] ...

  3. Hive安装 和管理

  4. mp3-

  5. Linux系统基础5周入门精讲(服务器介绍)

    使用工具:(1)源码管理(git工具):(2)自动部署:(3)web服务器 linux基础 服务器介绍 运维的职责:运行和维护服务器 1数据不能丢----大片不能没 2保证网站7*24小时允许---( ...

  6. 爬虫--Scrapy-持久化存储操作

    总体概况 持久化存储操作: a. 磁盘文件 a) 基于终端指令 i. 保证parse方法返回一个可迭代类型的对象(存储解析到的页面内容) ii. 使用终端指令完成数据存储到制定磁盘文件中的操作 1. ...

  7. 尚硅谷springboot学习13-配置的加载

    配置可以有很多不同的来源,也有不同的加载顺序,下面来具体的看一下 配置文件加载位置 spring boot 启动会扫描以下位置的application.properties或者application. ...

  8. 尚硅谷springboot学习6-eclipse创建springboot项目的三种方法(转)

    方法一 安装STS插件 安装插件导向窗口完成后,在eclipse右下角将会出现安装插件的进度,等插件安装完成后重启eclipse生效 新建spring boot项目 项目启动 方法二 1.创建Mave ...

  9. Cookie安全小结

    Cookie机制:一般来说,同域内浏览器中发出的任何一个请求都会带上Cookie,无论请求什么资源,请求时,Cookie出现在请求头的Cookie字段中.服务端响应头的Set-Cookie字段可以添加 ...

  10. mysql 回顾

    主键可以是一个或者是多个列,但所有的列(或者是列的组合)必须是唯一的,非空的 关键字distinct 可以去重,实现该效果还可以使用group by limit 默认从 0 开始,limit 5 其实 ...