跳至主要內容

01. 编程语言

LincZero大约 11 分钟

01. 编程语言

预备知识

学习资料、查阅文档

进度笔记

  • 《C++ Primer Plus 第六版 中文版》
    • 书理解至577页(不包含跳过部分,详见书本剪角)
    • 笔记更新至518页
  • 《Effective C++》&《深度探索C++对象模型》
    • 还没看

文档资源

学习用书

(By CodeSheep推荐)

顺序书名补充
第一本《Essential C++》适合由c过渡到c++
第二本《C++ Primer第四版》【圣经级别】内容很全,但不深
不是第六版plus,不是同一本书!
第三本《Effeetive C++》55个改善程序
第四本《More Effeetive C++》35个改善程序
第五本《C++ 标准程序库》
第六本《深入探索C++对象模型》

《C++ Primer Plus第六版》书评:

  • 内容挺新的,比教科书新多了,各种新特性

  • 大量文字描写类,文字绕口,如p266标注处

    有点类似于文字打乱不影响阅读那种,但前提是你知道他本来的意思,而不是一种新知识

    有时你本来懂的,都被他的文字描述给绕晕了,如p440第二点的第一句,如p455倒数第4段的“无效”和“补救”

深入资料

语言本身

语言风格、书写风格

基本同C

评价:

  • 工具多而杂

    • 特别是类那一块,非常非常非常多的零散知识和零散语法

      比如:类成员函数、this指针、类作用域、explicit限定等等等等

  • 有很多“专门解决方案”(“缺陷补救方案”)(“缺陷补丁”)

    • 即为解决一个零碎的小问题而专门引用一种新语法或关键字来解决

      比如:explicit、虚基类

  • C++的非默认原则

    • 不需要用的东西不提供给你,不进行默认设置

      这导致了写的时候经常要根据不同情况增加不同的关键字或切换其他语法

    • 比如:虚函数不是默认的方式,虚基类不是默认的方式

    • C++的理念是只有在需要的情况下使用动态联编,其他情况一律使用静态联编

      它并不像C语言那样通常使用静态联编,也不像动态类型的脚本语言那样可以随意使用动态联编

      它是时用时不用,而使用的时候又需要使用一套与原来不同的新的写法

  • 非常多能交叉的东西

    • 比如指针、数组、new、类等都能和其他一堆东西结合,形成一些复合的东西,衍生物非常非常多

      主要是有的东西不是单纯的结合罢了,结合的过程当中还会诞生新的语法

      比如:作用域为类的常量、静态类成员函数

  • 语言设计的不对称感非常强

    • 不对称,导致不美观,而且很别扭

    • 比如:同样是定义A+x的行为,当A+xx+A是两种不同的写法

      • 前者使用成员函数+operator,后者使用非成员函数+友元函数+operator

        (虽然前者也可以写成后面一种形式)

    • 比如:同样是定义类型转换的行为,A<-xx<-A是两种不同的写法

      • 前者使用接受单参数的构造函数,后者使用转换函数operator typeName
  • 非常多重载的关键字(因为不想引入新关键字),让人傻傻捋不清

    • auto
      • 自动变量
      • 自动类型
    • static
      • 静态变量
      • 在类声明可用来表示静态类成员函数
      • 在类声明也可以用来表示作用域为类的常量,如static const int Months = 12;
    • class
      • 声明类,如class A {...}
      • 模板,如template <class Type>
      • 作用域内枚举(C++11),如enum class egg {...}
    • 0
      • 0
      • 空指针(0、NULL、nullptr)
    • virtual
      • 虚函数、纯虚函数
      • 虚基类
  • 或者同一个工具,非常多的用法

    • 作用域解析符::(或叫类限定符)
      • 局部使用被隐藏了的全局版本
      • 使用对应命名空间版本的函数
      • 继承时显示选择基类/派生类版本的方法
      • 多重继承时选择使用哪个基类版本的方法

语言简介、特点、简史

简介

  • 是什么

    • C++是在C语言基础上开发的一种集

      • 面向对象编程(OOP)
      • 泛型编程
      • 过程化编程

      于一体的编程语言,是C语言的超集

  • 新增特性:

    • 类和对象(面向对象)
    • 继承(面向对象)
    • 多态、虚函数和RTTI(运行阶段类型识别)(面向对象)
    • 函数重载
    • 引用变量
    • 泛型(独立于类型的)编程,这种技术是由模板和标准模板库(STL)提供的
    • 处理错误条件的异常机制
    • 管理函数、类和变量名的名称空间

特点

简史

与C一样,是在贝尔实验室诞生的,作者Bjarne Stroustrup,他的权威参考手册《The C++ Programming Language》和《The design and Evolution of C++》,他的个人网站:http://www.research.att.com/-bs/

C语言的超集,注重实用价值而不是意识形态方法

在C++获得一定程度的成功后,Stroustrup才添加模板,使得泛型编程称为可能

史记

