C++:C++PrimerPlus第六版:Chapter9:内存模型和名称空间

news2024/10/5 14:23:02

Chapter9:内存模型和名称空间

  • 1. C++源文件组织策略
    • 我们先看下面程序清单: coordin.h
    • main.cpp
    • Coordin.cpp
  • 2. 内存存储方案
  • 2.1 自动存储持续性
  • 2.2 静态存储持续变量
  • 2.3 存储方案和动态分配

本章节从三个大方面做总结

  1. C++多个源文件组织方式
  2. C++存储方案
  3. C++名称空间
    💚 在源文件组织方式这一章:我会分析总结C++关于多个源文件组织策略,在第二章:我会从C++存储持续性,作用域和链接性来分析存储模型,在第三章节:我会分析名称空间标识符使用,其中重点是第二章节。

1. C++源文件组织策略

我们先看下面程序清单:
coordin.h

#ifndef COORDIN_H_
#define COORDIN_H_
struct polar
{
	double distance;  // distance from origin
	double angle; // direction from origin
};

struct rect
{
	double x; // horizontal distance from origin
	double y; // vertical distance from oeigin
};

// prototypes
polar rect_to_polar(rect xypos);
void show_polar(polar dapos);
#endif

main.cpp

#include<iostream>
#include "coordin.h"  // structure templates function
using namespace std;
int main()
{
	rect rplace;
	polar pplace;
	cout<< "Enter the X and Y values: ";
	while(cin >> rplace.x >> rplace.y)
	{
    	pplace = rect_to_polar(rplace);
    	show_polar(pplace);
    	cout << "Next two numbers(q to quit):";
    }
    cout << "Bye ! \n";
    return 0;
}

Coordin.cpp

#include<iostream>
#include<cmath>
#include "coordin.h"  
polar rect_to_polar(rect xypos)
{
	using namespace std;
	polar answer;
	answer.distance = sqrt(xypos.x * xypos.x + xypos.y * xypos.y);
	answer.angle = atan2(xypos.y,xypos.x);
	return answer;
}

void show_polar(polar dapos)
{
	using namespace std;
	const double Rad_to_deg = 57.29577951;
	cout << "distance = " << dapos.distance;
	cout<< ", angle = " << dapos.angle * Rad_to_deg;
	cout << " degrees\n";
}

💚 下面我们通过 “ g++ ” 编译指令来编译链接 main.cpp 和 coordin.cpp 两个源文件。
在这里插入图片描述
注意点:

  1. 在同一个源文件cpp中 只能将同一个头文件包含一次,所以 coordin.h 使用: #ifndef 和 # endif 语句 ,如果没有使用预处理器编译指令 #define 定义的名称 COORDIN_H 时,才处理 #ifndef 和 # endif 之间的语句。
  2. 虽然我们讨论的是根据文件进行单独编译,但是为了保持通用性,C++标准使用了术语翻译单元 (translation unit),而不是文件。

2. 内存存储方案

首先我们介绍变量在内存的时间,即生命周期。
有四种不同方案来存储数据。

  • 自动存储持续性:在函数定义中声明的变量(包括函数参数)的存储持续性为自动的。他们在程序开始执行其所属函数或代码块中被创建,在执行完函数或代码块时,他们使用的内存被释放。通常意义上,我们把这称之为:栈变量C++ 有两种存储持续性为自动的变量
  • 静态存储持续性:在函数定义外定义的变量和 关键字 static 定义的变量的存储持续性都称为静态,他们在整个程序运行过程中都存在。C++有三种存储持续性为静态的变量
  • 线程存储持续性:当前,多核处理器很常见,这些CPU可以处理多个任务,这让程序能够将计算放在可并行处理的不同线程中,如果变量时使用关键字 thread_Local 声明的,则其生命周期与所属线程一样长。
  • 动态存储持续性:用 new 运算符分配的内存将一直存在,直到使用 delete运算符将其释放或程序结束为止,这种内存的存储持续性为动态,有时被称为 自由存储或堆。

