c中堆栈的理解
一直对堆栈的使用以及全局变量、静态全局变量、局部变量、静态局部变量、初始化的全局变量、未初始化的全局变量、初始化的局部变量、未初始化的局部变量理解的不是很清楚,今天抽个时间来总结以下这方面的知识:
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中堆栈的理解的更多相关文章
- 【转】对ARM堆栈的理解
对ARM堆栈的理解 堆栈严格来说应该叫做栈,栈(Stack)是限定仅在一端进行插入或删除操作的线性表.因此,对栈来说,可以进行插入或删除操作的一端端称为栈顶(top),相应地,另一端称为栈底(bott ...
- Java中堆栈的区别
简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配. 当在一段代码块定义一个变量时,Java就在栈中为这个变量分 ...
- Linux 系统中堆栈的使用方法
本节内容概要描述了Linux内核从开机引导到系统正常运行过程中对堆栈的使用方式.这部分内容的说明与内核代码关系比较密切,可以先跳过.在开始阅读相应代码时再回来仔细研究. Linux 0.12系统中共使 ...
- Fouandation(NSString ,NSArray,NSDictionary,NSSet) 中常见的理解错误区
Fouandation 中常见的理解错误区 1.NSString //快速创建(实例和类方法) 存放的地址是 常量区 NSString * string1 = [NSString alloc]init ...
- linux中socket的理解
对linux中socket的理解 一.socket 一般来说socket有一个别名也叫做套接字. socket起源于Unix,都可以用“打开open –> 读写write/read –> ...
- 谈谈我对Java中CallBack的理解
谈谈我对Java中CallBack的理解 http://www.cnblogs.com/codingmyworld/archive/2011/07/22/2113514.html CallBack是回 ...
- JavaScript中的闭包理解
原创文章,转载请注明:JavaScript中的闭包理解 By Lucio.Yang 1.JavaScript闭包 在小学期开发项目的时候,用node.js开发了服务器,过程中遇到了node.js的第 ...
- 网站开发进阶(三十四)编码中的setCharacterEncoding 理解
编码中的setCharacterEncoding 理解 1.pageEncoding="UTF-8"的作用是设置JSP编译成Servlet时使用的编码. 2.contentType ...
- 关于zynq7 中MIO的理解
关于zynq7 中MIO的理解 Zynq7000有54个MIO,分配在GPIO的Bank0和Bank1,属于PS部分,这些IO与PS直接相连,不需要添加引脚约束,MIO信号对PL部分是不可见的,对MI ...
随机推荐
- Spring boot 自定义starter
以下配置来自尚硅谷.. 常用如何配置 @Configuration //指定这个类是一个配置类 @ConditionalOnXXX //在指定条件成立的情况下自动配置类生效 @AutoConfigur ...
- ReactiveX 学习笔记(14)使用 RxJava2 + Retrofit2 调用 REST API
JSON : Placeholder JSON : Placeholder (https://jsonplaceholder.typicode.com/) 是一个用于测试的 REST API 网站. ...
- ASP.NET HTTP 协议
http是无状态的,不会记得“上个请求***”,所以哪怕是同一个页面中的js.css.jpg也都要重复的提交Accept-Language.Accept-Encoding.Cookie等. 一般情况下 ...
- javascript单线程那些事
首先,说下为什么 JavaScript 是单线程? 总所周知,JavaScript是以单线程的方式运行的.说到线程就自然联想到进程.那它们有什么联系呢? 进程和线程都是操作系统的概念.进程是应用程序的 ...
- vue项目bug-Couldn’t find preset "es2015"
在使用vue项目的时候安装了其他的插件,发现会报错 Couldn’t find preset "es2015".是因引用的插件使用了es标准,解决办法如下 npm install ...
- 利用官方的vue-cli脚手架来搭建Vue集成开发环境
在利用vue-cli脚手架搭建vue集成环境之前,我们需要先安装nodejs的环境.如果在cmd中输入node --version和npm --version出现如下的版本信息,就说明安装已经成功了. ...
- linux shell 语法学习
文件比较运算符-e filename 如果 filename存在,则为真 [ -e /var/log/syslog ]-d filename 如果 filename为目录,则为真 [ -d /tmp/ ...
- mac shortcut
在Windows系统中,如果你想跳到行首.行尾直接点击home.end键就可以了,但MacBook的相关快捷键就有些区别了,相关快捷键如下: Ctrl+A:到行首(达到Home键的效果) .fn键+左 ...
- Hibernate 再接触 继承映射
用一张 每一个类一张表 建立外键 第一种 一张总表 Person package com.bjsxt.hibernate; import javax.persistence.Discriminator ...
- MAC下Xcode配置opencv(2017.3.29最新实践,亲测可行)(转)
本文原创,未经同意,谢绝转载!(转载请告知本人并且经过本人同意--By Pacific-hong) 本人小硕一枚,因为专业方向图像相关,所以用到opencv,然后网上MAC下Xcode配置opencv ...