C++ Primer章节笔记及课后答案
文章平均质量分 58
笔记
冷眼观world
社畜
展开
-
第一章课后习题答案
//1.3int main(){ cout << "Hello, World" << endl; return 0;}//1.4int main(){ int v1, v2; cin >> v1 >> v2; cout << "The answer of " << v1 << " times " << v2 << " is " << v1 * v2 <<原创 2021-06-03 19:31:41 · 65 阅读 · 0 评论 -
第二章-变量和基本类型
第二章-变量和基本类型基本内置类型赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数举例:8bit大小的unsigned char可以表示0 ~ 255一共256个数把-1赋给unsigned char会得到255运算方式为:(-1) % 256= (-1 + 256) % 256= 255 % 256= 255给带符号类型超出它表示范围的值时,结果是未定义的变量初始化和赋值是两个概念。初始化是创建变量时赋予其一个初始值,赋值是把原创 2021-03-25 14:16:55 · 208 阅读 · 0 评论 -
第二章课后习题答案
//2.1short 16位短整型int 16位整型long 32位长整型long long 64位长整型带符号可以表示正数、负数和0无符号仅能表达式大于等于0的值float 32位浮点数double 64位浮点数//2.2使用double,因为结果一般不是整型//2.3u2 - u = 32u - u2 = 4294967264i2 - i = 32i - i2 = -32i - u = 0u - i = 0//2.5'a'字符 L'a'宽字符 "a"字符串 L"a原创 2021-06-04 19:03:44 · 99 阅读 · 0 评论 -
第三章-数组
文章目录第三章-字符串、向量和数组string数组第四章-表达式第五章-语句条件语句迭代语句第六章-函数第七章-类第三章-字符串、向量和数组stringstring使用加法运算符必须确保运算符两侧的运算对象至少有一个string数组理解复杂的数组声明int *ptrs[10]; //ptrs含有10个整型指针的数组int &refs[10] = ... //错误,不存在引用的数组int (*parray)[10] = &arr; //parray指向一个含有10个整数原创 2021-03-28 13:38:28 · 127 阅读 · 0 评论 -
第三章课后习题答案
//3.2int main(){ string str; cin >> str; char c; while (cin >> c) str = str + c; cout << str << endl; return 0;}//3.3输入运算符自动忽略开头的空白,读取字符直到下一个空白getline从给定输入流读取内容,直到遇到换行符(也读取了该换行符)//3.4int main(){ string str1, str2;原创 2021-06-05 18:05:12 · 201 阅读 · 0 评论 -
第四章-表达式
第四章-表达式左值表达式表示一个对象的身份——在内存中的位置;右值表达式表示的是对象的值——内容。理解左值、右值取余运算符:m % (-n) = m % n;(-m) % n = -(m % n)。换句话说,如果m%n不等于0则符号永远和m相同算术运算符+、-、*、/;关系运算符<、>、!=等;逻辑运算符&&、||、!;一般来说优先级算术>关系>逻辑i != j < k= i != (j < k)运算对象可按任意顺序求值。在一个表达式中原创 2021-03-28 14:39:07 · 112 阅读 · 0 评论 -
第四章课后习题答案
//4.1105//4.2(a)*(vec.begin())(b)(*(vec.begin())) + 1//4.4((12 / 3) * 4) + (5 * 15) + ((24 % 4) / 2)91//4.5(a)-86 (b)-18(c)0 (d)-2//4.6n % 2 == 0//4.7计算机存储某种类型的存储空间有限所以对该类型的表示能力也是有限的当计算结果超出这个范围就会产生溢出i = 30000000000 * 30000000000..../原创 2021-06-09 18:52:28 · 166 阅读 · 0 评论 -
第五章-语句
第五章-语句条件语句switch语句执行跳过某个特定case而执行另一个case,如果有个变量定义在前面的case而使用在后面的case,此时将发生绕过初始化直接使用的错误。所以要在某个分支定义并初始化一个变量,就应该把变量定义在块内,以此让后面的case标签都在变量的作用域之外case true: { string s = ....; ... } break;case false; if (s) //错误,s不在作用域中迭代语句condition中使用的变量必须定义在循原创 2021-03-28 14:56:53 · 68 阅读 · 0 评论 -
第五章课后习题答案
//5.1空语句块就是内部没有任何语句的一对花括号循环不需要执行任何操作时会用到//5.2用花括号括起来的语句和声明的序列//5.3int main(){ int sum = 0, val = 1; while (val <= 10) { sum += val; val++; }}//5.4(a)iter没有初始化string::iterator iter= s.begin();while (iter != s.end()) { ... }(b)//5.原创 2021-07-06 18:03:51 · 60 阅读 · 0 评论 -
第六章-函数
第六章-函数函数的返回类型不能是数组类型或函数类型,单可以是指向数组或函数的指针指针或引用形参与constint i =42;const int *cp = &i;const int &r = i;const int &r2 = 42;int *p = cp; //错误,p类型和cp不匹配int &r3 = r; //错误,r3类型和r类型不匹配int &r4 = 42; //不能用字面值初始化一个非常量引用// const int &原创 2021-03-28 20:09:16 · 102 阅读 · 0 评论 -
第六章课后习题答案
//6.1形参出现在函数定义的地方,形参规定了一个函数所接受的数据的类型和数量实参出现在函数调用的地方,实参主要是为了初始化形参//6.2(a)函数体返回结果类型和返回值类型不一致且不能自动转换(b)缺少返回值(c)缺少左花括号(d)缺少一对花括号//6.3int fact(int val){ if (!val) return 1; return val * fact(val - 1);}//6.4int fact(int val){ if (!val) retur原创 2021-07-26 00:23:31 · 114 阅读 · 0 评论 -
第七章-类
第七章-类默认情况下this的类型是指向非常量版本的常量指针,就像:Sales_data *const this。这样不能修改this的地址,但是能修改this指向的值如果将函数声明成const比如std::string Sales_data::isbn() const { ... },那指针将是const Sales_data *const this,就不会改变指向的对象。IO类属于不能被拷贝类型,所以只能用引用来传递当类没有声明任何构造函数时编译器才会自动生成默认构造函数友元声明只能出现在类原创 2021-04-01 17:14:43 · 138 阅读 · 0 评论 -
第七章课后习题
//7.1int main(){ Sales_data total; if (cin >> total) { Sales_data trans; while (cin >> trans) { if (total.isbn() == trans.isbn()) total += trans; else { cout << total << endl; total = trans; } }原创 2021-09-15 00:53:21 · 70 阅读 · 0 评论 -
第十二章-动态内存
动态分配的对象的生存期与它们在哪里创建是无关的,只有当显式地被释放时才会被销毁。动态内存和智能指针动态内存管理通过一对运算符完成,new:在动态内存中为对象分配空间并返回一个指向该对象的指针。delete:接受一个动态对象的指针,销毁该对象,并释放与之关联的内存。忘记释放内存会导致内存泄露;在尚有指针引用内存的情况下就释放了内存,会产生引用非法内存的指针。为了更安全地使用指针,可以使用智能指针,智能指针能负责自动释放对象。shared_ptr允许多个指针指向同一个对象;unique_ptr独占.原创 2021-04-20 19:03:14 · 120 阅读 · 0 评论 -
第十二章课后习题
//12.1b2有4个元素,但是最终被销毁b1有4个元素//12.3不需要,因为常量对象不允许修改自己的内容//12.4check函数是私有函数,只能被成员函数调用而成员函数能保证i肯定大于等于0//12.5可以比较方便的进行拷贝形式的初始化//12.6vector<int>* new_vector(){ return new vector<int>;}void read(vector<int> *pv){ int num; whil原创 2021-09-22 22:07:17 · 65 阅读 · 0 评论 -
动态内存使用示例——共享对象的类
前景提要一般我们使用过的类,分配的资源都与对应对象生存期一致。比如每个vector都有自己的元素,当我们拷贝一个vector时,原vector和副本vector的元素是分离的vector<string> v1;//作用域{ vector<string> v2 = {"a", "an", "the"}; v1 = v2;}//作用域结束v2被销毁,其元素也被销毁//v1保存了v2元素的拷贝我们可以定义一个类Blob。与平时的容器不同,它对象的不同拷贝之间共享相同的原创 2021-05-06 20:45:11 · 129 阅读 · 0 评论 -
动态内存管理类示例——string专用版vector容器
规划vector实现原理是预先分配足够的内存来保存元素,然后每添加一个元素都会检查是否有空间容纳更多元素。如果有,成员函数会在下一个可用位置构造一个对象,如果没有,vector就会重新分配空间(获得新的更大的空间,然后将已有元素移动到新的空间中,释放旧空间,然后添加新元素)我们使用类似的策略:先使用allocator来获得没被构造过的原始内存,添加新元素时都用construct在原始内存上创建对象。当删除元素时使用destroy销毁元素。用三个指针指向三个位置:elements指向分配的内存中的首元原创 2021-04-25 21:04:42 · 147 阅读 · 0 评论 -
第十三章-拷贝控制
拷贝构造函数如果一个拷贝构造函数的第一个参数是自身类型的引用,且其他参数都有默认值,则此构造函数是拷贝构造函数class Foo{public: Foo(); //默认构造函数 Foo(const Foo&); //拷贝构造函数 //...};//拷贝构造函数的第一个参数必须是引用也可以定义接受非const引用的拷贝构造函数,但大多数情况下都是一个const引用拷贝构造函数不应该是explict的理解直接初始化和拷贝初始化之间的差异string dots(10,原创 2021-04-27 19:25:50 · 76 阅读 · 0 评论 -
拷贝控制示例——Message和Folder
条件使用两个类设计,Message——表示电子邮件消息,Folder——表示消息目录。每个Message可以出现在多个Folder中。修改某一条Message,它在它所在的所有Folder中都会被修改。Message使用一个set保存它所在的Folder的Folder指针。Folder也会用set保存它包含的Message的Message指针。Message要有save和remove操作,向一个给定的Folder添加或删除一条Message。Folder也得有类似的操作。拷贝一个Message原创 2021-04-26 21:06:46 · 1307 阅读 · 0 评论 -
第十四章-运算符重载
重载运算符的参数数量与该运算符作用的运算对象数量一样。一元运算符有一个参数,二元运算符有两个参数如果一个运算符函数是成员函数,则它第一个(左侧)对象绑定到隐式的this指针上。所以成员运算符函数的参数数量要比运算符运算对象少一个对运算符函数来说,它要么是类的成员函数,要么至少得有一个类类型的参数可以像调用普通函数那样直接调用运算符函数//注意这是 非成员 运算符函数的等价调用data1 + data2;operator+(data1, data2);也能像调用其他成员函数调用成员运算符.原创 2021-05-09 19:48:34 · 201 阅读 · 1 评论 -
第十五章-面向对象(一)
定义基类和派生类【例】书店不同书的定价策略不同,有的书按原价销售,有的打折销售等等.....编写Quote基类,表示按原价销售的书籍派生出Bulk_quote类,表示可以打折书籍class Quote{public: Quote() = default; Quote(const string &book, double sales_price) : bookNo(book), price(sales_price) {} string isbn() const { return bo原创 2021-05-25 20:04:45 · 100 阅读 · 0 评论 -
第十五章-面向对象(二)
继承中的类作用域设计在继承关系中,派生类的作用域嵌套在基类的作用域中。如果一个名字在派生类中不能正确解析,则编译器将继续在外层的基类作用域中寻找该名字的定义(正是这种作用域嵌套关系,所以派生类才能像使用自己的成员一样使用基类的成员)Bulk_quote bulk;cout << bulk.isbn();//第一步,因为是Bulk_quote调用的isbn,所以先在Bulk_quote中找isbn的名字,没有找到//第二步,Bulk_quote是Disc_quote的派生类,所以在D原创 2021-06-02 17:20:08 · 71 阅读 · 0 评论 -
第十五章课后习题答案(差15.31-15.42)
//15.1在类中被声明为virtual的成员,基类希望这种成员能被派生类重定义除了构造函数外,所有非static成员都可以是虚成员//15.2基类希望派生类有权访问而禁止其他用户访问的成员定义为protectedprivate只能被基类的成员和友元访问,派生类也不能访问//15.3class Quote{public: Quote()=default; Quote(string &book, double sales_price) : bookNo(book), price(原创 2021-10-12 13:16:15 · 92 阅读 · 0 评论 -
面向对象示例——Basket类
目标定义一个能存放继承关系的容器Baseket类难点容器中不能保存不同类型的元素,那么该如何将具有继承关系的多种类型的对象存放在容器中呢?比如Bulk_quote和Quote,因为我们不能将Quote转换为Bulk_quote,所以容器肯定不能存放Bulk_quote类型。那保存Quote类型吗?也不行,虽然保存Quote类型可以让Bulk_quote放置进该容器,但是会丢失派生类自己的部分。vector<Quote> basket;basket.push_back(Quote("0-原创 2021-06-02 19:36:04 · 267 阅读 · 0 评论 -
第十八章-异常处理和命名空间
抛出异常栈展开:抛出异常后,程序暂停当前函数执行过程并立即开始寻找和异常匹配的catch。如果throw出现在try里,就检查该try关联的catch,如果没找到且该try嵌套在其他try中,则继续检查与外层try匹配的catch。如果还是没找到,就退出当前函数,在调用当前函数的外层函数中继续寻找;如果有抛出异常的函数的调用语句在try中,就检查对应的catch,如果没找到且try嵌套在别的try中…同上。假设找到一个匹配的catch子句,则程序进入该子句并执行其中的代码。执行完后找到与try块关联的原创 2021-07-09 16:12:17 · 123 阅读 · 0 评论 -
第十八章-多重继承和虚继承
以动物园中动物的层次关系举例。定义一个抽象类ZooAnimal来保存动物园中动物共有的信息并提供公共接口,再定义一些辅助类,比如濒临灭绝的动物panda,由Bear和Endangered共同派生来:class Bear : public ZooAnimal {};class Panda : public Bear, public Endangered {};构造一个派生类的对象将同时构造并初始化它的所有基类子对象//显式初始化所有基类Panda::Panda(string name, b.原创 2021-07-10 15:10:05 · 214 阅读 · 1 评论 -
十八章课后习题答案
//18.1(a)类型是range_error(b)被抛出的异常对象是对指针p解引用的结果,类型与p的静态类型相同,为exception若写成throw p,则异常对象是exception*//18.2在释放资源前发生了异常,导致内存泄漏//18.3方法一将可能发生异常的代码放在try中,捕获异常后进行释放void exercise(int *b, int *e){ vector<int> v(b, e); int *p = new int[v.size()]; try原创 2021-10-13 18:18:16 · 55 阅读 · 0 评论