《c++入门经典》笔记7

《c++入门经典》笔记7

第七章 使用数组和字符串存储信息

7.1数组是什么

数组是一系列类型相同的相关数据。可将数组视为一系列数据存储单元,其中每个存储单元都是数组的一个元素。

要声明数组,可依次指定数据类型、数组名以及用方括号括起的元素数,如下所示:

long peaks[25];

数组元素从0开始编号,直到n-1(n为数组长度)

程序清单7.1 WeightGoals.cpp

#include <iostream>
int main()
{
    float goal[4];
    goal[0]=0.9;
    goal[1]=0.75;
    goal[2]=0.5;
    goal[3]=0.25;
    float weight,target;

    std::cout<<"Enter current weight: ";
    std::cin>>weight;
    std::cout<<"Enter goal weight: ";
    std::cin>>target;
    std::cout<<std::endl;

    for (int i = 0; i < 4; i++)
    {
        float loss = (weight - target) * goal[i];
        std::cout<<"Goal "<<i<<": ";
        std::cout<<target+loss<<std::endl;
    }
    return 0;
}

7.2写入时超过数组末尾

数组越界没啥好说的,略

7.3初始化数组

例如:

int post[10] = {0,10,20,30,40,50,60,70,80,90};

如果省略长度,它包含的元素数将等于初始值数。

int post[] = {0,10,20,30,40,50,60,70,80,90};//10

获取数组元素,最常用的使用sizeof()

const int size = sizeof(post) / sizeof(post[0]);

初始化的元素数量不能超过声明的长度,比如:

int array[3] = {1,2,3,4};//编译器报错
int arr[3] = {1,2};//允许

7.4多维数组

n维数组是n-1维数组的堆叠

比如:

int board[8][8];//二维数组

就是八个长度为8的一维数组的堆叠,所以也可以用以下方法存储这些数据:

int board[64];

初始化多维数组:

程序清单7.2 Box.cpp

#include <iostream>
int main()
{
    int box[5][3] = {
        {8, 6, 7},
        {5, 3, 0},
        {9, 2, 1},
        {7, 8, 9},
        {0, 5, 2}};
        for (int i = 0; i < 5; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                std::cout<<"box["<<i<<"]";
                std::cout<<"["<<j<<"] = ";
                std::cout<<box[i][j]<<"\n";
            }
        }
    return 0;
}

也可各维元素放在一起,但是会比较难看:

    int box[5][3] = {8, 6, 7,5, 3, 0,9, 2, 1,7, 8, 9,0, 5, 2};

7.5字符数组

在c++中,字符串是以空字符结尾的字符数组,空字符是以编码为'\0'的特殊字符。可像其他数组那样声明并初始化字符串

char yum[] = {'Z','0','m','b','i','e',' ','E','a','t',' ','B','r','a','i','n','s','\0'};

最后的'\0'是用于结束字符串的空字符

这种逐个字符输入的方法比较困难,很容易出错,c++提供了使用字面量初始化字符串的简捷方式:

char yum[] = "Zombie Eat Brains";

这种初始化方法不需要使用空字符,而是由编译器自动添加的。

字符串"Zombie Eat Brains"占用18个字节(包括空字符)

也可创建未初始化的字符数组,这被称为缓冲区。

缓冲区可用于存储用户输入,虽然std::cin>>yum;可以将输入存储到变量中,但是如果用户输入的字符数超过了缓冲区的长度,cin写入时将跨过缓冲区边界,导致程序不能正确运行,更可能导致安全问题。其次,如果用户输入了空格,cin将认为字符串就此结束,不再将接下来的内容写入缓冲区

为解决这些问题,必须调用cin对象的getline()函数,并提供两个参数:

  • 要填充的缓冲区
  • 最多读取的字符数

下面的语句就是将用户输入中最多18个字符(包括空格)读取,将其存储到字符数组yum中:

std::cin.getline(yum,18);

调用这个方法时,还可提供第三个参数——终止输入的分隔符:

std::cin.getline(yum,18,' ');

这条语句在遇到空格之后停止读取输入。如果省略了第三个参数,则将换行符'\n'作为分隔符

程序清单7.3 BridgeKeeper.cpp

#include<iostream>
int main()
{
    char name[50];
    char quest[80];
    char velocity[80];

    std::cout<<"\nWhat is your name? ";
    std::cin.getline(name,49);
    std::cout<<"\nWhat is your quest? ";
    std::cin.getline(quest,79);
    std::cout<<"\nWhat is the velocity of an unladen swallow? ";
    std::cin.getline(velocity,79);
    
    std::cout<<"\nName:"<<name<<std::endl;
    std::cout<<"Quest:"<<quest<<std::endl;
    std::cout<<"Velocity:"<<velocity<<std::endl;
    return 0;   
}

运行如下:

这三个问题来自电影《巨蟒与圣杯》。

为什么在输入时输入的字符数比数组长度小1呢?这是因为需要预留(至少是最后那一个)位置给表示字符串终止的'\0'字符。

7.6复制字符串

string.h是专门用以处理字符串的函数库

头文件添加它的两种办法就是#include<cstring>或者#include<string.h>

这个库里面有两个用于将一个字符串复制到另一个字符串的函数,一个是strcpy(),另一个是strncpy()

strcpy与strncpy的区别:

strcpy是将整个数组复制到指定缓冲区(也就是另一个数组),但是这样可能会导致写入时超过缓冲区的边界。

strcpy_s(strings2,string1)//将整个s1复制到s2,strcpy_s是strcpy的安全版本函数,如果不用这个也可以,但有的编译器会警告或报错,比如vc++

strncpy接受第三个参数,指定最多复制多少个字符:

strncopy(string1,string2,80);

程序清单7.4 StringCopier.cpp

#include <iostream>
#include <cstring>

int main()
{
    char string1[] = "Free the bound periodicals!";
    char string2[80];
    char string3[20];

    strcpy(string2, string1);

    std::cout << "String1: " << string1 << std::endl;
    std::cout << "String2: " << string2 << std::endl;

    strncpy(string3,string1,19);
    std::cout << "String1: " << string1 << std::endl;
    std::cout << "String3: " << string3 << std::endl;
}

7.7使用foreach循环读取数组

c++新增了一种用于遍历数组元素的for循环,这种for循环通常被称为foreach循环,因为它对每个与那苏都执行循环一次

程序清单7.5 Production.cpp

#include <iostream>

int main()
{
    int production[]{10500, 16000, 5800, 4500, 13900};
    for (int year : production)
    {
        std::cout << "Output: " << year << std::endl;
    }
    return 0;
}

posted @ 2020-07-14 20:21  小立哥  阅读(152)  评论(1编辑  收藏  举报