《C++PrimePlus》第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/186190.html

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

相关文章

两巨头Facebook 和 GitHub 联手推出 Atom-IDE

9月13日&#xff0c;GitHub 宣布与 Facebook 合作推出了 Atom-IDE —— 它包括一系列将类 IDE 功能带到 Atom 的可选工具包。初次发布的版本包括更智能、感知上下文的自动完成&#xff1b;导航功能&#xff0c;如大纲视图和定义跳转(outline view and goto-definition)&#xf…

[UE4][C++]基于UUserWidget的一种序列图播放方法

最近在做一个大项目&#xff0c;鸽了几个月了....... 一、传统方法Flipbook 这种方法适合序列图较少的情况下、可以一个一个添加进来然后调整顺序。蓝图也比较友好可以直接设置很多属性和功能。这里简单了解一下即可&#xff0c;想要深入了解的同学可以自行搜索。 1.1创建Fli…

用 Addon 增强 Node.js 和 Electron 应用的原生能力

前言 Node.js Addon 是 Node.js 中为 JavaScript 环境提供 C/C 交互能力的机制。其形态十分类似 Java 的 JNI&#xff0c;都是通过提供一套 C/C SDK&#xff0c;用于在 C/C 中创建函数方法、进行数据转换&#xff0c;以便 JavaScript / Java 等语言进行调用。这样编写的代码通常…

大模型推理加速框架vllm部署的实战方案

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

【教学类-06-07】20231124 (55格版)X-X之间的加法、减法、加减混合题

背景需求 在大四班里&#xff0c;预测试55格“5以内、10以内、20以内的加法题、减法题、加减混合题”的“实用性”。 由于只打印一份20以内加法减法混合题。 “这套20以内的加减法最难”&#xff0c;我询问谁会做&#xff08;摸底幼儿的水平&#xff09; 有两位男孩举手想挑…

python——第十二天

内置模块或者其他模块学习方式&#xff1a; dir help os模块负责程序与操作系统的交互&#xff0c;提供了访问操作系统底层的接口&#xff1b;即os模块提供了非常丰富的方法用来处理文件和目录。 os&#xff1a; os.path 遍历C盘代码 import os from os import path def …

1|1111

1、指定在每天凌晨4&#xff1a;00将该时间点之前的系统日志信息&#xff08;/var/log/messages &#xff09;备份到目录下/backup&#xff0c;备份后日志文件名显示格式logfileYY-MM-DD-HH-MM 2、配置ssh免密登陆&#xff1a;客户端主机通过redhat用户基于秘钥验证方式进行远…

手写一个简单版的Spring

1. 创建一个工程及初始化 创建Java工程 创建对应的包 config&#xff1a;为配置类包 service&#xff1a;定义的将要被自己写的Spring容器管理的组件bean spring&#xff1a;里面定义自己写的Spring的类文件&#xff0c;包含子包anno注解包 test&#xff1a;定义测试类 2.…

springboot+vue基本微信小程序的外卖点餐平台系统

项目介绍 餐饮行业是一个传统的行业。根据当前发展现状&#xff0c;网络信息时代的全面普及&#xff0c;餐饮行业也在发生着变化&#xff0c;单就点餐这一方面&#xff0c;利用手机点单正在逐步进入人们的生活。传统的点餐方式&#xff0c;不仅会耗费大量的人力、时间&#xf…

C++入门第九篇---Stack和Queue模拟实现,优先级队列

前言&#xff1a; 我们已经掌握了string vector list三种最基本的数据容器模板&#xff0c;而对于数据结构的内容来说&#xff0c;其余的数据结构容器基本都是这三种容器的延申和扩展&#xff0c;在他们的基础上扩展出更多功能和用法&#xff0c;今天我们便来模拟实现一下C库中…

【OpenSTL】方便好用的时空预测开源库

