C++Primer中文版(第4版)学习笔记

上传人:仙*** 文档编号:85612299 上传时间:2022-05-06 格式:DOC 页数:59 大小:12.63MB
收藏 版权申诉 举报 下载
C++Primer中文版(第4版)学习笔记_第1页
第1页 / 共59页
C++Primer中文版(第4版)学习笔记_第2页
第2页 / 共59页
C++Primer中文版(第4版)学习笔记_第3页
第3页 / 共59页
资源描述:

《C++Primer中文版(第4版)学习笔记》由会员分享,可在线阅读,更多相关《C++Primer中文版(第4版)学习笔记(59页珍藏版)》请在装配图网上搜索。

1、wordC+Primer中文版(第4版)学习笔记调用 GNU 或微软编译器调用 GNU 编译器的默认命令是 g+: $ g+ prog1.cc -o prog1微软编译器采用命令 cl 来调用:acm pc2编译器搭配下面是pc2配置:(以vc为编译环境)配置环境变量:jdk设置:path=C:Program FilesJavajdk1.6.0bin; vc编译器设置: path=C:Program FilesMicrosoft Visual StudioVC98Bin; lib=C:Program FilesMicrosoft Visual StudioVC98Lib; include=C:

2、Program FilesMicrosoft Visual StudioVC98include环境变量配置完成之后,设置下pc2就ok了!pc2设置如下: pile line: cl.exe :mainfile Executable Filename: :basename.exe program execution mand line:basename.exe做到这些配置,根本上编译就不成问题了!注意,期间可以需要到C:Program FilesMicrosoft Visual StudioMONTools路径下拷贝mspdb60.dll到C:Program FilesMicrosoft Vi

3、sual StudioVC98Bin;!这个自己调试就Ok了!访问 main 函数的返回值的方式和系统有关。不论 UNIX 还是 Windows 系统,执行程序后,必须发出一个适当的 echo 命令。UNIX 系统中,通过键入如下命令获取状态:$ echo $?要在 Windows 系统下查看状态,键入C:directory echo %ERRORLEVEL%再谈编译 编译器的局部工作是寻找程序代码中的错误。编译器不能查出程序的意义是否正确, 但它可以查出程序形式上的错误。下面是编译器能查出的最普遍的一些错误。1、语法错误。程序员犯了 C+ 语言中的语法错误。下面代码段说明常见的语法错误;每个

