C++ Primer Plus(第六版)—— 第四章 复合类型 笔记和答案


1.不能将一个数组赋值给另一个数组。

[cpp]  view plain  copy
  1. int a[5] = { 1, 2, 3, 4 };  
  2. char b[4] = { 'a' };  
  3. char c[10];//未初始化的字符好像经常会显示“烫烫烫烫烫”,哈哈哈哈哈哈哈哈哈哈哈  
  4. int d[4];//未初始化的int经常是-858993460。  
百度一下:
烫烫烫和屯屯屯产生自VC,这是debug模式下VC对内存的初始化操作。
VC会把栈中新分配的内存初始化为0xcccccccc,而把堆中新分配的内存初始化为0xcd。
把0xcc和0xcd按照字符打印出来,就是烫和屯了。
还有锟斤拷,这个是字符编码造成的。在进行从老的编码体系到unicode的转换过程中,
部分字符不能转化,于是unicode给了它们一个特殊的占位符U + FFFD,这个用UTF - 8表示就成了\xef\xbf\xbd。
如果出现两个连着的\xef\xbf\xbd\xef\xbf\xbd,按照两个字节一个字显示成汉字,就成了锟斤拷这三个字。
而0xcccccccc用int格式就是-858993460了。。。
设计成0xcccccccc是有特殊用意的……这个好像叫做Poison,未初始化的Pointer去取值的话会出错。
肯定有人问为什么不弄成0x00000000,因为空指针是指针的有效状态,可能会误导人,
而0xCCCCCCCC在Windows下永远不可能是一个指针的有效状态(不是NULL,不指向一个对象,不指向一堆对象紧接之后的区域),这就是在模拟野指针


2.string是以\0结尾的,char[]没有特别赋值的话,是没有的。

[cpp]  view plain  copy
  1. char a2[5] = { 'a''b''c''d''e' };  
  2. char b2[5] = { 'a''b''c''d''\0' };  
  3. cout << a2 << endl;  
  4. cout << b2 << endl;  
cout的时候,a2是没有结尾的,所以会一直往下走,知道出现一个\0为止。


每一次运行的结果可能都不同。


3.C++对字符串的长度没有限制,处理的时候碰到\0就会结束。


4.字符串常量,隐式添加了\0。例如‘S’和“S”是不同的,“S”中实际是两个字符,S和\0。\0只会在末尾出现,两个字符串拼接,则中间是没有\0的。


5.通过cin输入的字符串,用空字符(空格、回车、制表符等)来结尾。

[cpp]  view plain  copy
  1. char a2[25] ;  
  2. char b2[25] ;   
  3. cout << "input name:" << endl;  
  4. cin >> a2;  
  5. cout << "input school" << endl;  
  6. cin >> b2;  
  7. cout << "name:" << a2 << endl;  
  8. cout << "school:" << b2 << endl;  
结果是:


输入的fable game之后,就跳过了。

这个数组超过25个之后居然还能正常输出。只不过后面就跟着中断了。


6.位字段,真惭愧,第一次听说到这个东西。每个字段占的内存是按位来算的,不是原来基础类型的字节大小。在成员名后面加个:和位数就可以了。

一般用于硬件编程了,已经非常非常底层了。怪不得还没听说过。

[cpp]  view plain  copy
  1. typedef struct bit_field {  
  2. unsigned int a : 5;  
  3. unsigned int b : 3;  
  4. unsigned int c : 20;  
  5. unsigned int d : 4;  
  6. } bit_field_s;  

7.共同体,用于节省内存。还是没有用过。。。。。。


8.枚举形的强制类型转换,好像是没有任何异常检测和抛错什么的。。。

[cpp]  view plain  copy
  1. enum EMyEnum  
  2. {  
  3.     EMyEnum1,  
  4.     EMyEnum2,  
  5.     EMyEnum3,  
  6.     EMyEnum4,  
  7. };  
  8. EMyEnum a = EMyEnum(5);  
结果a的值是5.
这个平时写代码经常用到,自己写代码检测又嫌麻烦。只能自己把握了。


9.指针的声明,每一个变量都要带*

[cpp]  view plain  copy
  1. int i = 123;  
  2. int* p1, p2;  
  3. p1 = &i;  
  4. p2 = &i;//这一句编译不过,因为p2是int,而不是int*  

