稍稍看了会C++ Primer,然后把书中讲这部分的内容精简下。
先给大家说下自动变量,这个是在函数中用的,我个人认为是比较多的一中变量。自动变量的修饰符是(auto),但一般情况下我们忽略它,它是在代码块中被创建,当代码块结束就消失的一种变量。它是存放在堆栈中,所以可想而知,当堆栈结束后,变量也不在了。
接下来讲下自动变量中的寄存器变量,上面说了,变量放在堆栈中,所以会消耗内存,而寄存器变量则解决了这个问题,它需要在自动变量声明前加上一个“register”,这样编辑器就会去使用寄存器来处理变量。但记住一点,由于寄存器上没有地址,所以,对寄存器变量不能使用取地址符号。
接下来说一下静态变量。这个是我个人感觉很头疼的一种变量。
首先,静态存储持续性有三种链接性,1.外部链接性,2.内部链接性,3.无连接性。
下面上一张表格,里面介绍了五种存储方式。
存储描述 | 持续性 | 作用域 | 链接性 | 如何声明 |
自动 | 自动 | 代码块 | 无 | 在代码块中,(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++的类和对象的基本知识了,开始复习面向对象的技术了。等周末我继续更新博客。好晚。。写着写着差点睡着。。。