c++ primer 第五版 阅读笔记四

第四章 复合类型

4.1 数组

4.2 字符串

  • 字符串是存储在内存中的连续字节中的一系列字符。存储在连续字节中的一系列字符意味着可以将字符串存储在char数组中,其中每个字符都位于自己的数组元素中。
  • C++ 处理字符串的方式有两种:

1. 来自C 语言,常被成为 C- 风格字符串(C-style string)。

注意:char size = 'a' ( √ )          char size = "a" ( × )

#include <iostream>
#include <cstring>                  //strlen()的头文件

using namespace std;

int main()
{
    const int num = 15;
    char str1[] = "Hello world!";
    char str2[num];

    cin>>str2;

    cout<<strlen(str1)<<endl;       //strlen()求得的字符串的长度不含'\0' <-> typeof()
    cout<<strlen(str2)<<endl;

    return 0;
}

输出结果:

12

2

注意:如果 name 是字符串,则要存储该字符串,数组的长度不能短于 strlen(name) + 1。虽然字符串中还可能有其它的字符。

#include <iostream>
#include <cstring>                  //strlen()的头文件

using namespace std;

int main()
{
    const int num = 15;
    char name[num];
    char dessert[num];

    cout<<"Enter your name: \n";
    cin>>name;
    cout<<"Enter your favourite dessert: \n";
    cin>>dessert;
    cout<<"I have some delicious "<<dessert;
    cout<<" for you."<<name<<".\n";

    return 0;
}

输入及输出结果:

Enter your name:

Alistair Dreeb

Enter your favourite dessert:

I have some delicious Dreeb for you.Alistair.

 

#include <iostream>

using namespace std;

int main()
{
    const int num = 15;
    char name[num];
    char dessert[num];

    cout<<"Enter your name: \n";
    cin.getline(name,20);
    cout<<"Enter your favourite dessert: \n";
    cin.getline(dessert,20);
    cout<<"I have some delicious "<<dessert;
    cout<<" for you."<<name<<".\n";

    return 0;
}

输入及输出结果:

#include <iostream>

using namespace std;

int main()
{
    const int num = 15;
    char name[num];
    char dessert[num];

    cout<<"Enter your name: \n";
    cin.get(name,num);
//    cin.get();
    cout<<"Enter your favourite dessert: \n";
    cin.get(dessert,num);
    cout<<"I have some delicious "<<dessert;
    cout<<" for you."<<name<<".\n";

    return 0;
}

2. 基于string 类库的方法。

4.3 string 类简介

  • 使用 string 类,必须在程序中包含头文件string。string 类位于名称空间 std 中,因此您必须提供一条using 编译指令,或使用std::string来引用它。string 类定义隐藏了字符串的数组性质,让您能够像处理普通变量那样处理字符串。
  • 字符串和数组的相同点:

  • 字符串和数组的不同点:

问题:那么数组可以直接赋给string对象吗?

答:可以,我理解为都是对象。

#include <iostream>
#include <string>
#include <cstring>

using namespace std;

int main()
{
    const int num = 15;
    char name[num] = "hello";
    string str = "hello_world";

    cout<<str<<endl;
    str = name;

    cout<<name<<endl;
    cout<<str<<endl;

    return 0;
}

运行结果:

  • 字符串的拼接和附加:使用  + 、+=

  • string 类的其他操作: 头文件:cstring

1. strcpy():可以将字符串复制到字符数组中;strcpy(charr1,const charr2);  -》 strcpy(shuzu1,shuzu2);//将数组2的值赋给数组1。注意不可以将string类型的常字符串复制给数组,至于为什么我也不知道,可能与函数的具体实现有关。

2. strcat():将字符串附加到字符数组末尾;strcat(charr1,charr2);  -》 strcat(charr1,""juice);

注意:

3. str1.size():求字符串的长度;

  • string 类 I/O

4.4 结构简介

  • 创建结构体:
struct Type_name{
    int a;
    char b[10];
    ...
};

  • 创建结构体变量:
Typename a;
Typename b;
Typename c;
...

  • 访问结构体变量的成员:

  • 初始化结构:

  • 使用结构:

  • 结构的声明:

  • 结构可以使用string 类作为成员:

  • 其他结构属性:

#include <iostream>
#include <string>

using namespace std;

struct animal{
    char name[10];
    int age;
    string color;
};

int main()
{
    animal cat = {"cat",3,"white"};
    animal dog = {"dog",4,"yellow"};
    animal unknow;

    cout<<cat.name<<unknow.name<<endl;

    unknow = cat;
    cout<<cat.name<<unknow.name;

    return 0;
}

输出结果:

cat$
catcat

  • 数组结构

  • 结构中的位字段

4.5 共用体

4.6 枚举

ps:这节没有使用书本,有点麻烦,就从网上找了个视频,通俗易懂,大家也可以看一下:https://video.tudou.com/v/XMTg4NzgxODYyNA==.html?__fr=oldtd。接下来提炼一下视频内容:

在程序中,有时候我们需要一组关联性的常量。例如:使用键盘控制方向时,我们需要定义上下左右四个方向。

4.7 指针和自由存储空间

  • 使用 new 来分配内存

  • 使用 delete 来释放内存

使用 delete 操作符,使得在使用完内存后,能够将其归还给 内存池。而且 delete 只用来释放使用new分配的内存。不过,对空指针使用delete是安全的。

  • 使用 new 创建动态数组

这部分之前的博客有涉及,而且写的较为详细,所以就不赘述了。

回忆一下:

1. 一维数组的创建:int* p = new int [15];