10.new分配的内存一般都在堆(heap)或者自由存储区中,变量声明的内存一般都在栈(stack)中。


11.C++3中管理内存的方式:自动存储,静态存储,动态存储。

    a.自动存储:局部变量,放在栈中,后进先出。函数被退出栈,变量就没了。

    b.静态存储:static,或者写在函数外

    c.动态存储:new出来的都是,放在堆中。

[cpp]  view plain  copy
  1. #include "Chapter4.h"  
  2. #include <iostream>  
  3. #include "Chapter2.h"  
  4. using namespace std;  
  5. class CTest  
  6. {  
  7. public:  
  8.     CTest(char c);  
  9.     ~CTest();  
  10.     static CTest* getACTest();  
  11. private:  
  12.     char flag;  
  13. };  
  14.   
  15. CTest::CTest(char c)  
  16. {  
  17.     flag = c;  
  18.     cout << "create CTest, flag:" << flag << endl;  
  19. }  
  20.   
  21. CTest::~CTest()  
  22. {  
  23.     cout << "delete CTest, flag:" << flag << endl;  
  24. }  
  25.   
  26. CTest* CTest::getACTest()  
  27. {  
  28.     CTest b('b');  
  29.     CTest* c = new CTest('c');  
  30.     return c;  
  31. }  
  32.   
  33. static CTest a('a');  
  34. void CChapter4Answer::answer()  
  35. {  
  36.     CTest* c = CTest::getACTest();  
  37.     CTest d('d');  
  38. }  
试了一下,各个地方的变量什么时候创建和删除。

最后得到的结果:


因为a是静态变量,所以程序启动的时候先创建了a,然后才进入main函数。

在getTest函数内先创建了b,然后new了一个c。b是声明出来的,所以函数结束之后,就会删除掉,而c是new出来的,放在堆中。

然后创建d,删除d,其实d就是在一个更大的函数内而已。

然后走完main函数,在外面才删除了a。静态变量是在关闭程序的时候才回收的。

然后c呢,c的析构函数没有走到。证明在堆中的内存,程序是不会回收的,这就是内存泄露了吧。相信操作系统会回收吧。

另外,走出了main函数之后,还是有别的操作的。这真是第一次知道。

要人工确保new和delete,对于稍微大一点的程序来说,应该不大可能吧。一般都会用智能指针,所以我在工作中,根本没有主动使用过delete这个关键字。

但是即使是智能指针,还是会出现内存泄露的情况。最先想到的就是两个智能指针互相指向,都在等对方释放。


12.vector初始化可以用{}直接包含一些元素进去。

[cpp]  view plain  copy
  1. CTest* c = CTest::getACTest();  
  2. CTest d('d');  
  3.   
  4. vector<CTest> e = { d };//这个很方便  


4.12 复习

[cpp]  view plain  copy
  1. //1
  2. char actor[30] = { 0 };  
  3. short betsie[100] = { 0 };  
  4. float chuck[13] = { 0 };  
  5. long double dipsea[64] = { 0 };  

[cpp]  view plain  copy
  1. //2
  2. array<char, 30> actor = { 0 };  
  3. array<short, 100> betsie = { 0 };  
  4. array<float, 13> chuck = { 0 };  
  5. array<long double, 64> dipsea = { 0 };  

[cpp]  view plain  copy
  1. //3
  2. int a[5] = { 1, 2, 3, 4, 5 };  

[cpp]  view plain  copy
  1. //4
  2. int even = a[0] + a[4];  

[cpp]  view plain  copy
  1. //5
  2. float ideas[5] = { 1, 2, 3, 4, 5 };  
  3. cout << "ideas[1]:" << ideas[1] << endl;  

[cpp]  view plain  copy
  1. //6
  2. char c[20] = "cheeseburger";  
  3. cout << c << endl;  
[cpp]  view plain  copy
  1. //7
  2. string str = "Waldorf Salad";  
  3. cout << str << endl;  

[cpp]  view plain  copy
  1. //8
  2. struct SFish  
  3. {  
  4.     char type[20];  
  5.     int weight;  
  6.     double lenght;  
  7. };  

[cpp]  view plain  copy
  1. //9
  2. SFish fish = { "big", 2, 3.4 };  1.