1983年8月,第一个C++实现投入使用(所以我喜欢说1983年C++开了天界) 1983年12月,Rick Mascitti建议命名为CPlusPlus,即C++。 1985年2月,第一个C++ Release E发布。 10月,CFront的第一个商业发布,CFront Release 1.0。 10月,Bjarne博士完成了经典巨著The C++ Programming Language第一版 1986年11月,C++第一个商业移植CFront 1.1,Glockenspiel。 1987年2月,CFront Release 1.2发布。 11月,第一个USENIX C++会议在新墨西哥州举行。 1988年10月,第一次USENIX C++实现者工作会议在科罗拉多州举行。 1989年12月,ANSI X3J16在华盛顿组织会议。 1990年3月,第一次ANSI X3J16技术会议在新泽西州召开.    5月,C++的又一个传世经典ARM诞生。     7月,模板被加入。     11月,异常被加入。 1991年6月,The C++ Programming Language第二版完成。      6月,第一次ISO WG21会议在瑞典召开。     10月,CFront Release 3.0发布。 1993年3月,运行时类型识别在俄勒冈州被加入。      7月,名字空间在德国慕尼黑被加入。 1994年8月,ANSI/ISO委员会草案登记。 1997年7月,The C++ Programming Language第三版完成。     10月,ISO标准通过表决被接受 1998年11月,ISO标准被批准。(ISO/IEC 14882-1998)

语言标准、新增特性、版本变迁

语言标准准

  • C语言:由Dennis M. Ritchie在1973年设计和实现
  • K&R C:C语言标准 1978年Ritchie和Bell实验室的另一位程序专家Kernighan合写了著名的《The C Programming Language》,将C语言推向全世界,根据这本书定义的C语言后来被人们称作K&R C
  • ANSI C:C语言标准 随着C语言使用得越来越广泛,人们日益强烈地要求对C语言进行标准化。美国国家标准局(ANSI)1988年10月颁布ANSI标准X3.159-1989(即ANSI C标准), 国际标准(ISO)1989年左右采纳 ANSI C标准,定义为ISO/IEC 9899:1990
  • C++98:C++标准(1998年)
  • C++11:C++标准(2011年)

新增特性

此处略

版本变迁

由C而来,是C的超集

项目创建、环境安装、开发工具

HelloWorld、基础知识

HelloWorld

#include <iostream> 				// 预处理编译指令

int main() 							// 函数头(函数 = 返回类型 + 函数名 + 形参列表/参数列表 + 函数体)
{									// 函数体({}包裹的部分)
    std::cout << "Hello World!\n"; 	// 【写法1】C++,打印
    // using namespace std;			// 【写法2】using编译指令(使用命名空间)
    // cout << "Hello World!\n"; 	// 【写法2】C++,打印
    // printf("Hello World!"); 		// 【写法3】C语言,<stdio.h>中的printf依然能用
    return 0;						// 返回值,结束函数(main函数不加也行,其他必须加)
}

基础知识

main()函数(与C不同)

  1. 作为接口的函数头
  2. 为什么main()不能使用其他名称
  3. main的返回类型:C可以省略,而C++不可以

变量声明(与C不同)

声明风格 - 空行:用空行将声明语句与程序其他部分分开,C++不用

声明风格 - 位置:C或Pascal通常在函数或过程开始位置声明,C++没有这种限制,只需在使用前声明

==(C语言的C99新规范也可以在中间声明了)==以前学校用VC++6.0来教的编译器好像不支持,垃圾学校

C++注释(与C不同)

  • C风格注释/**/

  • C++风格注释//

  • 虽然C/C++都能用两种注释

  • 注释补充://!

    //后面的确全是注释,但//!的含义和C++语法无关,是程序员约定俗成的:表示这一行语句会引发编译错误。

    在Codeblocks IDE中,被//注释掉的语句会被冲蚀,而//!注释掉的语句则会高亮,以引起程序员的警惕。

C++预处理器和iostream文件

典型的预处理器操作:在源代码被编译之前,替换或添加文本(这里将iostream文件添加到程序中)

使用cin和cout进行输入和输出的程序必须包含文件iostream

头文件名(与C不同)

头文件命名约定:如表。去掉h不只是形式上的变化,没有h的头文件可以包含名称空间

头文件类型约定示例说明
C++旧式风格.h结尾iostream.hC++可用(话说现在好像也不能用了)
C旧式风格.h结尾math.hC、C++可用
C++新式风格没有扩展名iostreamC++可用,使用namespace std
C转换为C++加上前缀c,没有扩展名cmatchC++可用,可以使用不是C的特性,如namespace std

名称空间(与C不同)

C++新特性,C没有,优点:让编写大型程序以及将多个现有代码组合起来时更容易,有助于组织程序

using编译指令,现在接受,等以后(第9章)再理解,以免一头雾水

  • 作用举例:使用两个已封装好的产品,都包含一个wanda()函数,封装在名称空间中就知道是哪一个wanda()函数

    如:Microflop::wanda("go dancing?");Piscine::wanda("a fish named Desire");

  • 其他语言:这点很多其他语言的模块导入功能也具备,像C、Js这种原生不支持命名空间就显得很不方便

    如:Python:from moduleA import Catfrom moduleA import *import moduleA

  • std名称空间:,加了using namespace std后表示默认使用std这个名称空间,就简写成cout了,但这种方法不建议

  • 四种用法

    • 多函数程序访问名称空间,using namespace std放在函数定义前
    • 函数内可以访问名称空间,using namespace std放在特定的函数定义中
    • 可以访问指定的元素,using std::cout
    • 完全不适用编译指令using,std::cout <<

一些前提知识

对象分类

  • 左值:可被引用的数据对象(可以通过地址访问的值)
    • 等号左边值:可以在赋值语句左边的值,即可被修改的值
    • const变量(在const出来之前,左值就是等号左边值的意思)
  • 非左值
    • 字面常量(字符串字面量除外,它由地址表示)
    • 包含多项的表达式
  • 右值:不可被引用的数据对象(不能通过地址访问的值)(非引用值)