💚💚💚
下面介绍变量的作用域(可被程序使用)以及链接性的细节。
作用域(ascope 😃
描述了名称在文件(翻译单元)的多大范围内可见: 例如 :函数中定义的变量可在该函数中使用,但不能在其他函数中使用。
链接性(linkage):
描述了名称如何在不同单元间共享,链接性为外部的名称可在文件间共享,链接性为内部的名称只能由一个文件中函数共享,例如:自动变量的名称没有链接性,因为它们不能共享。

💚

  1. 自动变量的作用域为局部。
  2. 静态变量的作用域为全局还是局部:这取决于变量该如何定义。如:在函数原型作用域定义,作用域为局部。 在类中声明的成员的作用域为整个类,在名称空间中声明的变量作用域为 整个名称空间。

2.1 自动存储持续性

默认情况下,函数中声明的函数参数和变量的存储持续性为自动,作用域为局部,没有链接性。
💚 自动变量的初始化

int w;   // value of w is 模糊
int x = 5;  // initialized with a numeric literal
int big = INT_MAX-1;  // initialized with a constant expression
int y = 2*x;  // use previously determined value of x
int z = 3*w;  // use new value of w 

💚 自动变量和栈
例子:定义函数 fib(int real, long tell) ,我们来看下 函数栈运行流程。
注意:程序中使用两个指针来跟踪栈,一个指针指向栈底:栈的开始位置,一个指针指向栈顶:下一个存储单元。
在这里插入图片描述

2.2 静态存储持续变量

C++ 为静态存储持续性变量提供了3种 链接性:

  • 外部链接性(可在其他文件中访问)
  • 内部链接性(只能在当前文件中访问)
  • 无链接性(只能在当前函数或代码块中访问)
    这三种链接性都在整个 程序中存在,与自动变量相比,它们的寿命更长。
    🧡重点:由于静态变量的数目在程序运行期间是不变的,因此程序不需要使用特殊装置(如栈)来管理他们,编译器将分配固定的内存块来存储所有的静态变量,这些变量在整个程序执行期间一直存储。
    下面,我们有一个图来说明,如何创建上述三种变量。
    在这里插入图片描述
    🧡 静态变量的初始化
    除默认的零初始化外,还可对静态变量进行常量表达式初始化和动态初始化。
    零初始化:意味着将变量设置为零,对于标量类型,零将被强制转换为合适的类型。 如: 空指针用0表示,结构成员被零初始化,填充位将都被设置为零。
    常量初始化:变量设置为常量
    🧡零初始化和常量初始化决定因素
    零初始化和常量初始化都被称为静态初始化,首先,所有静态初始化都被零初始化,不管程序员是否显示初始化了它,接下来,如果使用常量初始化,编译器将指针常量表达式。
#include<cmath>
int x;    // zero-initialization
int y = 5;  // constant ant-expression initialization
long z = 13*13;  // constant ant-expression initialization
int enough = 2*sizeof(long);  // constant expression initialization
// 因为:pi 的计算需要链接 函数 atan()且被执行时,才能计算出来,它被称为动态初始化
const double pi = 4.0*atan(1.0);// dynamic initialization

💚 💚静态持续性,外部链接性
链接性为外部的变量通常简称为 外部变量,它们的存储持续性为静态(整个程序生命周期),作用域为整个文件。
这里有一个概念:单定义规则
一方面,在每个使用外部变量的文件中,都必须声明它,另一方面,C++中有 “单定义规则(one definition Rule ODR)”,该规则指出,变量只能定义一次,为了满足这种需求,C++提供了两种变量声明:

  1. 定义声明(defining declaration):或简称定义(declaration) 它给变量分配存储空间,
  2. 引用声明(referencing declaration ):或简称声明declaration 它不给变量分配存储空间,因为它引用已有变量
  3. 引用声明使用关键字 extern, 且不进行初始化,否则,声明即为定义,导致分配存储空间。
double up;  // definition, up is 0
extern int blem;  // blem defined else where
extern char gr = 'z'; // definition because initialized

下面例子说明了,如果要在多个文件中使用外部变量,只需要在一个文件中定义该变量,且在使用该变量的文件中,必须使用关键字 extern。
在这里插入图片描述

💚 💚静态持续性,内部链接性
将 static限定符用于作用域为整个文件的变量时,该变量的链接性为内部,存储持续为静态(整个程序生命周期)
在这里插入图片描述
💚💚静态存储持续性,无链接性
这种变量是这样创建的:将static 限定符用于代码块中定义的变量,这将会使局部变量的存储持续性为静态(扩展了变量生命周期),但它无链接性,作用域仅限于代码块。
🧡 初始化:程序只在启动时进行一次初始化,以后再调用函数,并不会像自动变量再次初始化

2.3 存储方案和动态分配

前面我们谈了C++变量静态存储和自动存储模型,下面我们来讲讲C++运算符 new(或者C函数 malloc()) 分配的内存,这被称为动态内存。
动态内存由运算符 new/delete 控制,不是由作用域和链接性规则控制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/517217.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

案例告诉你 ChatGPT 最有可能取代哪些职业

ChatGPT 的应用场景ChatGPT 最可能取代哪些职业&#xff1f;写在最后 ChatGPT 的应用场景 ChatGPT 的应用场景大体上可以归类为三大模块。 第一类是 代码相关 的任务场景。包含程序语言之间的相互转换&#xff08;如 python 转 java&#xff09;、程序命令的生成、代码 bug 的…

考虑多能负荷不确定性的区域综合能源系统鲁棒规划(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

单链表OJ题:LeetCode--21.合并两个有序链表

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;今天给大家带来的是LeetCode中876题&#xff1a;链表的中间结点 数 据 结 构&#xff1a;数据结构专栏 作 者&#xff1a;stackY、 C 语 言 &#xff1a;C语言专栏 LeetCode &#xff1a;LeetCode刷题训练营 L…

5月16日,亚马逊云科技邀你一起探索游戏的无限可能

游戏精品化趋势越发明显&#xff0c;如何才能让技术帮助创意更好地实现&#xff1f;游戏出海如火如荼&#xff0c;如何才能在全球市场分一杯羹&#xff1f;生成式AI横空出世&#xff0c;如何才能充分利用&#xff0c;实现降本增效、利润提升&#xff1f;相信每个游戏人&#xf…

Word控件Spire.Doc 【文本框】教程(3):如何在 Word 中插入或删除文本框

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…

基于VC + MSSQL实现的县级医院医学影像PACS

一、概述&#xff1a; 基于VC MSSQL实现的一套三甲医院医学影像PACS源码&#xff0c;集成3D后处理功能&#xff0c;包括三维多平面重建、三维容积重建、三维表面重建、三维虚拟内窥镜、最大/小密度投影、心脏动脉钙化分析等功能。 二、医学影像PACS实现功能&#xff1a; 1、…

漏洞分析丨CVE-2012-1873

一、漏洞简述 cve-2012-1873同样是一个著名的堆溢出漏洞&#xff0c;他是IE6-8中MSHTL.dll中的CTableLayout::CalculateMinMax函数里&#xff0c;程序在执行时会以HTML代码中的元素span属性作为循环控制次数向堆中写入数据。第一次会优先根据span申请堆空间&#xff0c;当我们…

【企业信息化】第3集 免费开源ERP: Odoo 16 POS终端管理系统

文章目录 前言一、概览二、硬件三、使用功能 前言 世界排名第一的免费开源ERP: Odoo 16 POS终端管理系统。几分钟内完成设置&#xff0c;几秒内完成销售。 一、概览 Odoo POS 基于智能界面&#xff0c;任何零售公司均可毫不费力地使用 因为其极具灵活性&#xff0c;您可配置 …

2023最全 Java 高频面试合集,掌握这些你也能进大厂!

进大厂是大部分程序员的梦想&#xff0c;而进大厂的门槛也是比较高的&#xff0c;所以这里整理了一份阿里、美团、滴滴、头条等大厂面试大全&#xff0c;对于 Java 后端的朋友来说应该是最全面最完整的面试备战仓库&#xff0c;为了更好地整理每个模块&#xff0c;我也参考了很…

版本控制器git

目录 一、版本控制系统 二、工作流程和使用命令 &#xff08;1&#xff09;工作流程 &#xff08;2&#xff09;一次完整流程的相关命令 1.初始化1个空的本地仓库 2.克隆方式1个远程仓库到本地仓库 3.新文件添加到暂存区 4.查看仓库状态&#xff0c;显示有变更的文件 5…

Java实现杨辉三角

1 问题 实现杨辉三角。 2 方法 public class textttt01 { public static void main(String[] args) { //定义了一个长度为10&#xff0c;高度为10的二维数组&#xff0c;数组中的值都为0&#xff1b; int[][] arrnew int[10][10]; for (int i0;i<ar…

开源轻量级 IM 框架 MobileIMSDK 的Uniapp客户端库已发布

一、基本介绍 MobileIMSDK-Uniapp端是一套基于Uniapp跨端框架的即时通讯库&#xff1a; 1&#xff09;超轻量级、无任何第3方库依赖&#xff08;开箱即用&#xff09;&#xff1b;2&#xff09;纯JS编写、ES6语法、高度提炼&#xff0c;简单易用&#xff1b;3&#xff09;基于…

html实现经典捕鱼达人小游戏

文章目录 1.设计来源1.1 游戏界面 2.效果和源码2.1 动态效果2.2 源代码 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/130638634 html实现经典捕鱼达人小游戏源码 &#xff0c;99.99%的还原实物&#xff0c;起…

【办公】解决京瓷打印机总是出现烦人的“在手送纸盘中装纸 彩色纸”的问题

问题 打印机是日常办公的常见工具&#xff0c;京瓷是著名的打印机品牌&#xff0c;而且是很多事业单位首选的打印机品牌。然而在日常使用中京瓷打印机总是会出现烦人的“在手送纸盘中装纸 彩色纸”的问题&#xff0c;如下图所示&#xff1a; 一旦出现该问题&#xff0c;就需要…

给XZZ准备的小攻略(私人向)

定时发送邮件功能&#xff1a; 定时发送邮件的功能位于 homework 的 views.py 中 使用的模块是 apscheduler &#xff08;我读作ap司改就&#xff09; 准备的部分&#xff1a;&#xff08;了解即可&#xff09; 安装好 django-apscheduler 后&#xff0c;在 setting.py 中添…

python 调用golang 注意事项

1.调用编译后的动态库文件&#xff0c;报头文件错误 原因&#xff1a; 不同平台下编译的add.so 不能通用&#xff0c;Windows下可以运行的so文件&#xff0c;linux下就不能运行&#xff0c;需要重新编译linux的so文件&#xff1b; 该报错可能就是跨平台使用动态库文件了&…

yolov5爬坑小作文

第一坑 做完训练集&#xff0c;配置要yaml文件后&#xff0c;笔者启动了训练命令 python train.py --data 我的yaml位置 --batch-size 我的每次进行一次反向传播之前需要前向计算的图片张数 --device 我的GPU编号 之后报错 OSError: [WinError 1455] 页面文件太小,无法完成…

检测数据类型

//typeof() 对于基本数据类型没问题&#xff0c;遇到引用数据类型不管用 console.log(typeof 666) //number console.log(typeof [1,2,3]) //object //instanceof() 只能判断引用数据类型&#xff0c;不能判断基本数据类型 console.log( [] instanceof Array) //true …

Acunetix 15.6 (Linux, Windows) - Web 应用程序安全测试

Acunetix 15.6 (Linux, Windows) - Web 应用程序安全测试 请访问原文链接&#xff1a;https://sysin.org/blog/acunetix-15/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Acunetix 漏洞扫描器&#xff0c;管理您的网络安全。…

电脑待机怎么设置?分享4个宝藏方法!

案例&#xff1a;电脑待机怎么设置 【有时候我使用电脑时可能因为各种事而被打断&#xff0c;但是不是很想让电脑关机&#xff0c;请问大家电脑待机时间应该怎么设置呀&#xff1f;】 有时候我们在使用电脑时可能需要做别的一些事&#xff0c;这时我们的电脑会进入待机状态。…