首先几个基本概念(网上的各种说法都很乱;个人理解整理了一下

内存分类方法很多,动态、静态;  五区;  三段;

内存的区:

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种:

  1. none(无)

    总是被当做单独的个体,也就是说该标识符的多个声明被当作独立不同的实体

  2. internal(内部)

    在同一个源文件中的所有声明中都指向同一个实体,但位于不同源文件的多个声明则分属不同的实体

  3. 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:内存分配方式与动静态变量的更多相关文章

  1. [转载]C语言程序的内存分配方式

    "声明一个数组时,编译器将根据声明所指定的元素数量为数量为数组保留内存空间."其实就是编译器在编译的过程中,会加入几条汇编指令在程序里处理内存分配,并不是说编译时就分配了内存,不要 ...

  2. C语言数据在内存分配

    一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈.程序结束时由编译器自动释放 ...

  3. C语言变量声明内存分配

    转载: C语言变量声明内存分配   一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等.其操作方式类似于数据结 ...

  4. C语言中的内存分配与释放

    C语言中的内存分配与释放 对C语言一直都是抱着学习的态度,很多都不懂,今天突然被问道C语言的内存分配问题,说了一些自己知道的,但感觉回答的并不完善,所以才有这篇笔记,总结一下C语言中内存分配的主要内容 ...

  5. c语言中的内存分配malloc、alloca、calloc、malloc、free、realloc、sbr

    C语言跟内存分配方式 (1) 从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. (2) 在栈上创建.在执行函数时,函数内局部变 ...

  6. C++内存分配方式——小结

    1 内存分配方式 内存分配方式有如下三种: 从静态存储区域分配.内存在程序编译的时候就分配好了,这些内存在整个程序运行期间都存在,如全局变量.static变量等等. 在堆栈上分配.在函数执行期间,函数 ...

  7. C语言中动态内存分配的本质是什么?

    摘要:C语言中比较重要的就是指针,它可以用来链表操作,谈到链表,很多时候为此分配内存采用动态分配而不是静态分配. 本文分享自华为云社区<[云驻共创]C语言中动态内存分配的本质>,作者: G ...

  8. [c语言]c语言中的内存分配[转]

    在任何程序设计环境及语言中,内存管理都十分重要.在目前的计算机系统或嵌入式系统中,内存资源仍然是有限的.因此在程序设计中,有效地管理内存资源是程序员首先考虑的问题. 第1节主要介绍内存管理基本概念,重 ...

  9. c/c++内存分配方式(转)

    原文链接:http://blog.csdn.net/jing0611/article/details/4030237 1.内存分配方式 内存分配方式有三种: [1]从静态存储区域分配.内存在 程序编译 ...

随机推荐

  1. 【Pyecharts可视化分享】杭州步行热门路线等~

    前言 本文包括内容如下: 杭州步行热门路线 渐变效果散点图 均是Echarts官方提供等示例,本文将会通过Pyecharts来进行实现. 杭州步行热门路线 因为代码中需要调用百度地图,所以开始之前你需 ...

  2. 2019年3月最新可用KMS激活服务器地址

    更新日期:2019/3/6 kms.03k.org kms.chinancce.com kms.lotro.cc cy2617.jios.org kms.shuax.com kms.luody.inf ...

  3. Unsupervise-learning-notes

    K-means 数据是没有label的,按照数据之间的相似性进行分类 原理and步骤 是随机选取K个对象作为初始的聚类中心, 计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类 ...

  4. git项目分支管理

    分支管理 创建项目时,会针对不同环境创建两个常设分支(也可以算主分支,永久不会删除): master :生产环境的稳定分支,生产环境基于该分支构建.仅用来发布新版本,除了从 release 测试分支或 ...

  5. 错误 CS8107 C# 7.0 中不支持功能“xxxxxx”。请使用 7.1 或更高的语言版本。

    解决方法:项目右键属性 —> 生成 —> 找到最下面的高级按钮,点击高级按钮 —> 常规 —> 语言版本 —> 选择 C#最新次要版本,或者比当前版本更高的版本即可,点击 ...

  6. 【算法】用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

    public class Solution { Stack<Integer> stack1 = new Stack<Integer>(); Stack<Integer&g ...

  7. 关于JavaScript的原型继承与原型链

    在讨论原型继承之前,先回顾一下关于创建自定义类型的方式,这里推荐将构造函数和原型模式组合使用,通过构造函数来定义实例自己的属性,再通过原型来定义公共的方法和属性. 这样一来,每个实例都有自己的实例属性 ...

  8. 你写的 Python 代码总是不规范?用它!

    今天咱们来说说 代码风格 ! 不同的编程语言 有不同的代码风格 ​ ​ ​ ​ ​ Python 的代码规范 就是人们常说的 PEP8 ​ ​ 在这个网站 https://www.python.org ...

  9. laravel本地化扩展包的下载使用

    1.下载扩展包 composer require caouecs/laravel-lang:~3.0 2.下载完成之后在根目录下的vendor中caouces\src下就是语言的扩展包 2.1我们复制 ...

  10. 实用沙盒工具 —— VMware Workstation15安装教程

    一:简介 VMware Workstation(中文名"威睿工作站")是一款功能强大的桌面虚拟计算机软件,提供用户可在单一的桌面上同时运行不同的操作系统,和进行开发.测试 .部署新 ...