c++primer笔记(1)

程序设计方法 -- programming paradigm
过程化程序设计方法 -- procedural programming
抽象数据类型 -- abstract data type 简写为ADT
与每个类相关的算法被称为该类的公有接口(public interface)
基于对象 -- object based

面向对象的程序设计方法通过继承inheritance 机制和动态绑定dynamic binding 机制扩展了抽象数据类型继承机制是对现有实现代码的重用动态绑定是指对现有的公有接口的重用

函数由四部分组成返回类型函数名参数表以及函数体前三部分合起来称为函数原型(function prototype)

标准C++中如果main()函数没有显式地提供返回语句则它缺省返回0

预处理器指示符 -- preprocessor directive

C++标准库还提供了一组扩展的基本数据类型其中包括字符串(string) 复数(complex number) 向量(vector) 和列表(list)

编译C++程序时,编译器自动定义了一个预处理器名字__cplusplus

另外两个比较有用的预定义名字是:__LINE__和__FILE__。 __LINE__记录文件已经被
编译的行数,__FILE__包含正在被编译的文件的名字。

另外两个预定义名字分别包含当前被编译文件的编译时间__TIME__ 和日期__DATE__

assert()是C 语台标准库中提供的一个通用预处理器宏,在代码中常利用assert()来判断一个必需的前提条件,以便程序能够正确执行。

cerr 通常用来产生给程序用户的警告或错误信息

在内置数据类型与标准库类的类型之间是复合类型compound type 特别是指针和数组类型

数组(array) 是一种顺序容器它包含单一类型的元素

在C++中对象可以静态分配——即编译器在处理程序源代码时分配,也可以动态分配——即程序执行时调用运行时刻库函数来分配.

静态与动态内存分配的两个主要区别是:
1、静态对象是有名字的变量,我们直接对其进行操作。而动态对象是没有名字的变量,我们通过指针间接地对它进行操作
2、静态对象的分配与释放由编译器自动处理。程序员需要理解这一点,但不需要做任何事情。相反动态对象的分配与释放,必须由程序员显式地管理,相对来说比较容易出错,它通过new 和delete 两个表达式来完成。

如果忘了删除动态分配的内存,程序就会在结束时出现内存泄露(memory leak)的问题。
内存泄露是指一块动态分配的内存,我们不再拥有指向这块内存的指针,因此我们没有办法将它返还给程序以后重新使用。

一般来说公有成员提供了该类的公有接口public interface ——即实现了这个类的行为的操作集合
私有成员提供私有实现代码private implementation ——即存储信息的数据
这种"类的公共接口"与"私有实现代码的分离",被称为信息隐藏(information hiding)
信息隐藏的两个好处:
1、如果类的私有实现代码需要修改或扩展,那么,只有相对很小一部分“要求访问这些实现代码的成员函数”需要修改。而许多使用该类的用户程序无需修改,但是要求重新编译。
2、如果类的私有实现代码有错误,那么通常需要检查的代码数量只局限在相对较少的需要访问这些实现代码的成员函数上,而无需检查整个程序

类定义以及相关的常数值或typedef 名通常都存储在头文件中并且头文件以类名来命名

对于一个非虚拟函数的调用,编译器在编译时刻选择被调用的函数,而虚拟函数调用的决定则要等到运行时刻.在执行程序内部的每个调用点上,系统根据被调用对象的实际基类或派生类的类型,来决定选择哪一个虚拟函数实例.

RTTI: 运行时刻类型识别

异常是指在运行时刻程序出现的反情形。
异常处理(exception handling) 为"响应运行时刻的程序异常"提供了一个标准的语言级的设施,它支持统一的语法和风格,也允许每个程序员进行微调。
异常处理机制的主要构成:
1、程序中异常出现的点
2、程序中异常被处理的点
如果try 块内抛出的异常不能被相关联的catch 子句处理,那么函数将被终止。然后,异常机制再在调用stats()的函数中查找处理代码。
如果异常机制按照函数被调用的顺序回查每个函数直到main()函数,仍然没有找到处理代码,那么它将调用标准库函数terminate() 。缺省情况下,terminate()函数结束程序。


