使用语言参考手册

根据你在学习编程语言(特别是C++)的阶段,LearnCpp.com可能是你唯一用来学习C++或查找相关内容的资源。LearnCpp.com旨在以适合初学者的方式解释概念,但它无法涵盖语言的每一个方面。随着你开始探索超出这些教程所涵盖的主题,你不可避免地会遇到这些教程无法解答的问题。在这种情况下,你需要利用外部资源。

其中一个资源是Stack Overflow,你可以在那里提问(或者更好的是,阅读之前有人问过并已回答的相同问题)。但有时,更好的第一步是查阅参考手册。与倾向于关注最重要主题并使用非正式/常见语言以便于学习的教程不同,参考手册使用正式术语精确描述C++。正因为如此,参考材料往往是全面的、准确的……但也难以理解。

在本课中,我们将通过研究三个示例,展示如何使用cppreference,这是一个我们贯穿课程中经常引用的流行标准参考手册。

概览

Cppreference首先为你提供了一个关于核心语言和库的概览:

cppreference概览

从这里,你可以访问cppreference提供的所有内容,但使用搜索功能或搜索引擎会更方便。在完成LearnCpp.com上的教程后,概览是一个很好的去处,可以让你深入了解库,并看看语言还提供了哪些你可能不知道的功能。

表格的上半部分展示了当前语言中的特性,而下半部分则展示了技术规范,这些特性可能在未来版本中被添加到C++中,或者已经部分被接受到语言中。如果你想知道即将推出的新功能,这会很有用。

从C++11开始,cppreference在每个特性旁边都标注了它们被添加到语言标准的版本号。标准版本就是你在上面图片中某些链接旁边看到的小绿数字。没有版本号的特性自C++98/03以来就已可用。版本号不仅出现在概览中,而且在cppreference的每个地方都有,让你清楚地知道在特定的C++版本中你可以或不可以使用什么。

警告

如果你使用搜索引擎,而某个技术规范刚刚被标准接受,你可能会被链接到技术规范而不是官方参考,这两者可能有所不同。

提示

Cppreference是C++和C的参考手册。由于C++与C共享一些函数名,因此在搜索某些内容后,你可能会发现自己进入了C的参考部分。Cppreference的网址和顶部的导航栏始终会显示你正在浏览的是C还是C++的参考部分。

std::string::length

我们先来研究一个你在之前课程中已经熟悉的函数:std::string::length,它返回字符串的长度。

在cppreference的右上角搜索“string”。这样做会显示一个长长的类型和函数列表,目前只有顶部的内容是相关的。

字符串搜索

我们本可以直接搜索“string length”,但为了在本课程中展示尽可能多的内容,我们选择走长路。点击“Strings library”会带你进入一个关于C++支持的各种字符串类型的页面。

字符串库页面

如果我们查看“std::basic_string”部分,可以看到一个typedef列表,其中包含std::string。

点击“std::string”会带你进入std::basic_string的页面。没有专门的std::string页面,因为std::string是std::basic_string的typedef,这也可以在typedef列表中看到:

typedef

<char>表示字符串中的每个字符都是char类型。你会注意到C++还提供了其他使用不同字符类型的字符串。在使用Unicode而不是ASCII时,这些会很有用。

在同一个页面的下方,有一个成员函数列表(类型的行为)。如果你想了解某种类型可以做什么,这个列表非常方便。在这个列表中,你会找到一个关于length(和size)的条目。

点击链接会带你进入length和size的详细函数描述页面,这两个函数的作用相同。

每个页面的顶部都以该特性的简要概述、语法、重载或声明开始:

字符串长度重载

页面标题显示了类和函数的名称以及所有模板参数。我们可以忽略这部分内容。在标题下方,我们可以看到所有不同的函数重载(共享相同名称的不同版本的函数)以及它们适用于哪种语言标准。

在那之下,我们可以看到函数接受的参数以及返回值的含义。

由于std::string::length是一个简单的函数,所以这个页面的内容并不多。许多页面会展示它们所记录的特性的示例用法,这个页面也是如此:

字符串长度示例

当你还在学习C++时,示例中会有一些你尚未见过的特性。如果有足够的示例,你可能能够理解足够多的内容,从而大致了解函数的用法和作用。如果示例过于复杂,你可以在其他地方搜索示例,或者查阅你不理解的部分的参考内容(你可以点击示例中的函数和类型,查看它们的作用)。

