《C++ Primer Plus》读书笔记 第二章 开始学习C++

第二章 开始学习C++

本章对C++程序的基本结构做一概述,并预览后面将介绍的主题,如函数和类。

进入C++

cpp 复制代码
// myfirst.cpp--displays a message

#include <iostream>                           // a PREPROCESSOR directive
int main()                                    // function header
{                                             // start of function body
    using namespace std;                      // make definitions visible
    cout << "Come up and C++ me some time.";  // message
    cout << endl;                             // start a new line
    cout << "You won't regret it!" << endl;   // more output
// If the output window closes before you can read it,
// add the following code:
    // cout << "Press any key to continue." <<endl;
	// cin.get();                                                   
    return 0;                                 // terminate main()
}                                             // end of function body

示例代码包含下述元素

  • 注释,由前缀//标识。
  • 预处理器编译指令#include。
  • 函数头:int main( )。
  • 编译指令using namespace。
  • 函数体,用{和}括起。
  • 使用C++的cout工具显示消息的语句。
  • 结束main( )函数的return语句。

main( )函数

  • 第一行int main( )叫函数头(function heading),花括号({和})中包括的部分叫函数体。函数头对函数与程序其他部分之间的接口进行了总结;函数体是指出函数应做什么的计算机指令。
  • 在C++中,每条完整的指令都称为语句。所有的语句都以分号结束,绝对不能省略。
  • main( )中最后一条语句叫做返回语句(return statement),它结束该函数。

作为接口的函数头

  • C++函数可被其他函数激活或调用,函数头描述了函数与调用它的函数之间的接口。位于函数名前面的部分叫做函数返回类型,它描述的是从函数返回给调用它的函数的信息。函数名后括号中的部分叫做形参列表(argument list)或参数列表(parameter list);它描述的是从调用函数传递给被调用的函数的信息。

  • 通常,main( )被启动代码调用,而启动代码是由编译器添加到程序中的,是程序和操作系统(UNIX、Windows 7或其他操作系统)之间的桥梁。事实上,该函数头描述的是main( )和操作系统之间的接口。

  • 如果编译器到达main( )函数末尾时没有遇到返回语句,则认为main( )函数以如下语句结尾:

    cpp 复制代码
    return 0

    这条隐含的返回语句只适用于main( )函数,而不适用于其他函数。

为什么main( )不能使用其他名称

  • C++程序必须包含一个名为main( )的函数(不是Main( )、MAIN( )或mane( )。记住,大小写和拼写都要正确)
  • 在运行C++程序时,通常从main( )函数开始执行。因此,如果没有main( ),程序将不完整,编译器将指出未定义main( )函数。
  • 例外的情况:Windows编程中动态链接库(DLL)模块、专用环境的程序---如机器人中的控制器芯片

