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

news2024/10/6 21:22:41

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;
	}
}

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

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

相关文章

【HuggingFace Transformer库学习笔记】基础组件学习:pipeline

一、Transformer基础知识 pip install transformers datasets evaluate peft accelerate gradio optimum sentencepiece pip install jupyterlab scikit-learn pandas matplotlib tensorboard nltk rouge在host文件里添加途中信息&#xff0c;可以避免运行代码下载模型时候报错…

为什么选择美国VPS服务器

企业、个人和组织都需要一个稳定高效的服务器来托管他们的网站、应用程序和数据。而对于中国用户来说&#xff0c;寻找一个性价比高的便宜美国VPS服务器&#xff0c;既能满足需求&#xff0c;又能节约成本&#xff0c;成为了一个非常重要的问题。 VPS即虚拟专用服务器&#xf…

【正点原子STM32连载】第五十九章 T9拼音输入法实验(Julia分形)实验 摘自【正点原子】APM32F407最小系统板使用指南

1&#xff09;实验平台&#xff1a;正点原子APM32F407最小系统板 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html## 第五十…

Java二级医院区域HIS信息管理系统源码(SaaS服务)

一个好的HIS系统&#xff0c;要具有开放性&#xff0c;便于扩展升级&#xff0c;增加新的功能模块&#xff0c;支撑好医院的业务的拓展&#xff0c;而且可以反过来给医院赋能&#xff0c;最终向更多的患者提供更好的服务。 系统采用前后端分离架构&#xff0c;前端由Angular、J…

JAVA线程池原理详解

线程池的优点 1、线程是稀缺资源&#xff0c;使用线程池可以减少创建和销毁线程的次数&#xff0c;每个工作线程都可以重复使用。 2、可以根据系统的承受能力&#xff0c;调整线程池中工作线程的数量&#xff0c;防止因为消耗过多内存导致服务器崩溃。 线程池的创建 public…

【ceph】如何打印一个osd的op流程,排查osd在干什么

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…

苍穹外卖-套餐分类

1. 新增套餐 1.1 需求分析和设计 产品原型&#xff1a; 业务规则&#xff1a; 套餐名称唯一套餐必须属于某个分类套餐必须包含菜品名称、分类、价格、图片为必填项添加菜品窗口需要根据分类类型来展示菜品新增的套餐默认为停售状态 接口设计&#xff08;共涉及到4个接口&…

【MySQL】数据库基础操作

&#x1f451;专栏内容&#xff1a;MySQL⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;前路未远&#xff0c;步履不停 目录 一、数据库操作1、创建数据库2、查看所有数据库3、选定指定数据库4、删除数据库 二、数据表操作1、创建数据表2、查看所有表3、…

Leetcode刷题之用队列实现栈(C语言版)

Leetcode刷题之用队列实现栈&#xff08;C语言版&#xff09; 一、题目描述二、题目要求三、题目示例四、题目解析Ⅰ、MyStack* myStackCreateⅡ、void myStackPush(MyStack* obj, int x)Ⅲ、int myStackPop(MyStack* obj)Ⅳ、int myStackTop(MyStack* obj)Ⅴ、bool myStackEmp…

你知道,葡萄酒不同的酿造工艺也能分类吗?

一串长在藤上的葡萄变成一杯美酒&#xff0c;是多么神奇的事情。而背后的魔法师就是葡萄酒的酿造工艺。经过数千年的酿酒经验累积&#xff0c;目前葡萄酒的种类繁多&#xff0c;酿造工艺也越来越多样化&#xff0c;不同的细节和工艺决定了不同形态的葡萄酒。所以&#xff0c;葡…

openEuler 22.03 LTS x86_64 cephadm 部署ceph16.2.14 【2】添加mon

接上篇 openEuler 22.03 LTS x86_64 cephadm 部署ceph18.2.0 未完成 笔记-CSDN博客 故障 /usr/libexec/podman/catatonit: no such file or directory [rootnode-1 ~]# cephadm bootstrap --mon-ip 10.47.76.94 --skip-pull Verifying podman|docker is present... Verifyin…

设置定时自动请求测试_自动定时循环发送http_post请求---postman工作笔记001

其实就是创建接口文件夹的时候,有个monitor collection 用来监听接口执行情况,这里就可以设置 可以看到多久执行一次对吧,这里可以设置每几分钟执行一次,一共执行多少次等等 但是这里要说明一下,如果需要使用monitor功能,必须需要登录, 所以如果这里点击monitor collection…

医保线上购药系统:代码驱动的医疗创新

医保线上购药系统&#xff0c;这是一个融合技术和医疗的创新典范。本文将通过简单的技术代码示例&#xff0c;为您揭示这一系统是如何通过技术驱动医疗创新&#xff0c;为用户提供更智能、便捷的健康管理体验的。 1. 前端界面开发 使用React框架&#xff0c;我们可以轻松构建…

工业以太网交换机的特点

交换机的使用范围非常广泛&#xff0c;可以说只有需要进行网络连接的地方&#xff0c;基本上都会与交换机有关。但是工业以太网交换机的适用范围相对较小&#xff0c;主要用于工业控制领域的以太网交换设备。工业以太网交换机拥有电信级的性能特征&#xff0c;能够适应苛刻的工…

【亚太杯B题论文已更新】2023年第十三届APMCM亚太地区大学生数学建模竞赛——(文末领取方式)

2023年第十三届APMCM亚太地区大学生数学建模竞赛——论文无偿分享&#xff01;&#xff01;&#xff01; B题第一问论文代码已出&#xff0c;其他赛题及后续论文代码会持续更新。 祝各位小伙伴都能在比赛中发挥出色&#xff0c;取得心仪的成绩呦&#xff01;一起加油&#xff…

java编程:使用递归 循环和位运算实现将10进制转为2进制

1 递归 /*** 递归&#xff1a;十进制转二进制* param decimal 待转换的十进制数* param binary 转换后的二进制数*/public static void decimalToBinaryByRecursion(int decimal,StringBuilder binary){if(decimal < 0){return;}decimalToBinaryByRecursion(decimal/2,bina…

用 VirtualBox 安装 OpenWrt 等 Linux 系统,无法启动的解决办法

用 VirtualBox 安装 OpenWrt 等 Linux 系统&#xff0c;无法启动的解决办法 最近新买了台联想小新 Pro 14 2023 锐龙版&#xff0c;因为有 32GB 的运行内存&#xff0c;所以想安装虚拟机以充分发挥。一开始使用 Hyper-V 来安装可以正常使用&#xff0c;但是后面想使用 Virtual…

数据库表结构导出成Excel或Word格式

前言 该工具主要用于导出excel、word&#xff0c;方便快速编写《数据库设计文档》&#xff0c;同时可以快速查看表的结构和相关信息。 本博客仅作记录&#xff0c;最新源码已经支持多种数据库多种格式导出&#xff0c;有兴趣的可移步源码作者地址&#xff1a;https://gitee.co…

基于LiteFlow构建实时会员权益体系

知识简介&#xff1a;通过LiteFlow规则引擎构建会员权益体系&#xff0c;实现权益节点可插拔&#xff0c;可编排&#xff0c;可复用的特性。完成会员权益数据底盘建设&#xff0c;将分散的权益数据集中&#xff0c;提升权益查询及管理水平。 历史痛点 1&#xff09;不同等级权…

Grafana 如何实现雷达图

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…