C语言随笔1:内存分配方式与动静态变量
首先几个基本概念(网上的各种说法都很乱;个人理解整理了一下
内存分类方法很多,动态、静态; 五区; 三段;
内存的区:
1.动态存储区分为 栈区、堆区 也统称为堆栈段
1.1栈区(.stack) 编译器自动分配释放,存放函数的参数值,局部变量的值等。函数结束自动释放
1.2堆区(.heap) 一般由程序员分配释放, 若程序员不释放,程序结束时可能由os回收。
new或者malloc出来的对象;(不释放导致内存泄漏)
2.静态区域分为 数据段(放数据)、代码段(只读)
2.1 全局区(数据段)—全局变量 和 静态变量 的存储 都是放在 数据段,
初始化的全局变量和静态变量在一块区域,
未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
程序结束后有系统释放。
内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在
2.2 文字常量区(代码段) —常量字符串就是放在这里的。 程序结束后由系统释放。
(常量不允许修改)
常量区在代码段里,不占内存,静态存储区在内存中
2.3 程序代码区(代码段) —存放函数体的二进制代码。常量区与代码区都是 代码段的
总结到这里,有个疑惑待解答;与ram和rom的联系;是否可以认为堆、栈、全局区是存在ram
代码段是在E方中存储。文字常量不占内存,但是还会释放,应该不是在宝贵的E方里存储
再反过头来从变量的角度看分配:
先说一个概念
作用域:起作用的区域。分为
1、 代码块:一个{}包括的区域,甚至可以在一个if的{}下定义变量,但不常用。一般都是在函数开头定义。
2、 文件作用域:一个.c文件 (由static限定的全局变量在此。#include指令包含的其他文件也算同一个文件,
但是static的变量还是要放在.c文件中,因为虽然会include进.h文件。但是在编译时
会在.h文件中也创建一个static变量,互不可见。
文件作用域是仅仅对一个文件起作用
3、全局可见:定义的全局变量,注意:对于全局变量的赋值必须在函数之内,除了初始化可以在外面赋值
链接属性:一共有3种:
none(无)
总是被当做单独的个体,也就是说该标识符的多个声明被当作独立不同的实体。
internal(内部)
在同一个源文件中的所有声明中都指向同一个实体,但位于不同源文件的多个声明则分属不同的实体。
external(外部):
不论声明多少次、位于几个源文件都表示同一个实体。
局部变量: 在动态存储区,函数结束释放(在栈区stack上)
若没有初始化,它的初始值是垃圾
同名内层块会对把外层的变量隐藏掉,不要这样用
作用域:代码块(既 一个{}括起来的一段代码;函数中使用一般放在最开头
静态局部变量:static 在静态存储区(数据段) 函数调用结束保留 下次调用维持上次的值
仅在创造时初始化一次,没有初始化默为0。(最好初始化,更严谨)
释放:main函数是整个程序的声明周期,静态变量在main 的return之后释放
(static改变了生命周期;没有改变作用域,仅仅是存储区域由栈变为数据段)
全局变量: 在静态存储区(数据段) 创造和初始化一次 没有初始化值默为0
只能定义一次,可以多次声明和引用
具有全局可见性,但是引用时需要extern
静态全局变量:static 在数据段 用于解决重名问题,该变量只在本文件使用
(所以一般不放在头文件,直接源文件)
(static只改变作用域;限定可见性为该.C文件)
全局变量的跨文件引用:
跨文件引用,只讨论全局变量和函数
extern 是只声明不定义
普通全局变量直接引用编译会报错,要extern才能用
具体用法:
变量:在a.c中定义了全局变量 struct t,在a.h中extern struct t;
并在b.c中#include a.h 然后就可以在b.c中使用。(这是项目 中的用法)
按照语法上来讲,在b.c中extern 也可以,规范用法还是在.h中extern
函数:用法与变量相同,都是在.h文件中extern出去。并include使用
原理上来讲:从链接属性上说,需要extern的变量在b.c中是没有定义的。t变量虽然具有全局可见性
编译器在编译各个独立的文件时是相互不透明的,但是编译器并不知道,所以需要extern一下,告诉编译器放行。
可以正常产生obj(二进制指令流);在link阶段,可见范围扩大到整个程序。(如果此时发现该变量定义多次会报错)。
编译结束生成.exe文件
extern 将变量从none属性变为external ,多个文件对应同一个实体
static 将变量从变为internal(内部)
在一些复杂的项目中,
比较习惯在所有的函数声明前添加extern修饰,
以防止遗漏包含头文件而导致的编译错误。
标识符:就是变量的名字
关键字:变量类型
C语言随笔1:内存分配方式与动静态变量的更多相关文章
- [转载]C语言程序的内存分配方式
"声明一个数组时,编译器将根据声明所指定的元素数量为数量为数组保留内存空间."其实就是编译器在编译的过程中,会加入几条汇编指令在程序里处理内存分配,并不是说编译时就分配了内存,不要 ...
- C语言数据在内存分配
一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈.程序结束时由编译器自动释放 ...
- C语言变量声明内存分配
转载: C语言变量声明内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等.其操作方式类似于数据结 ...
- C语言中的内存分配与释放
C语言中的内存分配与释放 对C语言一直都是抱着学习的态度,很多都不懂,今天突然被问道C语言的内存分配问题,说了一些自己知道的,但感觉回答的并不完善,所以才有这篇笔记,总结一下C语言中内存分配的主要内容 ...
- c语言中的内存分配malloc、alloca、calloc、malloc、free、realloc、sbr
C语言跟内存分配方式 (1) 从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. (2) 在栈上创建.在执行函数时,函数内局部变 ...
- C++内存分配方式——小结
1 内存分配方式 内存分配方式有如下三种: 从静态存储区域分配.内存在程序编译的时候就分配好了,这些内存在整个程序运行期间都存在,如全局变量.static变量等等. 在堆栈上分配.在函数执行期间,函数 ...
- C语言中动态内存分配的本质是什么?
摘要:C语言中比较重要的就是指针,它可以用来链表操作,谈到链表,很多时候为此分配内存采用动态分配而不是静态分配. 本文分享自华为云社区<[云驻共创]C语言中动态内存分配的本质>,作者: G ...
- [c语言]c语言中的内存分配[转]
在任何程序设计环境及语言中,内存管理都十分重要.在目前的计算机系统或嵌入式系统中,内存资源仍然是有限的.因此在程序设计中,有效地管理内存资源是程序员首先考虑的问题. 第1节主要介绍内存管理基本概念,重 ...
- c/c++内存分配方式(转)
原文链接:http://blog.csdn.net/jing0611/article/details/4030237 1.内存分配方式 内存分配方式有三种: [1]从静态存储区域分配.内存在 程序编译 ...
随机推荐
- Sikerio --《只狼》
“狼啊,替我断绝不死吧”
- JavaSE学习笔记(5)---内部类和String类
JavaSE学习笔记(5)---内部类和String类 一.内部类基础 转自菜鸟教程 在 Java 中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类.广泛意义上的内部类一般来 ...
- css样式的兼容性
浏览器 前缀 IE和safari -webkit- Chrome -ms- Firefox ...
- CF1254E Send Tree to Charlie
题意 讲不太清楚,看英文吧 cf 做法 在正式开始之前,我们先来玩一玩性质 首先考虑全\(0\)的情况,即本质不同的方案数 性质1:方案数并不为(n-1)!,即方案与结果不为双射 考虑一条边将树分为两 ...
- eXosip和osip详解
文档 可以查看exosip osip的在线文档 http://www.antisip.com/doc/ 在线文档 一般先看mainpage 会有库的一个整体说明. 其次看看 modules 会有一些使 ...
- java学习笔记之反射—反射和工厂模式
简单工厂模式又称为静态工厂方法模式,它是由工厂对象来决定要创建哪一种类的实例化对象. 静态工厂代码: class Factory{ private Factory() {} public static ...
- How to Install Oracle Java 11 on Ubuntu 18.04 LTS (Bionic) Written by Rahul, Updated on April 3, 20
本文系转载备份 请阅读点击下面链接阅读原文以获取更佳地阅读体验.谢谢. How to Install Oracle Java 11 on Ubuntu 18.04 LTS (Bionic) Writt ...
- CSS 实现一个自适应的正方形
传统方法正方形用固定的形式写 直接长=宽写固定的值如下 .box{ width: 200px; height: 200px; background: pink; color: ...
- Vuejs中created和mounted的区别
created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图. mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作
- Extended Traffic LightOJ - 1074 spfa判断负环
//判断负环 在负环内的城市输出? #include <iostream> #include <queue> #include <cstdio> #include ...