[cpp]  view plain  copy
  1. //10
  2. enum Response  
  3. {  
  4.     No,  
  5.     Yes,  
  6.     Maybe,  
  7. };  

[cpp]  view plain  copy
  1. //11.
  2. double ted = 123.456;  
  3. double* tedPtr = &ted;  
  4. cout << *tedPtr << endl;  

[cpp]  view plain  copy
  1. //12.
  2. float treacle[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };  
  3. float* ptr = treacle;  
  4. cout << ptr[0] << " " << ptr[9] << endl;  

[cpp]  view plain  copy
  1. //13
  2. int n = 0;  
  3. cin >> n;  
  4. int* a = new int[n];  
  5. vector<int> b(n);  
  6. for (int i = 0; i < n; i++)  
  7. {  
  8.     a[i] = i;//原来调试的时候,是看不到a指向的数组的内存的。  
  9.     b[i] = i;  
  10. }  
  11. for (int i = 0; i < n; i++)  
  12. {  
  13.     cout << a[i] << " " << b[i] << endl;  
  14. }  

[cpp]  view plain  copy
  1. /*14.语句没有问题。其实就是把字符串指针,强制转换成整形指针。 
  2. cout只对字符串指针进行特殊处理,其他类型的指针是输出该指针的内容,即地址。*/
  3. char* b = "Home of the jolly bytes";  
  4. int* a = (int *)b;  
  5. cout << a << " " << *a << endl;  
  6. cout << b << " " << *b << endl;  
  7. cout << (int *)"Home of the jolly bytes" << endl;  

[cpp]  view plain  copy
  1. //15.
  2. struct SFish  
  3. {  
  4.     char type[20];  
  5.     int weight;  
  6.     double lenght;  
  7. };  
  8. SFish* fish = new SFish{ "big", 2, 3.4 };  
  9. cout << "fish type:" << fish->type << " wight:" << fish->weight << " lenght:" << fish->lenght << endl;  

[cpp]  view plain  copy
  1. //16.还是要看看4.6清单的代码  只读单词,不能读整行
  2. int year;  
  3. cin >> year;//这里点了回车键  
  4. char address[80];  
  5. cin.getline(address, 80);//这里只读了一个回车键,没机会输入  
  6. cout << year << " " << address << endl;//address没有相应的内容  
  7. cin >> year;  
  8. cin >> address;  
  9. cout << year << " " << address << endl;//可以输入adress,不能读取空白字符,只能读一个单词  

[cpp]   view plain  copy
  1. //17.
  2. const int num = 10;  
  3. vector<string> a(num);// #include <string>  
  4. array<string, num> b;// #include <array>  


4.13 编程练习

[cpp]  view plain  copy
  1. //1
  2. string firstName = "";  
  3. string lastName = "";  
  4. cout << "What is your first name? " ;  
  5. getline(cin, firstName);  
  6. cout << "What is your last name? ";  
  7. getline(cin, lastName);  
  8. cout << "What letter grade do you deserve? ";  
  9. char grade;  
  10. cin >> grade;  
  11. grade++;  
  12. cout << "What is your age?";  
  13. int age;  
  14. cin >> age;  
  15. cout << "Name: " << lastName << ", " << firstName << endl;  
  16. cout << "Grade: " << grade << endl;  
  17. cout << "Age: " << age << endl;  

[cpp]  view plain  copy
  1. //2
  2. string name;  
  3. string dessert;  
  4. cout << "Enter your name:\n";  
  5. getline(cin, name);  
  6. cout << "Enter your favorite dessert:\n";  
  7. getline(cin, dessert);  
  8. cout << "I have some delicious " << dessert;  
  9. cout << " for you, " << name << endl;  

[cpp]  view plain  copy
  1. //3
  2. cout << "Enter your first name:";  
  3. char firstName[20];  
  4. cin.getline(firstName, 20);  
  5. cout << "Enter your last name:";  
  6. char lastName[20];  
  7. cin.getline(lastName, 20);  
  8. char name[80] = {0};//这个不初始化会出现中断  
  9. strcat_s(name, firstName);  
  10. strcat_s(name, ", ");  
  11. strcat_s(name, lastName);  
  12. cout << "Here's the information in a single string: "<< name;  