C++注释

  • C++注释以双斜杠(//)打头。
  • C++注释以//打头,到行尾结束。注释可以位于单独的一行上,也可以和代码位于同一行。
  • C++也能够识别C注释/* */

C++预处理器和iostream文件

  • C++和C一样,也使用一个预处理器,它处理名称以#开头的编译指令,该程序在进行主编译之前对源文件进行处理,不必执行任何特殊的操作来调用该预处理器,它会在编译程序时自动运行。
  • #include <iostream> 该编译指令导致预处理器将iostream文件的内容添加到程序中。
  • iostream文件的内容将取代程序中的代码行#include 。原始文件没有被修改,而是将源代码文件和iostream组合成一个复合文件,编译的下一阶段将使用该文件。
  • C++的输入/输出方案涉及iostream文件中的多个定义。为了使用cout来显示消息,第一个程序需要这些定义。

头文件名

  • 像iostream这样的文件叫做包含文件(include file)---由于它们被包含在其他文件中;也叫头文件(header file)---由于它们被包含在文件起始处。
  • C++编译器自带了很多头文件,每个头文件都支持一组特定的工具。
  • 对老式C的头文件保留了扩展名h(C++程序仍可以使用这种文件),而C++头文件则没有扩展名。
  • 有些C头文件被转换为C++头文件,这些文件被重新命名,去掉了扩展名h(使之成为C++风格的名称),并在文件名称前面加上前缀c(表明来自C语言)。

名称空间

  • 名称空间可以用来区分不同厂商产品的同名函数。
  • using namespace std; 这个using编译指令使得std名称空间中的所有名称都可用。
  • 最好是只使所需的名称可用,如using std::cout

使用cout进行C++输出

  • cout是一个预定义对象,用来显示字符串、数字和单个字符等。
  • cout的对象属性包括一个插入运算符(<<),它可以将其右侧的信息插入到流中。

控制符endl

  • endl是一个特殊的C++符号,表示一个重要的概念:重起一行。

换行符

  • C++还提供了另一种在输出中指示换行的旧式方法:C语言符号\n。
  • endl确保程序继续运行前刷新输出(将其立即显示在屏幕上);而使用"\n"不能提供这样的保证,这意味着在有些系统中,有时可能在您输入信息后才会出现提示。
  • 换行符是一种被称为"转义序列"的按键组合。

C++源代码的格式化

  • 在C++中,分号标示了语句的结尾。
  • 在C++中,回车的作用就和空格或制表符相同。
  • 在C++中,通常可以在能够使用回车的地方使用空格,反之亦然。

源代码中的标记和空白

  • 一行代码中不可分割的元素叫做标记(token)。
  • 必须用空格、制表符或回车将两个标记分开。
  • 空格、制表符和回车统称为空白(white space)。
  • 括号和逗号是不需要用空白分开的标记。

C++源代码风格

  • 每条语句占一行。
  • 每个函数都有一个开始花括号和一个结束花括号,这两个花括号各占一行。
  • 函数中的语句都相对于花括号进行缩进。
  • 与函数名称相关的圆括号周围没有空白。

C++语句

cpp 复制代码
// carrots.cpp -- food processing program
// uses and displays a variable

#include <iostream>

int main()
{
    using namespace std;
    
    int carrots;            // declare an integer variable
    
    carrots = 25;            // assign a value to the variable
    cout << "I have ";
    cout << carrots;        // display the value of the variable
    cout << " carrots.";
    cout << endl;
    carrots = carrots - 1;  // modify the variable
    cout << "Crunch, crunch. Now I have " << carrots << " carrots." << endl;
    // cin.get();
	return 0;
}
  • C++程序是一组函数,而每个函数又是一组语句。
  • 声明语句创建变量,赋值语句给该变量提供一个值。

声明语句和变量

  • 声明语句指出信息的存储位置和所需的内存空间。
  • 所有变量都必须声明。
  • 程序中的声明语句叫做定义声明(defining declaration)语句,简称为定义(definition)。
  • 在首次使用变量前声明它。

赋值语句

  • 赋值语句将值赋给存储单元。
  • 符号=叫做赋值运算符。
  • 可以连续使用赋值运算符。

cout的新花样

  • cout可用于数字和字符串,把值转换为合适的输出字符。
  • cout的智能行为源自C++的面向对象特性。C++插入运算符(<<)将根据其后的数据类型相应地调整其行为。

其他C++语句

cpp 复制代码
// getinfo.cpp -- input and output
#include <iostream>

int main()
{
    using namespace std;
    
    int carrots;
    
    cout << "How many carrots do you have?" << endl;
    cin >> carrots;                // C++ input
    cout << "Here are two more. ";
    carrots = carrots + 2;
// the next line concatenates output
    cout << "Now you have " << carrots << " carrots." << endl;
	// cin.get();
	// cin.get();
    return 0;
}

使用cin

  • 与cout一样,cin也是一个智能对象。它可以将通过键盘输入的一系列字符(即输入)转换为接收信息的变量能够接受的形式。

使用cout进行拼接

  • iostream文件定义了<<运算符,以便可以像下面这样合并(拼接)输出:

    cpp 复制代码
    cout << "Now you have " << carrots << " carrots." << endl;

类简介

  • 类是用户定义的一种数据类型。
  • 类定义描述的是数据格式及其用法,而对象则是根据数据格式规范创建的实体。
  • 函数可以来自函数库,类也可以来自类库。ostream和istream类就属于这种情况。
  • C++提供了两种发送消息的方式:一种方式是使用类方法(本质上就是稍后将介绍的函数调用);另一种方式是重新定义运算符,cin和cout采用的就是这种方式。

函数

cpp 复制代码
// sqrt.cpp -- using the sqrt() function

#include <iostream>
#include <cmath>    // or math.h

int main()
{
    using namespace std;
   
    double area;
    cout << "Enter the floor area, in square feet, of your home: ";
    cin >> area;
    double side;
    side = sqrt(area);
    cout << "That's the equivalent of a square " << side 
         << " feet to the side." << endl;
    cout << "How fascinating!" << endl;
	// cin.get();
	// cin.get();
    return 0;
}
  • C++函数分两种:有返回值的和没有返回值的。

使用有返回值的函数

  • 有返回值的函数将生成一个值,而这个值可赋给变量或在其他表达式中使用。
  • 被调用的函数叫做被调用函数(calledfunction),包含函数调用的函数叫做调用函数(calling function)。
  • 圆括号中的值是发送给函数的信息,这被称为传递给函数。该值叫做参数。
  • 发送回去的值叫做函数的返回值(return value)。

  • C++程序应当为程序中使用的每个函数提供原型。函数原型之于函数就像变量声明之于变量---指出涉及的类型。如 double sqrt(double);
  • 原型结尾的分号表明它是一条语句,这使得它是一个原型,而不是函数头。
  • 可以用两种方法来实现: 在源代码文件中输入函数原型;包含头文件如cmath,其中定义了原型。
  • 原型只描述函数接口,它描述的是发送给函数的信息和返回的信息。而函数定义包含了函数的代码。
  • 应在首次使用函数之前提供其原型。通常的做法是把原型放到main( )函数定义的前面。

函数变体

  • 有些函数需要多个参数,参数间用逗号分开,double pow(double, double);
  • 有些函数不接受任何参数,int rand(void);
  • 有些函数没有返回值,void bucks(double);

用户定义的函数

cpp 复制代码
// ourfunc.cpp -- defining your own function
#include <iostream>
void simon(int);    // function prototype for simon()

int main()
{
    using namespace std;
    simon(3);       // call the simon() function
    cout << "Pick an integer: ";
    int count;
    cin >> count;
    simon(count);   // call it again
    cout << "Done!" << endl;
	// cin.get();
    // cin.get();
    return 0;
}

void simon(int n)   // define the simon() function
{
    using namespace std;

    cout << "Simon says touch your toes " << n << " times." << endl;
}                   // void functions don't need return statements
  • 标准C库提供了140多个预定义的函数。如果其中的函数能满足要求,则应使用它们。
  • 自己定义函数通常把原型放到main()定义之前,代码放在main()的后面。

函数格式

  • 函数定义采用统一格式,有一个函数头;然后是花括号中的函数体。
  • C++不允许将函数定义嵌套在另一个函数定义中。每个函数定义都是独立的,所有函数的创建都是平等的。

函数头

  • main( )的返回值并不是返回给程序的其他部分,而是返回给操作系统。

用户定义的有返回值的函数

cpp 复制代码
// convert.cpp -- converts stone to pounds
#include <iostream>
int stonetolb(int);     // function prototype
int main()
{
    using namespace std;
    int stone;
    cout << "Enter the weight in stone: ";
    cin >> stone;
    int pounds = stonetolb(stone);
    cout << stone << " stone = ";
    cout << pounds << " pounds." << endl;
	// cin.get();
    // cin.get();
    return 0;
}

int stonetolb(int sts)
{
     return 14 * sts;
}

函数特性:

  • 有函数头和函数体;
  • 接受一个参数;
  • 返回一个值;
  • 需要一个原型。

在多函数程序中使用using编译指令

当前通行的理念是,只让需要访问名称空间std的函数访问它是更好的选择。

让程序能够访问名称空间std的方法有多种:

  • 将using namespace std;放在函数定义之前,让文件中所有的函数都能够使用名称空间std中所有的元素。
  • 将using namespace std;放在特定的函数定义中,让该函数能够使用名称空间std中的所有元素。
  • 在特定的函数中使用类似using std::cout;这样的编译指令,而不是using namespace std;,让该函数能够使用指定的元素,如cout。
  • 完全不使用编译指令using,而在需要使用名称空间std中的元素时,使用前缀std::。

编程练习答案

具体代码详见《C++ Primer Plus(第6版)》编程练习源代码

相关推荐
青草地溪水旁2 小时前
设计模式(C++)详解——迭代器模式(2)
java·c++·设计模式·迭代器模式
9号达人2 小时前
Java18 新特性详解与实践
java·后端·面试
我不是混子2 小时前
java浮点数精度问题及解决方案
java·后端
karry_k2 小时前
混合存储架构
后端
yunxi_052 小时前
我用 Elasticsearch 做 RAG 检索的一些“土经验”
后端·llm
JaguarJack2 小时前
PHP 8.2 vs PHP 8.3 对比:新功能、性能提升和迁移技巧
后端·php
学历真的很重要2 小时前
Claude Code 万字斜杠命令指南
后端·语言模型·面试·职场和发展·golang·ai编程
Mr_WangAndy3 小时前
C++设计模式_创建型模式_单件模式
c++·单例模式·设计模式
茉莉玫瑰花茶3 小时前
C++扩展 --- 并发支持库(补充3)
开发语言·c++