本节书摘来自异步社区《C程序设计新思维》一书中的第6章,第6.1节,作者 【美】Ben Klemens,更多章节内容可以访问云栖社区“异步社区”公众号查看

第6章 玩转指针

C程序设计新思维
他就是那个

喜欢我们所有歌曲的人,

他喜欢一起哼唱,

他喜欢边开枪边唱,

但是他不知道这歌的意义。

——选自Nirvana的歌曲“In Bloom(风华正茂)”
就像一首描述音乐的歌曲、一部刻画好莱坞的电影,指针就是一种描述其他数据的数据。我们很容易被指针搞崩溃,像引用的引用、别名、内存管理和malloc之类的东西,很容易把我们搞得天旋地转。但是,这些纷繁复杂的痛苦可以分解为独立的片段。例如,我们可以使用指针作为别名,这样就不需要再关注malloc,20世纪90年代的教科书常教导我们需要熟练掌握这个函数。一方面,C语法中星号的用法常常令人困惑。另一方面,C的语法也向我们提供了工具,用于处理那些格外复杂的指针细节,例如函数指针。

6.1 自动、静态和手工内存

C提供了3种基本的内存管理模式,比大多数语言要多上2种,事实上我们真正需要关注的也只是其中一种。但是,在本书第12章中,我还要向读者介绍2种额外的内存模型。

自动

我们在第一次使用一个变量时对它进行声明,当离开自己的作用域之后变量就会被销毁。如果不使用static关键字,在函数内部所声明的所有变量都是自动变量。一般的编程语言只具有自动类型的数据。

静态

静态变量在程序的整个生命期内一直存在。数组的长度在一开始就是固定的,但它所包含的值却可以改变(因此它并不是完全静态的)。数据是在main函数启动之前被初始化的,因此所有的初始化值都必须是常量,并且不需要计算。在函数的外部所声明的(属于文件作用域)和函数内部用static关键字声明的变量都是静态变量。最后,如果忘了对一个静态变量进行初始化,它会默认初始化为全零(或NULL)。

手工

手工类型的变量涉及malloc和free函数,这也是许多段错误的根源。这种内存模型是让许多C编程员欲哭无泪的罪魁祸首。另外,这也是唯一允许在声明之后改变数组长度的内存类型。

下面这张表显示了三种内存模型的区别所在。在接下来的几章中,我们将详细讨论这些区别。


                       

表中有些特性适用于变量,例如改变长度和方便的初始化。有些特性是内存系统的技术性结果,例如是否可以在初始化时设置值。因此,如果我们想要一个不同的特性,例如能够在运行时改变长度,就不得不关注malloc函数和指针所指向的堆。如果我们可以抹掉这一切重新开始,我们就不会把这三组特性与相关联的技术性烦恼捆绑在一起。但是,我们必须面对这一切。

这些就是当我们把数据存放到内存时所浮现的相关问题。它与变量本身不同,可以产生另一层次的乐趣:

1.如果我们用static关键字在函数外部或者函数内部声明一个struct、char、int、double或其他类型变量,它就是静态的。否则,它们就是动态的。

2. 如果我们声明了一个指针,它本身具有一种内存类型,很可能如规则1所述的属于自动或静态类型。但是,这个指针可以指向三种数据类型的任何一种,包括指向由malloc函数所分配数据的静态指针和指向静态数据的自动指针。所有的组合都是可以成立的。


自己动手:检查一些现有的代码,研究变量的分类:哪些数据位于静态内存、自动内存或手动内存,哪些变量是指向手工内存的指针、指向静态值的自动指针等。如果手头上没有现成的代码,可以用例6-6为素材完成这个练习。


任何函数都在内存中占据一个空间,称为函数帧,用以保存与这个函数有关的信息,例如当函数执行完成之后返回到哪里,以及保存所有自动分配的变量的空间。

当一个函数(例如main)调用另一个函数时,第一个函数的函数帧中的活动就会暂停,并且一个新的函数被添加到这个堆栈帧中。当函数执行完成时,它的帧就从这个堆栈帧中弹出。在这个过程中,保存在这个函数帧中的所有变量都会消失。

遗憾的是,堆栈的长度限制要比一般内存小得多,大约是2~3M(本书写作时在Linux系统下大致如此)。这点空间对于保存莎士比亚的所有悲剧作品已经足够,因此不必担心分配一个包含10000个整数的数组会出现问题。但是,我们很可能会用到更大的数据集,因此需要使用malloc为它们在其它地方分配空间。

通过malloc所分配的内存并不位于堆栈中,而是在系统中称为堆的空间中。堆的大小可能有限制,也可能没有限制。在普通的PC机上,可以粗略地认为堆的大小就是所有可用内存的大小。

