《Thinking in C++》学习笔记(一)【第二章】

第二章 对象的创建与使用

2.1语言的翻译过程

     翻译器分为两类:解释器(interpreter)和编译器(compiler)。

2.1.1解释器

     解释器将源代码转化成一些动作(它可由许多机器指令组成)并立即执行这些动作。

     解释器必须驻留内存以执行程序。

2.1.2编译器

     编译器直接把源代码转化成汇编语言或机器指令。

     分段编译(separate compilation):某些语言(如C语言)可以分别编译各段程序,最后使用连接器(linker)把各段程序连接成一个完整的可执行程序。

     人们把测试通过并能正常运行的程序块收集起来加入库(library)中,供其它程序员使用。

     源代码层的调试器(source-level debugger):通过跟踪程序经过源代码的进展来显示程序的执行情况。

2.1.3编译过程

      C/C++编译时首先要对源代码执行预处理。预处理器(preprocessor)是一个简单的程序,它用程序员定义好的模式代替源代码中的模式。预处理过的代码通常放在一个中间文件中。

      编译分两遍进行。首先对预处理过的代码进行语法分析。编译器把源代码分解成小的单元并把它们按树形结构组织起来——语法分析树

      使用全局优化器(global optimizer)来生成更短、更快的代码。

      编译的第二遍,由代码生成器(code generator)遍历语法分析树,把树的每个结点转化成汇编语言或机器代码。最后生成目标模块(.o或.obj文件)

      使用窥孔优化器(peephole optimizer)从相邻代码中查找冗余汇编语句。

      连接器(linker) 把一组目标模块连接成一个可执行程序,操作系统可以装载和运行它。当某一目标模块中的函数要引用另一目标模块中的函数或变量时,由连接器来处理这些引用,连机器还要添加一个特殊的目标模块来完成程序启动任务。

      连接器能搜索称为”库“的特殊文件来处理所有的引用。库将一组目标模块包含在一个文件中。

2.2.3.1静态类型检查(static type checking)动态类型检查(dynamic type checking)

       类型检查(type checking)是编译器在第一遍中完成的。

2.2分段编译工具

      程序分割的最基本的方法是创建命名子程序。C/C++里子程序成为函数(function),函数是一段代码段,可以将这些函数放在不同的文件中,并能分别编译。

      声明(declaration):“告知编译器”外部函数和数据的名称及它们的模样。“声明”是向编译器介绍名字——标示符。它告诉编译器这个函数或这个变量在某处可找到,它的模样像什么。而“定义”是说:“在这里建立变量或在这里建立函数”,它为名字分配存储空间。

      单一定义规则(one-definition rule):C/C++可以在不同的地方吗相同的变量和函数,但只能有一个定义。

2.2.1.1函数声明的语法

       在函数声明时,可以给出参数命,编译器会忽略这些参数命名。

       extern关键字:它表示变量是在文件以外定义的,或在文件后面部分才定义。

2.2.1.5包含头文件

       大部分库包含众多的函数和变量,为了减少工作量,确保一致性,当对这些函数变量做外部声明时,C/C++使用“头文件”(header file)。头文件是一个包含某个库的外部声明函数和变量的文件。

        包含头文件,要使用#include预处理命令,他告诉预处理器打开指定的头文件并在#include语句所在的地方插入头文件。#include有两种方式:

        (a)尖括号指定头文件:预处理器以特定的方式寻找文件,一般是环境中或编译器命令行指定的某种寻找路径。

        (b)双引号指定头文件:预处理器以“由实现定义的方式”来寻找文件,从当前目录开始寻找,如果文件没有找到就与按尖括号同样的方式重新寻找。

2.2.1.6标准C++ include语句格式

          标准使用的格式允许文件名长度可以大于8个字符,去除了扩展名。

          使用.h头文件是老的、非模板化的版本,而没有.h的文件是新的模板化版本。

2.2.2连接

          连接器把由编译器生成的目标模块(.o或.obj文件)连接成为操作系统可以加载和执行的程序。

2.2.3使用库文件

          连接器建立目标模块列表,把标示符加到“未解析的引用”列表中。如果遇到过函数或变量的定义,那么这就是已解决的引用,否则去查找库,把库中包含所需定义的模块加入连接。

           因为连接器按指定的顺序查找文件,用户使用与库函数同名的函数,被使用的是用户的函数而不是库函数,这可能是一个bug,C++名字空间禁止这样做。

2.2.3.2秘密的附加模块

          当创建一个可执行程序时,连接器会秘密连接某些模块。其中之一是启动模块,它包含了对程序的初始化例程,初始化例程建立堆栈,并初始化程序中的某些变量。

          连接器总是从标准库中查找程序中调用的经过编译的“标准”函数。标准库总可以被找到,只要程序中包含所需头文件就可以使用库中的任何模块,不要告诉连接器去找标准库,如果使用附加的库,必须把该库文件名添加到由连接器处理的列表文件中。

2.3.2名字空间

        namespace关键字:当程序达到一定规模后,函数名和标示符不够用,预防这种冲突的机制。

        using关键字:如果只包含头文件,编译器无法找到任何有关函数和对象的声明,要告诉编译器所使用的名字空间。

        对已经存在的代码提供向后兼容:#include<iostream.h> 相当于 #include<iostream>   using namespace std;

2.3.3程序的基本结构

        C的注释行以 “ /* ”开始,以“ */ ”结束,其中可以包含换行符。

        C++注释符“ // ”,注释从“ // ”开始,到换行符结束。

2.4.1字符数组的拼接

         如果两个加引号的字符数组邻接,并且它们之间没有标点,编译器就会 把这些字符数组连接成单个字符数组。

2.5字符串简介

          可以用“=”给string对象赋值

          连接string对象用“+”操作符

          将string加到一个string之后用“+=”操作符

2.6文件的读写

          头文件<fstream>,且自动包含<iostream>

          创建一个ifstream对象或ofstream对象

          getline()函数,第一个参数是ifstream对象,第二个参数是string对象。getline()将丢弃掉换行符。

           

//Copy one file to another,a line at a time
#include<string>
#include<fstream>
using namespace std;

int main()
{
   ifstream in("Scopy.cpp");
   ofstream out("Scopy2.cpp");
   string s;
   while(getline(in,s))
      out<< s <<"
";
}

2.7 vector简介

        在vector后追加一个新元素,可以使用成员函数push_back()

         元素可以由下标(indexing)选定

//Creating a vector that holds inergers
#include<iostream>
#include<vector>
using namespce std;

int main()
{
   vector<int> v;
   for(int i=0;i<v.size();i++)
       v.push_back(i);
   for(int i=0;i<v.size();i++)
        cout<<v[i]<<",";
    cout<<endl;
    for(int i=0;i<v.size();i++)
        v[i]=v[i]*10;         //Assignment
    for(int i=0;i<v.size();i++)
        cout<<v[i]<<",";
    cout<<endl;
}
原文地址:https://www.cnblogs.com/sage-blog/p/3857684.html