[cpp]  view plain  co
  1. //4
  2. string firstName = "";  
  3. string lastName = "";  
  4. cout << "Enter your first name:";  
  5. getline(cin, firstName);  
  6. cout << "Enter your last name:";  
  7. getline(cin, lastName);  
  8. string name = firstName + ", " + lastName;  
  9. cout << "Here's the information in a single string: " << name;  

[cpp]  view plain  copy
  1. //5
  2. struct CandyBar  
  3. {  
  4.     string brand;//品牌  
  5.     double weight;//重量  
  6.     int calorie;//卡路里  
  7. };   
  8. CandyBar snack = { "Mocha Munch", 2.3, 350 };  
  9. cout << "Candy brand:" << snack.brand << " weight:" << snack.weight << " calorie:" << snack.calorie;  

[cpp]  view plain  copy
  1. //6
  2. struct CandyBar  
  3. {  
  4.     string brand;//品牌  
  5.     double weight;//重量  
  6.     int calorie;//卡路里  
  7.     void getInfo()  
  8.     {   
  9.         cout << "Candy brand:" << brand << " weight:" << weight  << " calorie:" << calorie << "\n";  
  10.     }  
  11. };   
  12. CandyBar snack = { "Mocha Munch", 2.3, 350 };  
  13. snack.getInfo();  
  14. CandyBar candyArr[3] = { { "Mocha Munch", 2.3, 350 }, { "Big Rabbit", 3.4, 150 }, { "Alps", 4.5, 650 } };  
  15. candyArr[0].getInfo();  
  16. candyArr[1].getInfo();  
  17. candyArr[2].getInfo();  
[cpp]  view plain  copy
  1. //6
  2. struct Pizza  
  3. {  
  4.     string company;//品牌  
  5.     double weight;//重量  
  6.     double diameter;//直径  
  7.           
  8. };   
  9. Pizza p = { "", 0, 0 };  
  10. cout << "Please enter company:";  
  11. getline(cin, p.company);  
  12. cout << "Please enter diameter:";  
  13. cin >> p.diameter;  
  14. cout << "Please enter weight:";  
  15. cin >> p.weight;  
  16. cout << "Pizza company:" << p.company << "\ndiameter:" << p.diameter << "\nweight:" << p.weight << "\n";  

[cpp]  view plain  copy
  1. //7
  2. struct Pizza  
  3. {  
  4.     string company;//品牌  
  5.     double weight;//重量  
  6.     double diameter;//直径  
  7.           
  8. };   
  9. Pizza* p = new Pizza{ "", 0, 0 };  
  10. cout << "Please enter diameter:";  
  11. cin >> p->diameter;  
  12. getline(cin, p->company);//把回车符读取了  
  13. cout << "Please enter company:";  
  14. getline(cin, p->company);  
  15. cout << "Please enter weight:";  
  16. cin >> p->weight;  
  17. cout << "Pizza company:" << p->company << "\ndiameter:" << p->diameter << "\nweight:" << p->weight << "\n";  
  18. delete p;  
  19. p = NULL;

[cpp]  view plain  copy
  1. //9
  2. struct CandyBar  
  3. {  
  4.     string brand;//品牌  
  5.     double weight;//重量  
  6.     int calorie;//卡路里  
  7.     void printInfo()  
  8.     {   
  9.         cout << "Candy brand:" << brand << " weight:" << weight  << " calorie:" << calorie << "\n";  
  10.     }  
  11. };   
  12. CandyBar* candyArr = new CandyBar[3];  
  13. candyArr[0] = { "Mocha Munch", 2.3, 350 };  
  14. candyArr[1] = { "Big Rabbit", 3.4, 150 };  
  15. candyArr[2] = { "Alps", 4.5, 650 } ;  
  16. candyArr[0].printInfo();  
  17. candyArr[1].printInfo();  
  18. candyArr[2].printInfo();  
  19. delete[] candyArr;  
  20. candyArr = NULL;  

[cpp]  view plain  copy
  1. //10
  2. array<double, 3> socreArr;  
  3. cout << "Please enter you score:";  
  4. cin >> socreArr[0];  
  5. cout << "Please enter you score:";  
  6. cin >> socreArr[1];  
  7. cout << "Please enter you score:";  
  8. cin >> socreArr[2];  
  9. double totalScore = socreArr[0] + socreArr[1] + socreArr[2];  
  10. cout << "times:" << 3 << " averageScore:" << totalScore/3;  






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值