《C程序设计新思维》一第6章 玩转指针6.1 自动、静态和手工内存相关推荐

  1. 《C程序设计新思维》一6.3 不使用malloc的指针

    本节书摘来自异步社区<C程序设计新思维>一书中的第6章,第6.3节,作者[美]Ben Klemens,更多章节内容可以访问云栖社区"异步社区"公众号查看 ### 6.3 ...

  2. 如何学c语言程序设计,如何学好C语言 | 新思维:C语言程序设计

    C语言程序设计是信息技术专业的必修课,具有40多年的历史,经久不衰,足见其魅力和重要性. [C语言的重要性] C语言是目前世界上流行.使用最广泛的高级程序设计语言. C语言对操作系统和系统使用程序以及 ...

  3. 《JavaScript设计与开发新思维》——1.7 JavaScript编程目标

    本节书摘来自异步社区<JavaScript设计与开发新思维>一书中的第1章,第1.7节,作者:[美]Larry Ullman著,更多章节内容可以访问云栖社区"异步社区" ...

  4. 共同体不是c语言中的一个数据类型,《c语言程序设计教学资料》第12章---构体和共同体.ppt...

    <c语言程序设计教学资料>第12章---构体和共同体 向函数传递结构体 用结构体指针或结构体数组作为函数参数,向函数传递结构体的地址 按值调用 按地址调用 结构体变量作函数参数 实现按值调 ...

  5. 软考新思维--2017年上半年信息系统项目管理师上午试题分析与答案(试题1-5题)

    2017年上半年信息系统项目管理师上午试题分析与答案(试题1-5题) 1.信息系统是由计算机硬件.网络通讯设备.计算机软件,以及()组成的人机一体化系统. A.信息资源.信息用户和规章制度 B.信息资 ...

  6. 微信之父张小龙最新公开课曝光8个互联网新思维:下一个十年将非常有想象力...

    1月19日晚,在2021微信公开课PRO"微信之夜"上,张小龙做了一个半小时的演讲,分享了自己对于微信视频号.直播.以及微信产品十年的思考,还对下个版本的微信做了一些"剧 ...

  7. c语言程序设计常用思维,C语言程序设计中计算思维的思考①

    王鑫 李万军 摘   要:计算思维是运用计算机科学的基础概念去求解问题.设计系统和理解人类的行为.本文归纳了计算思维在C语言程序设计中的体现,可归纳为抽象计算思维.自动化计算思维和并行计算思维三种.针 ...

  8. 武汉理工大学新思维研究生英语课文翻译和课后习题答案(1~12单元)

    在学习期间,我们团队完成了<新思维研究生英语>全部12个单元的课文翻译和课后习题答案的整理工作. 其中课文翻译具有和原文一致的段落编号,课后习题答案不只是答案,我们还对习题的翻译进行了整理 ...

  9. 新思维研究生英语第1-12单元 课文翻译习题答案

    在学习期间,我们完成了<新思维研究生英语>全部12个单元的课文翻译和课后习题答案的整理工作. 其中课文翻译具有和原文一致的段落编号,课后习题答案不只是答案,我们还对习题的翻译进行了整理,更 ...

最新文章

  1. 简述事件接口与事件适配器的联系与区别_设计模式——适配器模式
  2. Webservice入门教程_用Eclipse的TCP_IP工具监听请求实现端口转接
  3. php搜索数据库设计,PHP数据库搜索功能设计
  4. 源码 连接mysql_MySql轻松入门系列————第一站 从源码角度轻松认识mysql整体框架图...
  5. 柯洁获清华大学免试入学推荐资格
  6. Centos7默认自带了Python2.7版本,但是因为项目需要使用Python3.x,这里提供一种比较快捷方便的安装方式...
  7. R语言ggplot2画图3
  8. 宇视相机怎样连接拾音器
  9. 算法题打卡-超人进化(剑指offer第一天)
  10. hao.360.cn不停跳....
  11. comsol-旋度的形象化概念
  12. background-image无法显示图片
  13. 微信小程序——瘦金社区
  14. 微型计算机usb接口工作方式,一种微型计算机的制作方法
  15. 计算机考试前的心情作文,考试前的准备中考优秀作文(精选7篇)
  16. 递归算法(二分查找)
  17. opencv mat 类型转换 CV_32FC1--CV_8U
  18. 微信小程序之间的参数传递、获取
  19. Android中的AlarmManager的使用
  20. 王老吉药业“关爱烈日下最可爱的人”公益活动在南京启动

热门文章

  1. SharePoint 2007有性能问题? 先试试这篇.
  2. ZT: Some lesser-known truths about programming
  3. Turn to Stone
  4. Drupal 修复远程代码执行漏洞
  5. Linux Shell常用技巧(四) awk
  6. sublime安装markdown
  7. 设计模式(Design pattern—
  8. 怎样看懂Oracle的执行计划
  9. Flask + Vue.js : Fullstack Development
  10. python switch语句的多种实现方法