2. 一维数组的销毁:delete p;

3. 如果作为参数返回,那么返回的是一个指向这个内存区域的地址(指针)

4. 分配的内存属于堆,而非栈

5. sizeof(p) == 4B

6. *(p + 1) == p[1]

7. 指针和字符串的关系

  • new 和 delete 的一个范例
#include <iostream>
#include <cstring>

using namespace std;

#define N 30

char* storeArr()
{
    char temp[80];
    cin>>temp;
    char* pr = new char (strlen(temp)+1);
    strcpy(pr,temp);
    return pr;
}

int main()
{
    int i = 0;
    char* pn;
    while(i < N)
    {
        pn = storeArr();
        cout<<pn;
        delete pn;
    }

    return 0;
}

以此可以解决,每来一个值可以动态的被存储。可以输出,但是如何能连续的存储呢?本来想使用 strcat() 的,但是它的长度是有限制的,但我们无法预计未来的规模,所以选择更友好的string 类进行改进设计了。而且输入次数有点多,偷懒改成4了,嘿嘿(✿◡‿◡)

#include <iostream>
#include <cstring>
#include <string>

using namespace std;

#define N 4

char* storeArr()
{
    char temp[80];
    cin>>temp;
    char* pr = new char (strlen(temp)+1);
    strcpy(pr,temp);
    return pr;
}

int main()
{
    int i = 0;
    char* pn;
    string str;
    while(i < N)
    {
        pn = storeArr();
        cout<<pn;
        str += pn;
        delete pn;
        i++;
    }
    cout<<endl;
    cout<<str;

    return 0;
}

输入与运行结果:

  • 自动存储、静态存储和动态存储

4.9 总结

本来准备自己总结的,但是感觉书上的总结更言简意赅一些,所以还是选择了书上的内容作为最后的总结。



复习题:

答:a) char actor[30];     b) short betsie[100];      c) float chunk[13];     d) long double dipsea[64];

答:int a[5] = {1,3,5,7,9};

答:int even = a[0] + a[4];

答:cout<<ideas[1];

答:char str[] = "cheeseburger";

答:struct fish{

string type;   //char type[20];

int weight;

double height;

};

答:fish f1 = {"lianyu",20,5.6};

答:enum Response {Yes=1,No=0,Maybe=2};          // 初始值是在里面直接赋值吗?

#include <iostream>

using namespace std;

enum Response {Yes = 1,No = 0,Maybe = 2};

void getRes(Response res)
{
    if(res)
    {
        cout<<res;
    }
    else if(res > 1)
    {
        cout<<res;
    }
    else
    {
        cout<<res;
    }
}

int main()
{
    Response res = Yes;
    getRes(res);

    return 0;
}

答:是的,如果不对枚举类型中的常量进行初始化,默认从左向右,从0开始一次递增1个单位。如果只对某项进行了初始化,那么其后的每项均在此项的基础上递增加1。

答:double* p = &ted; cout<<*p;  

答:

#include <iostream>

using namespace std;

int main()
{
    float treacle[10];
    for(int i = 0;i < 10;i++)
    {
        treacle[i] = i;
    }
    float* p = treacle;
    //float* p = &treacle[0];

    cout<<treacle[0]<<endl;
    cout<<*p<<endl;
    cout<<p[0]<<endl;
    cout<<endl;
    cout<<treacle[9]<<endl;
    cout<<*(p+9)<<endl;
    cout<<p[9]<<endl;

    return 0;
}

     

#include <iostream>

using namespace std;

int main()
{
    int num;
//    int p1[num];      //一维数组定义的时候可以使用变量来定义数组的长度
    cin>>num;
    int* p = new int (num);     //new的时候也可以

    for(int i = 0;i < num;i++)
    {
        p[i] = i;
    }
    for(int i = 0;i < num;i++)
    {
        cout<<p[i]<<"\t";
    }
    delete p;

    return 0;
}

? 遇到知识盲区了鸭

在IDE工具里跑了一下,结果是一个地址,不难想应该是字符串常量的地址。

回想之前,将一个char型的变量强制转化为int型输出也是通过此种方式,不同的是,那是一个普通变量,而这是一个地址的强制类型转化也就是需要用到指针*。

#include <iostream>
//#include <string>

using namespace std;

struct fish{
//    string type;
    char type[20];
    int weight;
    double height;
};

int main()
{
    fish* f1 = new fish;
    cout<<f1->type<<"\t"<<f1->weight<<"\t"<<f1->height;

    return 0;
}

用代码进行了编写,但发现了两个问题:

第一个,通过创建结构的对象,但是却没办法通过 . 来访问成员变量?原因是因为f1是一个指针而不是对象了吗?

答:应该是的,f1是一个指针,如果不通过动态内存分配,f1可以被创建成为一个对象,自然可以通过对象访问符号进行访问,但现在成为指针,只能通过 -> 来访问。

第二个问题,为什么结构体中不能定义string 类型的对象?根据之前看书是可以的呀?

答:是可以的,之所以不可以是因为访问符不合适其他的错误导致的影响。

#include <iostream>
#include <string>

using namespace std;

struct fish{
    string type;
//    char type[20];
    int weight;
    double height;
};

int main()
{
    fish* f1 = new fish;
    f1->type = "lianyu";
    f1->weight = 15;
    f1->height = 13.2;
    cout<<f1->type<<"\t"<<f1->weight<<"\t"<<f1->height;

    return 0;
}

答:cin是一词为一个单位进行提取的,就不能输入含空格的地址名了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值