容器用来存储数据的,数据可以是用户自定义类型(对象),也可以是预定义类型,c++中的容器主要使用如vector,list (顺序容器) 这些都是已经封装好了的,包含头文件"vector","list",通过迭代器iterator访问容器中的数据,map,set(关联容器),关联容器map键值对形式出现key-value,key唯一,mutimap多映射可以不唯一;set是一个单一值的集合,如1,2,3,4

我们编写的程序以及所保存的程序数据在计算机的内存中是以二进制位序列的方式存放的。位bit 是含有0 或1 值的一个单元。在物理上它的值是个负或正电荷。
一个字节由8位构成,而一个字由32位构成。

newline(换行符) /n
horizontal tab(水平制表键) /t
vertical tab(垂直制表键) /v
backspace(退格键) /b
carriage return (回车键) /r
formfeed (进纸键) /f
alert (beel) (响铃符) /a
backslash (反斜杠键) //
question mark (问号) /?
single quote (单引号) /'
double quote (双引号) /"

八进制序列的值代表该字符在机器字符集里的数字值下面的示例使用ASCII 码字符集表示文字常量:
/7 (bell) /14 (newline)
/0 (null) /062 ('2')

字符文字前面加"L",如:L'a'    这称为宽字符文字,类型为wchar_t
宽字符常量用来支持某些语言的字符集合,如汉语、日语

如果将一个字符串常量与一个宽字符串常量连接起来,结果是未定义的——即,没有这两种不同类型的连接定义标准行为。使用未定义行为的程序称作是不可移植的。

C++中的每个符号变量都与一个特定的数据类型相关联,这个类型决定了相关内存的大小、布局、能够存储在该内存区域的值的范围以及可以应用其上的操作集。

对于每一个变量,都有两个值与其相关联:
1、它的数据值,存储在某个内存地址中。称为右值。
2、它的地址值,存储数据值的那块内存的地址。称为左值。

对象声明(declaration)的作用是使程序知道该对象的类型和名字。它由关键字extern以及跟在后面的对象类型以及对象的名字构成。声明不是定义,不会引起内存分配。实际上,它只是说明了在程序之外的某处有这个变量的定义。

如果一个变量是在全局域(global scope)内定义的,那么系统会保证给它提供初始值0。如果变量是在局部域(local scope)内定义的,或是通过new表达式动态分配的,则系统不会像他提供初始值0。这称为未初始化,未初始化不是没有值,而是它的值是未定义的。

指针的典型用法是构建一个链接的数据结构,例如树和链表,并管理在程序执行过程中动态分配的对象,以及作为函数参数类型,主要用来传递数组或大型的类对象。

当指针持有0值时,表明他没有指向任何对象,或持有一个同类型的数据对象的地址。
指针不能持有非地址值。
指针不能被初始化或赋值为其他类型对象的地址值。

空(void*) 类型指针,它可以被任何数据指针类型的地址值赋值(函数指针不能赋值给它)。
void*表明相关的值是个地址,但该地址的对象类型不知道。我们不能够操作空类型指针所指向的对象,只能传送该地址值或将它与其他地址值作比较。

如:int *pi; pi = pi + 2;
指针加2意味着给指针持有的地址值增加了该类型两个对象的长度。而不是离散的十进制数值的加法。

补丁(patch)——把某些东西伸展开以便补上现有程序中的洞。

迭代器是指针的类抽象,由标准库提供。

在实际的程序中,指向const的指针常被用作函数的形式参数。它作为一个约定来保证被传递给函数的实际对象在函数中不会被修改。

引用(reference)又成为别名(alias),它可以用作对象的另一个名字。在实际的程序中,引用主要被用作函数的形式参数——通常将类对象传递给一个函数。
引用必须被初始化为指向一个对象。
const引用可以用不同类型的对象初始化,也可以是不可寻址的值,如文字常量。对于不可寻址的值,以及不同类型的对象,编译器为了实现引用,必须生成一个临时对象,引用实际上指向该对象,但用户不能访问它。

指针和引用的两个主要区别:
1、引用必须总是指向一个对象。如果用一个引用给另一个引用赋值,那么改变的是被引用的对象而不是引用本身。
2、引用之间的赋值