现在我们知道了std::string::length的作用,但我们之前就知道了。让我们来看看一些新的内容!

std::cin.ignore

在第9.5课——std::cin和处理无效输入中,我们提到了std::cin.ignore,它用于忽略直到换行符的所有内容。这个函数的一个参数是一个冗长的值。那是什么来着?难道不能直接用一个大数字吗?这个参数到底有什么作用?让我们来搞清楚!

在cppreference搜索“std::cin.ignore”会得到以下结果:

搜索引擎结果

  • std::cin, std::wcin — 我们想要的是.ignore,而不是普通的std::cin。
  • std::basic_istream<CharT,Traits>::ignore — 哎呀,这是什么?我们先跳过这个。
  • std::ignore — 不,这不是我们要找的。
  • std::basic_istream — 这个也不是。

没有找到,那怎么办?我们去std::cin的页面,从那里开始查找。在那一页上没有明显的内容。在页面顶部,我们可以看到std::cin和std::wcin的声明,它告诉我们需要包含哪个头文件才能使用std::cin:

声明

我们可以看到,std::cin是一个std::istream类型的对象。我们点击链接进入std::istream的页面:

basic_istream

等一下!我们在搜索“std::cin.ignore”时之前见过std::basic_istream。原来istream是basic_istream的typedef名称,所以我们的搜索并没有完全错误。

在该页面向下滚动,我们会看到熟悉的函数:

成员函数

我们已经使用过其中许多函数:operator»、get、getline、ignore。在该页面上浏览一下,了解一下std::cin中还有哪些其他内容。然后点击ignore,因为这是我们感兴趣的。

ignore

在页面顶部有函数签名和对函数及其两个参数的描述。参数后面的“=”符号表示默认参数(我们在第11.5课——默认参数中会讲到)。如果我们没有为具有默认值的参数提供参数,就会使用默认值。

第一个要点回答了我们所有的问题。我们可以看到,std::numeric_limitsstd::streamsize::max()对std::cin.ignore有特殊含义,它会禁用字符计数检查。这意味着std::cin.ignore会一直忽略字符,直到找到分隔符,或者直到没有更多的字符可供查看。

很多时候,如果你已经知道某个函数的作用,但忘记了参数或返回值的含义,你不需要阅读整个函数描述。在这种情况下,阅读参数或返回值的描述就足够了。

参数和返回值

参数描述非常简洁。它没有包含std::numeric_limitsstd::streamsize::max()的特殊处理或其他停止条件,但作为一个提醒很有用。

语言语法示例

除了标准库之外,cppreference还记录了语言语法。这里有一个有效的程序:

#include <iostream>

int getUserInput()
{
    int i{};
    std::cin >> i;
    return i;
}

int main()
{
    std::cout << "How many bananas did you eat today? \n";

    if (int iBananasEaten{ getUserInput() }; iBananasEaten <= 2)
    {
        std::cout << "Yummy\n";
    }
    else
    {
        std::cout << iBananasEaten << " is a lot!\n";
    }

    return 0;
}

为什么在if语句的条件中有一个变量定义?我们通过在最喜欢的搜索引擎中搜索“cppreference if statement”来使用cppreference找出它的作用。这样会带你进入if语句的页面。在页面顶部,有一个语法参考。

查看if语句的语法。如果你去掉所有的可选部分,你会得到一个你已经熟悉的if语句。在条件之前,有一个可选的初始化语句(init-statement),这看起来就像上面代码中发生的情况。

if (init-statement condition) statement-true
if (init-statement condition) statement-true else statement-false

在语法参考下方,是对语法的每个部分的解释,包括初始化语句。它提到初始化语句通常是一个带有初始化器的变量声明。

在语法之后是对if语句的解释和简单示例:

解释与示例

我们已经知道if语句是如何工作的,示例中没有包含初始化语句,所以我们向下滚动一点,找到一个专门讨论带有初始化器的if语句的部分:

带有初始化器的If语句

首先,展示了如何在不实际使用初始化语句的情况下编写初始化语句。现在我们知道上面的代码在做什么了。它是一个普通的变量声明,只是合并到了if语句中。

接下来的句子很

关注公众号,回复"cpp-tutorial"

可领取价值199元的C++学习资料

公众号二维码

扫描上方二维码或搜索"cpp-tutorial"