C++中参数的持续性,作用域和连接性。

稍稍看了会C++ Primer,然后把书中讲这部分的内容精简下。

先给大家说下自动变量,这个是在函数中用的,我个人认为是比较多的一中变量。自动变量的修饰符是(auto),但一般情况下我们忽略它,它是在代码块中被创建,当代码块结束就消失的一种变量。它是存放在堆栈中,所以可想而知,当堆栈结束后,变量也不在了。

接下来讲下自动变量中的寄存器变量,上面说了,变量放在堆栈中,所以会消耗内存,而寄存器变量则解决了这个问题,它需要在自动变量声明前加上一个“register”,这样编辑器就会去使用寄存器来处理变量。但记住一点,由于寄存器上没有地址,所以,对寄存器变量不能使用取地址符号。

接下来说一下静态变量。这个是我个人感觉很头疼的一种变量。

首先,静态存储持续性有三种链接性,1.外部链接性,2.内部链接性,3.无连接性。

下面上一张表格,里面介绍了五种存储方式。

5种变量储存方式
存储描述持续性作用域链接性如何声明
自动自动代码块在代码块中,(auto)
寄存器自动代码块在代码块中,用register
静态,无连接性静态代码块在代码块中,用static
静态,外部链接性静态文件外部在函数外面
静态,内部链接性静态文件内部在函数外面,使用关键字static

我先贴这些上来,相信大家也都能看懂些,时间不早了,先睡觉去,明天晚上下班后,接着补充,到时候给大家上几段代码,然后介绍下命名空间,其实也是一种作用域。嘿嘿,先挖个坑在这,明天来填坑,啊不对。。12点了,是今天晚上。。。

继续更新,接下来贴一段静态修饰的,外部链接性的例子

#include <iostream>

using namespace std;
//注意warming变量
double warming = 0.3;				//全局变量 称为定义,给变量分配存储空间

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

int main(){
	cout << "Global warming is " << warming << " degrees.\n";
	update(0.1);
	cout << "Global warming is " << warming << " degrees.\n";
	local();
	cout << "Global warming is " << warming << " degrees.\n";
	return 0;
}

void update(double dt)
{
	extern double warming;			//引用外部变量  为0.3	称为声明,不给变量分配存储空间
	warming += dt;
	cout << "UPdating gloabal warming to " << warming;
	cout << " degrees.\n";
}

void local()
{
	double warming = 0.8;			//隐藏了外部变量 为0.8
	cout << "Local warming = " << warming << " degrees.\n";
	cout << "the global waming is " << ::warming; 
}

这个注释蛮清楚了,最好运行下自己看看。

下面两段代码是静态修饰,内部链接性的例子

file1.cpp

#include <iostream>

int tom = 3;				//
int dick = 30;				//
static int harry = 300;		//内部链接性,只在该函数内部可用。

void remote_access();

int main()
{
	using namespace std;
	cout << "main()reports the following addresses: \n";
	cout << &tom << " = &tom, " << &dick << " = &dick, ";
	cout << &harry << " = &harry\n";
	cout << tom << ' ' << dick << ' ' << harry << ' ' << endl;		// 3 30 300
	remote_access();
	return 0;
}

file2.cpp

#include <iostream>

extern int tom;
static int dick = 10;			//内部链接性
int harry = 200;

void remote_access()
{
	using namespace std;
	cout << "remote_access() reports the following address: \n";
	cout << &tom << " = &tom, " << &dick << " = &dick, ";
	cout << &harry << " = &harry\n";
	cout << tom << ' ' << dick << ' ' << harry << ' ' << endl;		// 3 10 200
}

如果你运行了程序会发现,tom的地址在两个文件是一样的,但是呢,另两个变量地址不同,所以extern被认为是引用,不给这个变量分配空间。一般的,如果在一个文件定义一个外部链接性变量,另一个文件不使用extern,而是重新定义它,那就会报错。

接下来介绍下无链接性的静态变量。

#include <iostream>

const int ArSize = 10;

void strcount(const char * str);

int main()
{
	using namespace std;
	char input[ArSize];
	char next;

	cout << "Enter a line: \n";
	cin.get(input, ArSize);
	while(cin)
	{
		cin.get(next);
		while(next != '\n')
			cin.get(next);
		strcount(input);
		cout << "Enter next line (empty line to quit): \n";
		cin.get(input, ArSize);
	}
	cout << "Bye\n";
	return 0;
}

void strcount(const char * str)
{
	using namespace std;
	static int total = 0;			//静态存储,无链接性,作用域在函数中,但生命周期是整个文件,所以只经过一次初始化
	int count = 0;					//每次执行函数都重新初始化这个变量
	
	cout << "\""  << str << "\" contains ";
	while(*str++)
		count++;
	total += count;
	cout << count << " characters\n";
	cout << total << " characters total \n";
}

static 声明的变量生命周期在整个文件中,但作用域只在声明的代码块中。

这个例子最好自己运行下,多动手就理解了。

接下来再简单说下const,在全局定义const就类似使用static说明符。如果要让一个常量的链接性为外部的,那么就用extern来覆盖原有的内部链接性。如 extern const int state = 10;

在C++中,针对函数有个单定义规则,对每个非内联函数,程序只能包含一个定义,对于链接性为外部的函数来说,意味着在多文件程序中,只有一个文件包含该函数定义,但使用该函数的每个文件都应包含函数原型。

下面简单说下布局new操作符,它可以指定要使用的位置,例如可以声明一个char型数组 buffer[100]然后使用布局new操作符来初始化,int *p = new (buffer)int[20];则说明了,p指向的数组放在了Buffer[]中,p的首地址就是buffer数组的首地址。

紧接着介绍下命名空间,命名空间不能位于代码块中。

namespace Jill{
    int x;
}
接下来访问命名空间的名称,有两种方式,一种称为using声明,还一种称为using编译指令。

两者的不同是编译指令会使整个命名空间可用,但是using声明不会,他只是该用哪就用在哪,因为使用using编译指令的话,当出现了同名的局部变量则会覆盖命名空间里的变量。像上面的命名空间,using声明表示为 using Jill::x,using namespace Jill则是using编译指令。还有一种是没有命名的名称空间,如

namespace
{
    int y;
}
像这样的名称空间可以用来替代链接性为内部的静态变量。(最好用名称空间)。

可能听着晕乎乎的,还是上代码。答案我写在注释里了

#include <iostream>
using namespace std;
void other();
namespace n1
{
	int x = 1;
}

namespace n2
{
	int x = 2;
}

int main()
{
	using namespace n1;
	cout << x << endl;			// 1
	{
		int x = 4;
		cout << x << ", " << n1::x << ", " << n2::x << endl;	// 4, 1, 2
	}
	using n2::x;
	cout << x << endl;			// 2
	other();
	return 0;
}

void other()
{
	using namespace n2;
	cout << x << endl;			// 2
	{
		int x = 4;
		cout << x << ", " << n1::x << ", " << n2::x << endl;	// 4, 1, 2
	}
	using n2::x;
	cout << x << endl;			// 2
}
好了,先介绍到这,这周我开始看C++的类和对象的基本知识了,开始复习面向对象的技术了。等周末我继续更新博客。好晚。。写着写着差点睡着。。。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值