《C++PrimerPlus》第9章 内存模型和名称空间

9.1 单独编译

Visual Studio中新建头文件和源代码

通过解决方案资源管理器,如图所示:

分成三部分的程序(直角坐标转换为极坐标)

头文件coordin.h

#ifndef __COORDIN_H__ // 如果没有被定义过
#define __COORDIN_H__

struct polar {
	double distance;
	double angle;
};

struct rect {
	double x;
	double y;
};

polar rect_to_polar(rect xypos);
void show_polar(polar dapos);

#endif // 如果被定义过了(啥也不做)

源代码file1(放置main函数,调用其他函数)

#include <iostream>
#include "coordin.h" // 尖括号表明去系统目录找,双引号表明去当前目录找
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!" << endl;
	return 0;
}

源代码file2(其他函数的定义)

#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" << endl;
}

9.2 存储持续性、作用域和链接性

全局变量和局部变量

头文件support.h

#ifndef __SUPPORT_H__
#define __SUPPORT_H__
#include <iostream>

extern double warming; // 声明外部变量(不要赋值)

void update(double dt);
void local(void);

#endif

源代码external.cpp

#include <iostream>
#include "support.h"
using namespace std;

double warming = 0.3;

int main(){
	cout << "Global warming is " << warming << endl;
	update(0.1);
	cout << "Global warming is " << warming << endl;
	local();
	return 0;
}

源代码support.cpp

#include "support.h"
using namespace std;

void update(double dt) {
	warming += dt;
	cout << "Updating global warming to " << warming << endl;
}

void local(void) {
	double warming = 0.8; // 局部变量,只在local内部可见
	cout << "Local warming is " << warming << endl;
	// 作用域解析运算符(::),放在变量名前表示使用变量的全局版本
	cout << "But global warming is " << ::warming << endl;
}

static限定符用于全局变量

源代码twofile1.cpp

#include <iostream>
using namespace std;

int tom = 3;
int dick = 30;
static int harry = 300; // 仅在twofile1.cpp可见
void remote_access(void);

int main() {
	cout << "main() reports the following addresses: " << endl;
	cout << "&tom = " << &tom << endl;
	cout << "&dick = " << &dick << endl;
	cout << "&harry= " << &harry << endl;
	remote_access();
	return 0;
}

源代码twofile2.cpp

#include <iostream>
using namespace std;

extern int tom; // 声明为外部变量(来自twofile1.cpp)
static int dick = 10; // 只在twofile2.cpp中可见
int harry = 200; // 新建一个全局变量

void remote_access(void) {
	cout << "remote_access() reports the following addresses:" << endl;
	cout << "&tom = " << &tom << endl;
	cout << "&dick = " << &dick << endl;
	cout << "&harry= " << &harry << endl;
}

static限定符用于局部变量(统计字符串的字符个数)

#include <iostream>
using namespace std;

const int ArSize = 10;
void strcount(const char * str);

int main(){
	char input[ArSize];
	char next;
	cout << "Enter a line: " << endl;
	cin.get(input, ArSize);
	while (cin) {
		cin.get(next);
		// 如果输入的内容大于10个字符,则用cin.get全部消耗掉
		while (next != '\n')
			cin.get(next);
		strcount(input);
		cout << "Enter next line (empty line to quit):" << endl;
		cin.get(input, ArSize);
	}
	cout << "Bye!" << endl;
	return 0;
}

void strcount(const char * str) {
	// 局部变量加static,无论调用多少次这个函数,该变量只会在第一次初始化
	static int total = 0;
	int count = 0;
	while (*str) {
		count++;
		str++;
	}
	total += count;
	cout << count << " characters." << endl;
	cout << total << " characters total." << endl;
}

定位new运算符的使用

#include <iostream>
#include <new>
using namespace std;

const int BUF = 512;
const int N = 5;
char buffer[BUF];