虽然布尔类型的对象也被看作是一种整数类型的对象,但是它不能被声明为signed、unsigned、short或long.
false 0; ture 1;
算术值和指针值也能隐式地被转换成布尔类型的值。0或空指针被转换成false,所有其他的值被转换成true。

可以定义枚举类型的对象。
不能打印枚举成员的实际枚举名:定义一个由枚举成员值索引的字符串数组
不能使用枚举成员进行迭代。
C++不支持在枚举成员之间的前后移动。
枚举类型的对象能够被初始化,但是只能被一个相同枚举类型的对象或枚举成员集中的某个值初始化或赋值。

维数值必须是常量表达式——即,必须能在编译时刻计算出它的值。这意味着非const 的变量不能被用来指定数组的维数。
字符数组可以用一个由逗号分开的字符文字列表初始化,文字列表用花括号括起来,或者用一个字符串文字初始化。但是,注意这两种形式不是等价的,字符串常量包含一个额外的终止空字符。
一个数组不能被另外一个数组初始化,也不能被赋值给另外一个数组。而且,C++不允许声明一个引用数组(即由引用组成的数组)。

可以将vector 初始化为一个已有数组的全部或一部分,只需指定希望被用来初始化vector 的数组的开始地址以及数组最末元素的下一位置来实现。
与内置数组不同,vector 可以被另一个vector 初始化或被赋给另一个vector。

在典型情况下,typedef 名字可以用来增强"复杂模板声明的定义"的可读性,增强"指向函数的指针"以及"指向类的成员函数的指针"的可读性。

当一个对象的值可能会在编译器的控制或监测之外被改变时,例如一个被系统时钟更新的变量,那么该对象应该声明成volatile。因此,编译器执行的某些例行优化行为不能应用在已指定为volatile的对象上。
volatile修饰符的主要目的是提示编译器,该对象的值可能在编译器未监测到的情况下别改变。因此编译器不能武断地对引用这些对象的代码做优化处理。

拷贝构造函数:用一个对象的拷贝来初始化一个对象。

表达式由一个或多个操作数构成。最简单的表达式由一个文字常量或一个对象构成。一般地,表达式的结果是操作数的右值。
算术表达式结果的类型由操作数的类型来决定。

浮点数加法、乘法和减法的结果精度受到底层数据类型的固有精度的影响。

二元关系操作符(小于或等于操作符),左右操作数的计算顺序在标准C和C++中都是未定义的,因此计算过程必须是与顺序无关的。

数组对象本身不能被赋值,只有它包含的元素才能被赋值。

赋值操作符也可以被连接在一起,只要每个被复制的操作数都是相同的数据类型。

sizeof操作符的作用是返回一个对象或类型名的字节长度。
应用在指针类型上的sizeof操作符返回的是包含该类型地址所需的内存长度。但是应用在引用类型上的sizeof操作符返回的是包含被引用对象所需的内存长度。
sizeof操作符应用在char类型上时,在所有的C++实现中结果都是1。
sizeof操作符在编译时刻计算,因此被看做是常量表达式。

系统为每个程序提供了一个在程序执行时可用的内存池。这个可用的内存池被称为程序的空闲存储区或堆。
new表达式并不返回实际被分配的对象,而且返回这个对象的地址。

为了减轻程序代码的维护工作,效率有时可能会被牺牲。
1、避免使用global declaration,并适当地使用namespace。
2、把所有的declarations置于块开始的地方,以便能轻易看见所有被定义以及被使用的objects.
3、当declarations涉及许多修饰词时,每一个应占用独立的一行,
4、为所有的变量设立初值。

链表是一个数据项序列,每个数据项都包含一个某种类型的值和链表下一项的地址,地址可以为空,链表也可以为空,即链表中可以没有数据项。链表不可能为满,但是当程序的空闲存储区被耗尽时,试图创建一个新链表项会失败。

链表类支持的操作:插入(insert)、删除(delete)、查找(find)、链表长度(size)、显示(display)链表、比较链表(equality)、翻转(reverse)链表、连接(concatenate)链表。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值