第九章的总结:
1.为了保持通用性,C++使用术语翻译单元,而不是文件,文件不是计算机组织信息时的唯一方式。
2.C++允许编译器使用自己的名称修饰,因此不同的编译器编译出来的二进制模块(对象代码文件),通常是无法链接的。
3.自动存储持续性:代码块内局部的变量,走过了就自动消失了。
静态存储持续性:程序开始,就一直存在,直到程序结束。起作用域看声明的位置。
线程存储持续性:并行编程用到,使用tread_local声明,则与线程同寿了。
动态存储持续性:用new来分配的内存,直到delete才回收。
4.在C++旧版本和C中,auto是用于显示声明自动存储的。但是因为自动存储在局部变量中是默认的,所以几乎没人使用。
在C++11之后auto这样的用法被删掉了,改成自动类型推断。
5.自动存储被放在栈中。
栈是用来对自动变量进行管理,之所以成为栈,就是新数据被象征性放在原有数据的上面。
栈是后进先出的。
栈使用两个指针,一个在底部,一个在顶部,上面的数据没用之后,顶部指针向下移动,之前的位置上的内容就不再被标记,但是没有删除的。
当下一个数据放入栈中的时候,就会覆盖刚刚的内容。
6.静态存储的变量,因为一直存在,所以编译器分配了固定的位置给它们。变量的每个元素或成员的默认值都是0。
7、内部链接和外部链接的问题
static修饰的变量只能在本文间内使用,其他文件不能调用。
8.使用了extern来声明的变量,没有分配内存,而且必须有一个文件内是真正定义的。
9.存储说明符
auto(C++11中已经不是说明符了)
register(C++11以前是指示寄存器存储,C++11之后就是显式支出自动变量)
static:静态存储
extern:外部变量
thread_local:线程变量,C++11新增的,可以与static或extern一起使用
mutable:声明这样的成员,表示即使变量为const,其属性也可以改变
cv-限定符:
const:常量
volatile:中文意思是可变的,多变的,声明了这个关键字的变量,可能即使不对其进行修改,其本身也会产生变化。
声明了volatile的变量,将不再放在寄存器中进行访问优化。
10.使用外部C语言库的时候,引用他们的函数可以用extern
extern “C” void spiff(int);
即使是同一个编译器,编译出的C和C++的链接语言也可能不同。因为C中没有重载,C++有重载,所以函数名肯定要复杂多。
11.通常编译器使用三块独立的内存:静态变量,自动变量(栈),动态变量(堆)。
12.using可以指定使用命名空间,可以指定使用命名空间中的某个属性。
命名空间可以起别名。
#include
using namespace std;
namespace First
{
int test = 1;
};
int test = 2;
int main()
{
using First::test;
cout << "test = " <//1
cout << ::test << endl;//2
return 0;
}
13、
(1)自动存储,自动成为自动变量,不需要特别声明。
(2)外联的静态存储,在一个文件中定义为外部变量,另一个文件中使用extern来声明。
(3)内联的静态存储,加上static来声明,也可以使用一个未命名的名称空间来定义。
(3)无链接的静态存储,在函数中声明,要加上static。
14、using声明和using编译
using声明,指定了特定的变量可用,在同一个代码块中不能再次声明同样名字的变量
using编译指令,使用整个命名空间,可以声明本地的同样名称的变量,会屏蔽外面的变量。
#include
//using namespace std;
/*
int main()
{
double x;
cout << "Enter value: ";
while (!(cin >> x))
{
cout << "Bad input ,Please input a num: ";
cin.clear();
while (cin.get() != '\n')
{
continue;
}
}
cout << "Vlaue = " << x << endl;
return 0;
}
*/
//after
int main()
{
double x;
std::cout << "Enter value: ";
while (!(std::cin >> x))
{
std::cout << "Bad input ,Please input a number: ";
std::cin.clear();
while (std::cin.get() != '\n')
{
continue;
}
}
std::cout << "Value = " << x << endl;
}
++++++++++++++++++++++++++++++++++++
#include
#include
/*
int main(int argc, const char *argv[])
{
double x;
cout << "Enter value: ";
while (!(cin >> x))
{
cout << "Bad input ,Please input a number:";
cin.clear();
while (cin.get() != '\n')
{
continue;
}
}
cout << "Value = " << x << endl;
return 0;
}
*/
int main()
{
using std::cin;
using std::cout;
using std::endl;
double x;
cout << "Enter value: ";
while (!(cin >> x))
{
cout << " Bad input ,Please input a number: ";
cin.clear();
while (cin.get() != '\n')
{
continue;
}
}
cout << " Value = " << x << endl;
}
++++++++++++++++++++++++++++++++++++++++++
//在不同文件中,不同时被include,就没有问题的。如果都要被include了,就只能引入命名空间了。
#ifndef _TEST1_H_
#define _TEST1_H_
namespace Test2
{
double aver(int a, int b)
{
return (a + b + 0.0) / 2;
}
}
#endif
#ifndef _TEST_H_
#define _TEST_H_
namespace Test1
{
int aver(int a, int b)
{
return (a + b) / 2;
}
}
#endif
#include
#include "test.h"
#include "test1.h"
using namespace std;
int main(int argc, char *argv[])
{
cout << Test1::aver(1, 2) << endl;
cout << Test2::aver(1, 2)<< endl;
return 0;
}
14、影藏命名空间
#include
using namespace std;
extern int x;
namespace
{
int y = -4;
}
void another()
{
cout << "another()" << x << "," << y << endl;
}
#include
using namespace std;
void other();
void another();
int x = 10;
int y;
int main()
{
cout << x << endl;
int x = 4;
cout << x << endl;
cout << y << endl;
other();
another();
return 0;
}
void other()
{
int y = 1;
cout << " Other: " << x << "," << y << endl;
}
15、命名空间与区域之间的关系
#include
using namespace std;
void other();
namespace n1
{
int x = 1;
}
namespace n2
{
int x = 2;
}
int main()
{
using namespace n1;
cout << x << endl;
{
int x = 4;
cout << x << "," << n1::x << "," << n2::x << endl;
}
using n2::x;
cout << "x = " << x << endl;
other();
return 0;
}
void other()
{
using namespace n2;
cout << "x = " << x << endl;
{
int x = 4;
cout << x << "," << n1::x << "," << n2::x << endl;
}
using n2::x;
cout << x << endl;
}
结果:
1
4,1,2
x = 2
x = 2
4,1,2
2
代码练习:
#ifndef _TEST_H_
#define _TEST_H_
const int len = 40;
struct golf
{
char fullname[len];
int handicap;
};
void setgolf(golf & g, const char *name, int hc);
int setgolf(golf & g);
void handicap(golf & g, int hc);
void showgolf(const golf & g);
#endif
#include "Test.h"
#include
using namespace std;
void setgolf(golf & g, const char *name, int hc)
{
strcpy_s(g.fullname, name);
g.handicap = hc;
}
int setgolf(golf & g)
{
cout << "Please enter fullname: ";
cin.get();
cin.getline(g.fullname, 40);
if (strcmp(g.fullname, " ") == 0)
{
return 0;
}
cout << "Please enter handicap: ";
cin >> g.handicap;
return 1;
}
void handicap(golf & g, int hc)
{
g.handicap = hc;
}
void showgolf(const golf & g)
{
cout << g.fullname << ": " << g.handicap << endl;
}
#include "Test.h"
#include
using namespace std;
int main(int argc, char *argv[])
{
golf g[5];
char str[40] = "";
int hc;
cout << "Please enter fullname: ";
cin >> str;
cout << "Please enter handicap: ";
cin >> hc;
setgolf(g[0], str, hc);
int num = 1;
for (int i = 1; i < 5; i++)
{
if (setgolf(g[i]) == 0)
{
break;
}
num++;
}
cout << "Show golf" << endl;
for (int i = 0; i < num; i++)
{
showgolf(g[i]);
}
return 0;
}