int main(){
	double *pd1, *pd2;
	int i;
	cout << "Calling new and placement new: " << endl;
	// 用常规new运算符为N个double类型开辟内存空间
	pd1 = new double[N];
	// 用定位new运算符为N个double类型开辟内存空间
	pd2 = new (buffer) double[N];
	// 赋值
	for (int i = 0; i < N; i++) {
		pd2[i] = pd1[i] = 1000 + 20.0 * i;
	}
	cout << "pd1 = " << pd1 << ", buffer = " << (void *)buffer << endl;
	// 打印pd1和pd2的地址
	for (int i = 0; i < N; i++) {
		cout << pd1[i] << " at " << &pd1[i] << ";";
		cout << pd2[i] << " at " << &pd2[i] << endl;
	}

	cout << "\nCalling new and placement new a second time: " << endl;
	double *pd3, *pd4;
	pd3 = new double[N];
	pd4 = new(buffer) double[N]; // 会覆盖掉原来地址里的值
	for (int i = 0; i < N; i++) {
		pd4[i] = pd3[i] = 1000 + 40.0 * i;
	}
	for (int i = 0; i < N; i++) {
		cout << pd3[i] << " at " << &pd3[i] << ";";
		cout << pd4[i] << " at " << &pd4[i] << endl;
	}

	cout << "\nCalling new and placement new a third time: " << endl;
	delete[] pd1;
	pd1 = new double[N]; // 删了重新new(申请和之前相同的地方)
	pd2 = new(buffer + N * sizeof(double)) double[N]; // 地址往后偏移5个double类型的长度
	for (int i = 0; i < N; i++) {
		pd2[i] = pd1[i] = 1000 + 60.0 * i;
	}
	for (int i = 0; i < N; i++) {
		cout << pd1[i] << " at " << &pd1[i] << ";";
		cout << pd2[i] << " at " << &pd2[i] << endl;
	}

	delete[] pd1;
	delete[] pd3; // pd2和pd4是定位new开辟出来的,delete不能用于定位new
	return 0;
}

9.3 名称空间

当名称空间和声明区域定义了相同名称(伪代码)

namespace Jill{
    double bucket(double n) {...}
    double fetch;
    struct Hill {...};
}
char fetch; // 全局变量
int main(){
    using namespace Jill; // 使用using编译指令
    Hill Thrill; // 创建一个Jill::Hill 的结构
    double water = bucket(2); // 使用Jill::bucket()
    double fetch; // 不会出错,Jill::fetch被隐藏
    cin >> fetch; // 读入一个数据到局部变量fetch
    cin >> ::fetch; // 读入一个数据到全局变量fetch
    cin >> Jill::fetch; // 读入一个变量到Jill::fetch
    ...
}

int foom(){
    Hill top; // 会出错
    Jill::Hill crest; // 可用
}

名称空间示例(打印人名及欠款)

头文件namesp.h

#pragma once
#include <string>

namespace pers {
	struct Person {
		std::string fname;
		std::string lname;
	};
	void getPerson(Person &rp);
	void showPerson(const Person &rp);
}

namespace debts {
	using namespace pers;
	struct Debt {
		Person name;
		double amount;
	};
	void getDebt(Debt &rd);
	void showDebt(const Debt &rd);
	double sunDebts(const Debt ar[], int n);
}

源代码namessp.cpp

#include <iostream>
#include "namesp.h"

int main() {
	using debts::Debt;
	using debts::showDebt;

	Debt golf = { {"Micheal", "Jordan"}, 120.0 };
	showDebt(golf);
	return 0;
}

源代码namesp.cpp

#include <iostream>
#include "namesp.h" // 头文件放结构体类型、函数原型声明

namespace pers {
	using std::cout;
	using std::cin;

	void getPerson(Person &rp) {
		cout << "Enter first name: ";
		cin >> rp.fname;
		cout << "Enter last name: ";
		cin >> rp.lname;
	}
	void showPerson(const Person &rp) {
		cout << rp.lname << ", " << rp.fname;
	}
}

