c++primer读书笔记(5)

第九章的总结:
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;
}

你可能感兴趣的:(c++primer读书笔记(5))