4、注释描述下一行的错误。 / error: missing ) in parameter list for main int main ( / error: used colon, not a semicolon after endl std:cout Read each file. std:endl: / error: missing quotes around string literal std:cout Update master. std:endl; / ok: no errors on this line std:cout Write new master. std:endl; /

5、error: missing ; on return statement return 0 2、类型错误。C+ 中每个数据项都有其相关联的类型。例如,值 10 是一个整数。用双引号标注起来的单词“hello是字符串字面值。类型错误的一个实例是传递了字符串字面值给应该得到整型参数的函数。3、声明错误。C+ 程序中使用的每个名字必须在使用之前声明。没有声明名字通常会导致错误信息。最常见的两种声明错误,是从标准库中访问名字时忘记使用“std:,以与由于疏忽而拼错标识符名: #include int main() int v1, v2; std:cin v v2; / error: uses v no

6、t v1 / cout not defined, should be std:cout cout v1 + v2 std:endl; return 0; 错误信息包含行号和编译器对我们所犯错误的简要描述。按错误报告的顺序改正错误是个好习惯,通常一个错误可能会产生一连串的影响,并导致编译器报告比实际多得多的错误。最好在每次修改后或最多改正了一些显而易见的错误后,就重新编译代码。这个循环就是众所周知的编辑编译调试。从键盘输入文件完毕符操作系统使用不同的值作为文件完毕符。Windows 系统下我们通过键入 controlz同时键入“ctrl键和“z键,来输入文件完毕符。Unix 系统中,包括 Mac

7、 OSX 机器,通常用 controld。标准库的头文件用尖括号 括起来,非标准库的头文件用双引号 括起来。我们能将值 20 定义成如下三种形式中的任意一种: 20 / decimal / octal 0x14 / hexadecimal以 0零开头的字面值整数常量表示八进制,以 0x 或 0X 开头的表示十六进制。定义长整型时,应该使用大写字母 L。小写字母 l 很容易和数值 1 混淆。类似地,可通过在数值后面加 U 或 u 定义 unsigned 类型。使用科学计数法时,指数用 E 或者 e 表示。默认的浮点字面值常量为 double 类型。在数值的后面加上 F 或 f 表示单精度。同样加

8、上 L 或者 l 表示扩展精度非打印字符的转义序列newline换行符 nhorizontal tab水平制表符tvertical tab纵向制表符vbackspace退格符bcarriage return回车符rformfeed进纸符falert (bell)报警响铃符abackslash反斜线question mark疑问号?single quote单引号double quote双引号我们可以将任何字符表示为以下形式的通用转义字符: ooo这里 ooo 表示三个八进制数字,这三个数字表示字符的数字值。下面的例子是用 ASCII 码字符集表示字面值常量: 7 (bell) 12 (newli

9、ne) 40 (blank) 0 (null) 062 (2) 115 (M)字符0通常表示“空字符null character,我们将会看到它有着非常特殊的意义。同样也可以用十六进制转义字符来定义字符: xdddC+ 的格式非常自由。特别是有一些地方不能插入空格,其中之一是在单词中间。特别是不能在单词中连续开一行。但可以通过使用反斜线符号巧妙实现: / ok: A before a newline ignores the line break std:cou t Hi st d:endl;等价于 std:cout Hi std:endl;可以使用这个特性来编写长字符串字面值: / multi

10、line string literal std:cout a multi-line string literal using a backslash std:endl; return 0; 注意反斜线符号必须是该行的尾字符不允许有注释或空格符。同样,后继行行首的任何空格和制表符都是字符串字面值的一局部。正因如此,长字符串字面值的后继行才不会有正常的缩进。C+ 关键字asmdoifreturntryautodoubleinlineshorttypedefbooldynamic_castintsignedtypeidbreakelselongsizeoftypenamecaseenummutabl

11、estaticunioncatchexplicitnamespacestatic_castunsignedcharexportnewstructusingclassexternoperatorswitchvirtualconstfalseprivatetemplatevoidconst_castfloatprotectedthisvolatilecontinueforpublicthrowwchar_tdefaultfriendregistertruewhiledeletegotoreinterpret_castC+ 操作符替代名andbitandplnot_eqor_eqxor_eqand_

12、eqbitornotorxorC+ 支持两种初始化变量的形式:复制初始化和直接初始化。复制初始化语法用等号=,直接初始化如此是把初始化式放在括号中: int ival(1024); / direct-initialization int ival = 1024; / copy-initialization初始化置类型的对象只有一种方法:提供一个值,并且把这个值复制到新定义的对象中。对置类型来说,复制初始化和直接初始化几乎没有差异。对类类型的对象来说,有些初始化仅能用直接初始化完成。要想理解其中缘由,需要初步了解类是如何控制初始化的。变量初始化规如此置类型变量的初始化使用未初始化的变量是常见的程

13、序错误,通常也是难以发现的错误。虽然许多编译器都至少会提醒不要使用未初始化变量,但是编译器并未被要求去检测未初始化变量的使用。而且,没有一个编译器能检测出所有未初始化变量的使用。有时我们很幸运,使用未初始化的变量导致程序在运行时突然崩溃。一旦跟踪到程序崩溃的位置,就可以轻易地发现没有正确地初始化变量。但有时,程序运行完毕却产生错误的结果。更糟糕的是,程序运行在一部机器上时能产生正确的结果,但在另外一部机器上却不能得到正确的结果。添加代码到程序的一些不相关的位置,会导致我们认为是正确的程序产生错误的结果。建议每个置类型的对象都要初始化。虽然这样做并不总是必需的,但是会更加容易和安全,除非你确定忽

14、略初始化式不会带来风险。类类型变量的初始化每个类都定义了该类型的对象可以怎样初始化。类通过定义一个或多个构造函数来控制类对象的初始化。如果定义某个类的变量时没有提供初始化式,这个类也可以定义初始化时的操作。它是通过定义一个特殊的构造函数即默认构造函数来实现的。这个构造函数之所以被称作默认构造函数,是因为它是“默认运行的。如果没有提供初始化式,那么就会使用默认构造函数。不管变量在哪里定义,默认构造函数都会被使用。变量的声明和定义变量的定义用于为变量分配存储空间,还可以为变量指定初始值。在一个程序中,变量有且仅有一个定义。声明用于向程序明确变量的类型和名字。定义也是声明:当定义变量时我们声明了它的

15、类型和名字。可以通过使用extern关键字声明变量名而不定义它。不定义变量的声明包括对象名、对象类型和对象类型前的关键字extern: extern int i; / declares but does not definei int i; / declares and definesiextern 声明不是定义,也不分配存储空间。事实上,它只是说明变量定义在程序的其他地方。程序中变量可以声明屡次,但只能定义一次。只有当声明也是定义时,声明才可以有初始化式,因为只有定义才分配存储空间。初始化式必须要有存储空间来进展初始化。如果声明有初始化式,那么它可被当作是定义,即使声明标记为 extern:

16、 extern double pi = 3.1416; / definition虽然使用了 extern ,但是这条语句还是定义了 pi,分配并初始化了存储空间。只有当 extern 声明位于函数外部时,才可以含有初始化式。因为已初始化的 extern 声明被当作是定义,所以该变量任何随后的定义都是错误的: extern double pi = 3.1416; / definition double pi; / error: redefinition ofpi同样,随后的含有初始化式的 extern 声明也是错误的: extern double pi = 3.1416; / definitio

17、n extern double pi; / ok: declaration not definition extern double pi = 3.1416; / error: redefinition ofpi声明和定义之间的区别可能看起来微不足道,但事实上却是举足轻重的。在 C+ 语言中,变量必须且仅能定义一次,而且在使用变量之前必须定义或声明变量。任何在多个文件中使用的变量都需要有与定义别离的声明。在这种情况下,一个文件含有变量的定义,使用该变量的其他文件如此包含该变量的声明而不是定义。如下程序段将会输出什么?int i = 100, sum = 0;for (int i = 0; i

18、!= 10; +i)sum += i;std:cout i sum std:endl;【解答】输出为:100 45for 语句中定义的变量i,其作用域仅限于for 语句部。输出的i 值是for 语句之前所定义的变量i 的值。const因为常量在定义后就不能被修改,所以定义时必须初始化: const std:string hi = hello!; / ok: initialized const int i, j = 0; / error:iis uninitializedconst引用引用必须用与该引用同类型的对象初始化: int ival = 1024; int &refVal = ival;

19、 / ok:refValrefers toival int &refVal2; / error: a reference must be initialized int &refVal3 = 10; / error: initializer must be an object因为引用只是它绑定的对象的另一名字,作用在引用上的所有操作事实上都是作用在该引用绑定的对象上:const 引用const 引用是指向 const 对象的引用: const int ival = 1024; const int &refVal = ival; / ok: both reference and object a

20、reconst int &ref2 = ival; / error: nonconstreference to aconstobject可以读取但不能修改 refVal ,因此,任何对 refVal 的赋值都是不合法的。这个限制有其意义:不能直接对 ival 赋值,因此不能通过使用 refVal 来修改 ival。类定义使用 struct 关键字C+ 支持另一个关键字 struct,它也可以定义类类型。struct 关键字是从 C 语言中继承过来的。用 class 和 struct 关键字定义类的唯一差异在于默认访问级别:默认情况下,struct 的成员为 public,而 class 的成员

21、为 private。class Sales_item public: / operations onSales_itemobjects will go here private: std:string isbn; unsigned units_sold; double revenue; ;struct Sales_item / no need for public label, members are public by default / operations onSales_itemobjects private: std:string isbn; unsigned units_sold;

22、 double revenue; ;编译和多个源文件我们可以按以下方式编译这两个文件: $ CC -c main.cc Sales_item.cc -o main其中 $ 是我们的系统提示符,# 开始命令行注释。现在我们可以运行可执行文件,它将运行我们的 main 程序。如果我们只是修改了一个 .cc 源文件,较有效的方法是只重新编译修改正的文件。大多数编译器都提供了分别编译每一个文件的方法。通常这个过程产生 .o 文件,.o 扩展名暗示该文件含有目标代码。编译器允许我们把目标文件在一起以形成可执行文件。我们所使用的系统可以通过命令名 CC 调用编译。因此可以按以下方式编译程序: $ CC m

23、ain.o Sales_item.o # by default generates a.exe; $ CC main.o Sales_item.o -o main头文件用于声明而不是用于定义因为头文件包含在多个源文件中,所以不应该含有变量或函数的定义。对于头文件不应该含有定义这一规如此,有三个例外。头文件可以定义类、值在编译时就道的 const 对象和 inline 函数。这些实体可在多个源文件中定义,只要每个源文件中的定义是一样的。一些 const 对象定义在头文件中当该 const 变量是用常量表达式初始化时,可以保证所有的变量都有一样的值。但是在实践中,大局部的编译器在编译时都会用相应的

24、常量表达式替换这些 const 变量的任何使用。所以,在实践中不会有任何存储空间用于存储用常量表达式初始化的 const 变量。可在头文件中定义。如果 const 变量不是用常量表达式初始化,那么它就不应该在头文件中定义。相反,和其他的变量一样,该 const 变量应该在一个源文件中定义并初始化。应在头文件中为它添加 extern 声明,以使其能被多个文件共享。如下声明和定义哪些应该放在头文件中?哪些应该放在源文件中?请解释原因。(a) int var ;(b) const double pi = 3.1416;(c) extern int total = 255 ;(d) const dou

25、ble sq2 = squt (2.0) ;【解答】(a)、(c)、(d)应放在源文件中,因为(a)和(c)是变量定义,定义通常应放在源文件中。(d)中的const 变量sq2 不是用常量表达式初始化的,所以也应该放在源文件中。(b)中的const 变量pi 是用常量表达式初始化的,应该放在头文件中。不使用命名空间#include int main() int sum = 0, val = 1; / keep executing thewhileuntilvalis greater than 10 while (val = 10) sum += val; / assignssum + valt

26、osum +val; / add1toval std:cout Sum of 1 to 10 inclusive is sum std:endl; return 0; 命名空间的using声明using声明可以在不需要加前缀namespace_name:的情况下访问命名空间中的名字。using声明的形式如下: using namespace:name;一旦使用了using声明,我们就可以直接引用名字,而不需要再引用该名字的命名空间。 #include #include / usingdeclarations states our intent to use these names from t

27、he namespacestd using std:cin; using std:string; int main() string s; / ok:stringis now a synonym forstd:string cin s; / ok:cinis now a synonym forstd:cin cout s; / error: nousingdeclaration; we must use full name std:cout s; / read whitespace-separated string intos cout s s; / read whitespace-separ

28、ated string intos从标准输入读取string并将读入的串存储在s中。string类型的输入操作符:读取并忽略开头所有的空白字符如空格,换行符,制表符。读取字符直至再次遇到空白字符,读取终止。读入未知数目的string对象和置类型的输入操作一样,string的输入操作符也会返回所读的数据流。因此,可以把输入操作作为判断条件,这与我们在1.4.4节读取整型数据的程序做法是一样的。下面的程序将从标准输入读取一组string对象,然后在标准输出上逐行输出: int main() string word; / read until end-of-file, writing each wo

29、rd to a new line while (cin word) cout word endl; return 0; 使用getline读取整行文本getline。这个函数承受两个参数:一个输入流对象和一个string对象。getline函数从输入流的下一行读取,并保存读取的容到不包括换行符。和输入操作符不一样的是,getline并不忽略行开头的换行符。只要getline遇到换行符,即便它是输入的第一个字符,getline也将停止读入并返回。如果第一个字符就是换行符,如此string参数将被置为空string。getline函数将istream参数作为返回值,和输入操作符一样也把它用作判断条

30、件。例如,重写前面那段程序,把每行输出一个单词改为每次输出一行文本: int main() string line; / read line at time until end-of-file while (getline(cin, line) cout line endl; return 0; 由于getline函数返回时丢弃换行符,换行符将不会存储在string对象中。string对象的操作.empty()如果s为空串,如此返回true,否如此返回false。s.size()返回s中字符的个数sn返回s中位置为n的字符,位置从0开始计数s1 + s2把s1和s2连接成一个新字符串,返回新生

31、成的字符串s1 = s2把s1容替换为s2的副本v1 = v2比拟v1与v2的容,相等如此返回true,否如此返回false!=, , , and =保持这些操作符惯有的含义string:size_type类型从逻辑上来讲,size()成员函数似乎应该返回整形数值,或如2.2节“建议中所述的无符号整数。但事实上,size操作返回的是string:size_type类型的值。我们需要对这种类型做一些解释。任何存储string的size操作结果的变量必须为string:size_type类型。特别重要的是,不要把size的返回值赋给一个int变量。和字符串字面值的连接当进展string对象和字符串

32、字面值混合连接操作时,+操作符的左右操作数必须至少有一个是string类型的: string s1 = hello; / no punctuation string s2 = world; string s3 = s1 + , ; / ok: adding astringand a literal string s4 = hello + , ; / error: nostringoperand string s5 = s1 + , + world; / ok: each + hasstringoperand string s6 = hello + , + s2; / error: cant a

33、ddstringliterals可用下标操作符分别取出string对象的每个字符,分行输出: string str(some string); for (string:size_type ix = 0; ix != str.size(); +ix) cout strix endl;cctype Functionsisalnum(c)如果c是字母或数字,如此为True。isalpha(c)如果c是字母,如此为true。istrl(c)如果c是控制字符,如此为trueisdigit(c)如果c是数字,如此为true。isgraph(c)如果c不是空格,但可打印,如此为true。islower(c)

34、如果c是小写字母,如此为true。isprint(c)如果c是可打印的字符,如此为true。ispunct(c)如果c是标点符号,如此true。isspace(c)如果c是空白字符,如此为true。isupper(c)如果c是大写字母,如此true。isxdigit(c)如果是c十六进制数,如此为true。tolower(c)如果c大写字母,返回其小写字母形式,否如此直接返回c。toupper(c)如果c是小写字母,如此返回其大写字母形式,否如此直接返回c。建议:采用C标准库头文件的C+版本C+标准库除了定义了一些选定于C+的设施外,还包括C标准库。C+中的头文件cctype其实就是利用了C标

35、准库函数,这些库函数就定义在C标准库的头文件中。C标准库头文件命名形式为name而C+版本如此命名为ame,少了后缀,.h而在头文件名前加了c表示这个头文件源自C标准库。因此,cctype与文件的容是一样的,只是采用了更适合C+程序的形式。特别地,ame头文件中定义的名字都定义在命名空间std,而.h版本中的名字却不是这样。通常,C+程序中应采用ame这种头文件的版本,而不采用版本,这样,标准库中的名字在命名空间std中保持一致。使用.h版本会给程序员带来负担,因为他们必须记得哪些标准库名字是从C继承来的,而哪些是C+所特有的。标准库 vector 类型vector 是同一种类型的对象的集合,

36、每个对象都有一个对应的整数索引值。和 string 对象一样,标准库将负责管理与存储元素相关的存。我们把 vector 称为容器,是因为它可以包含其他对象。一个容器中的所有对象都必须是同一种类型的。vector 是一个类模板class template。使用模板可以编写一个类定义或函数定义,而用于多个不同的数据类型。因此,我们可以定义保存 string 对象的 vector,或保存 int 值的 vector,又或是保存自定义的类类型对象如 Sales_items 对象的 vector。声明从类模板产生的某种类型的对象,需要提供附加信息,信息的种类取决于模板。以 vector 为例,必须说明

37、vector 保存何种对象的类型,通过将类型放在类型放在类模板名称后面的尖括号中来指定类型: vector ivec; / ivecholds objects of typeint vector Sales_vec; / holdsSales_itemsvector 不是一种数据类型,而只是一个类模板,可用来定义任意多种数据类型。vector 类型的每一种都指定了其保存元素的类型。因此,vector 和 vector 都是数据类型。vector 对象的定义和初始化vector v1;vector 保存类型为 T 对象。默认构造函数 v1 为空。vector v2(v1);v2 是 v1 的一个

38、副本。vector v3(n, i);v3 包含 n 个值为 i 的元素。vector v4(n);v4 含有值初始化的元素的 n 个副本。vector 对象动态增长vector 对象以与其他标准库容器对象的重要属性就在于可以在运行时高效地添加元素。因为 vector 增长的效率高,在元素值的情况下,最好是动态地添加元素。虽然可以对给定元素个数的 vector 对象预先分配存,但更有效的方法是先初始化一个空 vector 对象,然后再动态地增加元素我们随后将学习如何进展这样的操作。值初始化如果没有指定元素的初始化式,那么标准库将自行提供一个元素初始值进展值初始化value initializa

39、tiond。这个由库生成的初始值将用来初始化容器中的每个元素,具体值为何,取决于存储在 vector 中元素的数据类型。如果 vector 保存置类型如 int 类型的元素,那么标准库将用 0 值创建元素初始化式: vector fvec(10); / 10 elements, each initialized to 0如果 vector 保存的是含有构造函数的类类型如 string的元素,标准库将用该类型的默认构造函数创建元素初始化式: vector svec(10); / 10 elements, each an empty stringvector Operationsv.empty()

40、如果 v 为空,如此返回 true,否如此返回 false。v.size()返回 v 中元素的个数。v.push_back(t)在 v 的末尾增加一个值为 t 的元素。vn返回 v 中位置为 n 的元素。v1 = v2把 v1 的元素替换为 v2 中元素的副本。v1 = v2如果 v1 与 v2 相等,如此返回 true。!=, , , and =保持这些操作符惯有的含义。vector 对象的 size使用 size_type 类型时,必须指出该类型是在哪里定义的。vector 类型总是包括总是包括 vector 的元素类型: vector:size_type / ok vector:size

41、_type / error初学 C+ 的程序员可能会认为 vector 的下标操作可以添加元素,其实不然: vector ivec; / emptyvector for (vector:size_type ix = 0; ix != 10; +ix) ivecix = ix; / disaster:ivechas no elements上述程序试图在 ivec 中插入 10 个新元素,元素值依次为 0 到 9 的整数。但是,这里 ivec 是空的 vector 对象,而且下标只能用于获取已存在的元素。这个循环的正确写法应该是: for (vector:size_type ix = 0; ix

42、!= 10; +ix) ivec.push_back(ix); / ok: adds new element with valueix必须是已存在的元素才能用下标操作符进展索引。通过下标操作进展赋值时,不会添加任何元素。警告:仅能对确知已存在的元素进展下标操作迭代器简介除了使用下标来访问vector对象的元素外,标准库还提供了另一种访问元素的方法:使用迭代器iterator。迭代器是一种检查容器元素并遍历元素的数据类型。标准库为每一种标准容器包括vector定义了一种迭代器类型。迭代器类型提供了比下标操作更通用化的方法:所有的标准库容器都定义了相应的迭代器类型,而只有少数的容器支持下标操作。因

43、为迭代器对所有的容器都适用,现代C+程序更倾向于使用迭代器而不是下标操作访问容器元素,即使对支持下标操作的vector类型也是这样。每种容器类型都定义了自己的迭代器类型,如vector: vector:iterator iter;begin和end操作每种容器都定义了一对命名为begin和end的函数,用于返回迭代器。如果容器中有元素的话,由begin返回的迭代器指向第一个元素: vector:iterator iter = ivec.begin();由end操作返回的迭代器指向vector的“末端元素的下一个。“超出末端迭代器off-the-end iterator。明确它指向了一个不存在的

44、元素。如果vector为空,begin返回的迭代器与end返回的迭代器一样。由于end操作返回的迭代器不指向任何元素,因此不能对它进展解引用*或自增操作。for (vector:iterator iter = ivec.begin(); iter != ivec.end(); +iter) *iter = 0; / set element to whichiterrefers to 0const_iterator每种容器类型还定义了一种名为const_iterator的类型,该类型只能用于读取容器元素,但不能改变其值。for (vector:const_iterator iter = text

45、.begin(); iter != text.end(); + iter) *iter = ; / error:*iterisconst使用const_iterator类型时,我们可以得到一个迭代器,它自身的值可以改变,但不能用来改变其所指向的元素的值。可以对迭代器进展自增以与使用解引用操作符来读取值,但不能对该元素赋值。不要把const_iterator对象与const的iterator对象混淆起来。声明一个const迭代器时,必须初始化迭代器。一旦被初始化后,就不能改变它的值: vector nums(10); / numsis nonconst const vector:iterator

46、 cit = nums.begin(); *cit = 1; / ok:citcan change its underlying element +cit; / error: cant change the value ofcit任何改变vector长度的操作都会使已存在的迭代器失效。例如,在调用push_back之后,就不能再信赖指向vector的迭代器的值了。标准库bitset初始化bitset对象的方法bitset b;b有n位,每位都0bitset b(u);b是unsigned long型u的一个副本bitset b(s);b是string对象s中含有的位串的副本bitset b(s

47、, pos, n);b是s中从位置pos开始的n个位的副本。bitset bitvec; / 32 bits, all zero这条语句把bitvec定义为含有32个位的bitset对象。和vector的元素一样,bitset中的位是没有命名的,程序员只能按位置来访问。位集合的位置编号从0开始,因此,bitvec的位序是从0到31。以0位开始的位串是低阶位low-order,以31位完毕的位串是高阶位high-order。string对象和bitsets对象之间是反向转化的:string对象的最右边字符即下标最大的那个字符用来初始化bitset对象的低阶位即下标为0的位。当用string对象初

48、始化bitset对象时,记住这一差异很重要。bitset操作b.any()b中是否存在置为1的二进制位?b.none()b中不存在置为1的二进制位?b.count()b中置为1的二进制位的个数b.size()b中二进制位的个数bpos访问b中在pos处二进制位b.test(pos)b中在pos处的二进制位置是否为1b.set()把b中所有二进制位都置为1 b.set(pos)把b中在pos处的二进制位置为1b.reset()把b中所有二进制位都置为0b.reset(pos)把b中在pos处的二进制位置为0b.flip()把b中所有二进制位逐位取反b.flip(pos)把b中在pos处的二进制位

49、取反b.to_ulong()用b中同样的二进制位返回一个unsigned long值os b把b中的位集输出到os流size_t类型定义在cstddef头文件中,该文件是C标准库的头文件的C+版本。它是一个与机器相关的unsigned类型,其大小足以保证存储在中对象的大小。建议:尽量防止使用指针和数组指针和数组容易产生不可预料的错误。其中一局部是概念上的问题:指针用于低级操作,容易产生与繁琐细节相关的bookkeeping错误。其他错误如此源于使用指针的语法规如此,特别是声明指针的语法。许多有用的程序都可不使用数组或指针实现,现代C+程序采用vector类型和迭代器取代一般的数组、采用stri

50、ng类型取代C风格字符串。一个有效的指针必然是以下三种状态之一:保存一个特定对象的地址;指向某个对象后面的另一对象;或者是0值。假如指针保存0值,明确它不指向任何对象。未初始化的指针是无效的,直到给该指针赋值后,才可使用它。如下定义和赋值都是合法的: int ival = 1024; int *pi = 0; / piinitialized to address no object int *pi2 = & ival; / pi2initialized to address ofival int *pi3; / ok, but dangerous,pi3is uninitialized pi

51、= pi2; / piandpi2address the same object, e.g.ival pi2 = 0; / pi2now addresses no object防止使用未初始化的指针很多运行时错误都源于使用了未初始化的指针。指针初始化和赋值操作的约束对指针进展初始化或赋值只能使用以下四种类型的值:1. 0 值常量表达式,例如,在编译时可获得 0 值的整型 const 对象或字面值常量 0。2. 类型匹配的对象的地址。3. 另一对象末的下一地址。4. 同类型的另一个有效指针。把 int 型变量赋给指针是非法的,尽管此 int 型变量的值可能为 0。但允许把数值 0 或在编译时可获

52、得 0 值的 const 量赋给指针: int ival; int zero = 0; const int c_ival = 0; int *pi = ival; / error:piinitialized from int value ofival pi = zero; / error:piassigned int value of zero pi = c_ival; / ok:c_ivalis aconstwith pile-time value of 0 pi = 0; / ok: directly initialize to literal constant 0void* 指针C+ 提供了一种

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!