namespace debts {
	void getDebt(Debt &rd) {
		getPerson(rd.name);
		std::cout << "Enter debt: ";
		std::cin >> rd.amount;
	}
	void showDebt(const Debt &rd) {
		showPerson(rd.name);
		std::cout << ": $" << rd.amount << std::endl;
	}
	double sunDebts(const Debt ar[], int n) {
		double total = 0;
		for (int i = 0; i < n; i++) {
			total += ar[i].amount;
		}
		return total;
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

人工智能概论

一、关键技术 人工智能包含了七项关键技术: 1. 机器学习: 机器学习是研究计算机怎样模拟或实现人类的学习行为&#xff0c;以获取新的知识或技能&#xff0c;重新组织已有的知识结构使之不断改善自身的性能&#xff0c;是人工智能技术的核心。 从学习模式划分&#xff0c;分…

JMeter从入门到精通

1、 jmeter的介绍 jmeter也是一款接口测试工具&#xff0c;由java语言开发的&#xff0c;主要进行性能测试。 2、jmeter安装 jmeter官网下载链接&#xff1a; https://jmeter.apache.org/download_jmeter.cgi &#xff0c;查看是否安装成功【jmeter -v】 下载 java jdk1.8&…

漏洞复现--致远 M3 反序列化 mobile_portal RCE

免责声明&#xff1a; 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…

应用程序APP制作用Vue3CreateApp打包有什么优势?有哪些好处?

在当代的前端开发领域&#xff0c;Vue.js作为一个领先的JavaScript框架&#xff0c;一直处于技术革新和发展的前沿。Vue3作为该框架的最新版本&#xff0c;带来了更多的新特性和优化。在这些新特性中&#xff0c;createApp方法是一个非常值得关注的变化。对于开发者而言&#x…

redis相关题

1 什么是Redis Redis(Remote Dictionary Server) 是⼀个使⽤ C 语⾔编写的&#xff0c;开源的&#xff08;BSD许可&#xff09;⾼性能⾮关系型&#xff08;NoSQL&#xff09;的键值对数据库。Redis 可以存储键和五种不同类型的值之间的映射。键的类型只能为字符串&#xff0c;…

石油化工隐蔽设备AR可视化检修协助系统让新手也能轻松上岗

随着城市基础设施建设的不断推进&#xff0c;地下管线巡检工作的重要性日益凸显。传统的巡检方法已无法满足现代都市的高效运营需求。此时&#xff0c;地下管线AR智慧巡检远程协助系统应运而生&#xff0c;凭借其独特的特点与优势&#xff0c;为城市地下管线巡检带来了革命性的…

vue中的插槽用法(动态插槽)

vue中提供了一种通讯方式叫插槽>分为&#xff1a;默认插槽、具名插槽(作用域插槽) 1. 当一个组件有不确定的结构时, 就需要使用slot技术了 2. 注意: 插槽内容是在父组件中编译后, 再传递给子组件 3. 如果决定结构的数据在父组件, 那用默认slot或具名slot (1) 当只有一个不…

易石无代码开发:电商平台连接CRM与客服系统,实现营销自动化

易石无代码开发的优势 易石软件以其强大的无代码开发平台&#xff0c;为电商企业提供了一种全新的业务集成手段。在激烈的市场竞争中&#xff0c;电商平台必须不断优化其运营效率和客户服务质量。易石无需复杂的API开发&#xff0c;通过简单的配置就能实现电商平台与CRM、客服…

openGauss学习笔记-135 openGauss 数据库运维-例行维护-检查openGauss健康状态

文章目录 openGauss学习笔记-135 openGauss 数据库运维-例行维护-检查openGauss健康状态135.1 检查办法135.2 操作步骤135.3 异常处理 openGauss学习笔记-135 openGauss 数据库运维-例行维护-检查openGauss健康状态 135.1 检查办法 通过openGauss提供的gs_check工具可以开展o…

Python自动化测试——元素定位

1.selenium简介 Selenium是一个用于Web应用程序测试的工具。Selenium是直接运行在浏览器中&#xff0c;模拟用户操作web界面。支持多平台&#xff1a;windows、linux、MAC &#xff0c;支持多浏览器&#xff1a;ie、firefox、chrome等浏览器。 2. 启动浏览器 # 导入webdrive…

狗都会配的SNAT和DNAT配置

1 SNAT 1.1 SNAT SNAT原理与应用:. SNAT 应用环境:局域网主机共享单个公网IP地址接入Internet (私有IP不能在Internet中正常路由) SNAT原理:源地址转换&#xff0c;根据指定条件修改数据包的源IP地址&#xff0c;通常被叫做源映谢 SNAT转换前提条件: 1.局域网各主机已正确设…

计算机毕业设计|基于SpringBoot+MyBatis框架的电脑商城的设计与实现(系统概述与环境搭建)

计算机毕业设计|基于SpringBoot+MyBatis框架的电脑商城的设计与实现(系统概述与环境搭建) 该项目分析着重于设计和实现基于SpringBoot+MyBatis框架的电脑商城。首先,通过深入分析项目所需数据,包括用户、商品、商品类别、收藏、订单、购物车、收货地址,建立了数据模型。在…

美团三季报“外强中干”,二级市场叫好不叫座

11月28日&#xff0c;美团&#xff08;HK:03690&#xff09;发布截至2023年9月30日的业绩公告。财报显示&#xff0c;美团2023年第三季度的收入为764.67亿元&#xff0c;较2022年同期的626.19亿元增长22.1%&#xff1b;净利润为35.93亿元&#xff0c;同比增长195.3%。 在非国际…

ArcGIS制作广场游客聚集状态及密度图

文章目录 一、加载实验数据二、平均最近邻法介绍1. 平均最近邻工具2. 广场游客聚集状态3. 结果分析三、游客密度制图一、加载实验数据 二、平均最近邻法介绍 1. 平均最近邻工具 “平均最近邻”工具将返回五个值:“平均观测距离”、“预期平均距离”、“最近邻指数”、z 得分和…

【JMeter】菜单栏介绍

【菜单栏】 1. Tools 导入curl接口信息 作用&#xff1a;快速导入接口信息&#xff0c;响应头和缓存信息等 Log level临时修改日志等级 作用&#xff1a; 从勾选的level开始往更高等级level抓取log日志等级优先级&#xff1a; ALL < TRACE < DEBUG <INFO<WA…

内模原理与控制

基于模型的控制方法&#xff1a; 把外部作用信号的动力学模型植入控制器来构成高精度反馈控制系统的设计原理。 内模原理&#xff08;IMP&#xff09;指的是&#xff0c;想要实现对R(s)的无差跟踪&#xff0c;系统的反馈回路中需要包含一个与外部输入R(s)相同的动力学模型。通…

【设计模式】03:单例模式

单例模式 OVERVIOW 单例模式1.单例模式实现2.饿汉与懒汉&#xff08;1&#xff09;饿汉模式&#xff08;2&#xff09;懒汉模式 3.懒汉线程安全1&#xff08;1&#xff09;引入互斥锁&#xff08;2&#xff09;引入双重检查锁定&#xff08;3&#xff09;引入原子变量 4.懒汉线…

[Android]AlertDialog对话框

1.介绍AlertDialog AlertDialog是Android中常用的对话框组件之一&#xff0c;用于在应用程序中显示一些提示信息、警告、确认信息或者提供用户进行选择的界面。AlertDialog通常用于与用户进行交互&#xff0c;例如要求用户确认某个操作、输入一些信息或者从一组选项中选择一个。…

【Linux】Linux下的代码调试器 ---gdb

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和Linux还有算法 ✈️专栏&#xff1a;Linux &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵&#xff0c;希望大佬指点一二 …

高等数学上岸宝典笔记

①不单调的函数也可能有反函数 ②注意反函数与函数转换时的定义域与值域 ③收敛数列不一定有最值 收敛数列必有上界和下界&#xff0c;但不一定有最值&#xff0c;比如{An}1/n&#xff0c;下界为0&#xff0c;但永远取不到0 ④数列与其子数列的关系 例题&#xff1a; ⑤带根号…