OpenSTL&#xff1a;方便好用的时空预测开源库 时空预测学习是一种学习范式&#xff0c;它使得模型能够通过在无监督的情况下从给定的过去帧预测未来帧&#xff0c;从而学习空间和时间的模式。尽管近年来取得了显著的进展&#xff0c;但由于不同的设置、复杂的实现和难以复现性…

Go语言的学习笔记2——Go语言源文件的结构布局

用一个只有main函数的go文件来简单说一下Go语言的源文件结构布局&#xff0c;主要分为包名、引入的包和具体函数。下边是main.go示例代码&#xff1a; package mainimport "fmt"func main() { fmt.Println("hello, world") }package main就是表明这个文件…

AlDente Pro v1.22.2(mac电池最大充电限制工具)

AlDente Pro是一款适用于Mac操作系统的小工具&#xff0c;可以帮助您限制电池充电量以延长电池寿命。通常情况下&#xff0c;电池在充满的状态下会继续接受电源充电&#xff0c;这可能会导致电池寿命缩短。使用AlDente Pro&#xff0c;您可以设置电池只充到特定的充电水平&…

高清动态壁纸软件Live Wallpaper Themes 4K mac中文版功能

Live Wallpaper & Themes 4K mac是一款提供各种高清动态壁纸和主题的应用程序。该应用程序提供了大量的动态壁纸和主题&#xff0c;包括自然、动物、城市、抽象等各种类别&#xff0c;可以满足用户不同的需求。除了壁纸和主题之外&#xff0c;该应用程序还提供了许多其他功…

拦截器详解

一、概述 什么是拦截器&#xff1f; 是一种动态拦截方法调用的机制&#xff0c;类似于过滤器。Spring框架中提供的&#xff0c;用来动态拦截控制方法的执行。 到底是干啥用的&#xff1f; 拦截请求用的&#xff0c;在指定的方法调用前后&#xff0c;执行在拦截器中编写的程序 …

苹果App加急审核

苹果App加急审核 &#xff08;注意加急的次数&#xff0c;有的说一年能加急两次&#xff0c;有的说不止两次。遇到紧急问题了就用&#xff0c;非紧急 等一等也行&#xff09; 1.登录苹果账号 Sign In - Apple &#xff08; https://developer.apple.com/contact/app-store/?…

力扣每日一道系列 --- LeetCode 206. 反转链表

&#x1f4f7; 江池俊&#xff1a; 个人主页 &#x1f525;个人专栏&#xff1a; ✅数据结构探索 ✅LeetCode每日一道 &#x1f305; 有航道的人&#xff0c;再渺小也不会迷途。 LeetCode 206. 反转链表 思路一&#xff1a;头插 初始化两个指针&#xff0c;cur 和 newhead。…

单片机、ARM、嵌入式开发、Android 底层开发有什么关系?

单片机、ARM、嵌入式开发、Android 底层开发有什么关系&#xff1f; 从我目前的见识来看&#xff1a; 单片机是个系统&#xff08;比如&#xff1a;51、AVR、PLC...&#xff09;&#xff0c;其中包含了去除了输入输出之外的运算器、控制器、存储器&#xff0c;我们用程序可以非…

CANdelaStudio 使用教程3 新建Service

文章目录 简述Service 的相关配置项1、Protocol Services2、Diagnostic Class Templates3、Supported Diagnostic Classes 新建 Service1、新建 Service2、新建类并添加服务3、 选择支持的服务4、Diagnostic Class Templates&#xff1a;Identification 编辑 Service1、新增服务…

区块链技术将如何影响未来的数字营销?

你是否听腻了区块链和数字营销等流行语&#xff0c;却不明白它们对未来意味着什么&#xff1f;那么&#xff0c;准备好系好安全带吧&#xff0c;因为区块链技术将彻底改变我们对数字营销的看法。从建立消费者信任到提高透明度和效率&#xff0c;其可能性是无限的。 让我们来探…