《C++ Primer》第1章 开始
1.1 编写一个简单的C++程序
关于main函数
在C++中,一个函数定义包含返回类型、函数名、形参列表、函数体四个部分。
main
函数的定义也不例外。只是有以下特殊:
1.每个程序必须有且只有一个
main
函数。操作系统通过调用main
来运行C++程序。2.
main
函数的返回类型必须为int
。
main
函数的返回值用来指示状态。返回值0表明成功;非0的返回值的含义由系统指定,通常用来指出错误类型。
关于类型
值得注意的是,类型不仅定义了数据元素的内容,还定义了这类数据上可以进行的运算。
比如int
类型可以进行算数运算,而bool
类型可以进行逻辑运算。
编译、运行程序
计算机所使用的操作系统和编译器决定了如何编译程序。比如我的电脑用的是Linux操作系统,并安装了gcc编译器和g++编译器。
不同的编译器支持的C++源文件后缀名也略有不同,有.cc
、.cpp
、.cxx
等等。(用.cpp
即可)
1.命令行界面中,用以下命令编译程序:
$ CC prog1.cc
其中cc
为编译器的名字,$
为系统提示符,prog1.cc
为包含main
函数的源文件。
对应到Ubuntu+g++/gcc
,则为:
$ g++ prog1.cpp
执行完上述编译命令后,系统会生成可执行文件。Linux下可执行文件后缀为.out
。默认文件名为a.out
。
更常用的,我们用以下命令编译程序:
$ g++ -o prog1 prog1.cpp
-o prog1
是编译器参数,指定了可执行文件的文件名。在Linux中,会生成名为prog1
(不是prog1.out
)的可执行文件。
2.然后用以下命令即可运行程序:
$ ./a.out
./
表示a.out
在当前目录下。
3.访问main
函数返回值用以下命令:
$ echo $?
问题:P5-1.1节练习-练习1.2,改写程序,使其返回-1后,用
echo $?
查看返回值,发现是255,Why?答:因为-1的unsigned值为255。
1.2 初识输入与输出
C++没有定义任何输入输出语句,其IO机制是由标准库提供的。
标准库定义的所有名字都在命名空间std
中。
iostream
库包含istream
和ostream
两个基本类型,分别表示输入流和输出流。
一个流就是一个字符序列,其从IO设备读出或写入设备。
流:随着时间的推移,字符是顺序生成或消耗的。
-
标准输入输出对象
标准库定义了4个IO对象:
1.
cin
:标准输入对象。它是istream
类型的对象。2.
cout
:标准输出对象。它是ostream
的类型的对象。3.
cerr
:标准错误对象。它是ostream
类型的对象。通常用来输出警告和错误信息。4.
clog
:它是ostream
类型的对象。用来输出程序运行时的一般性信息。
<<
为输出运算符,接受两个运算对象:左侧的运算对象必须是一个ostream
的对象,右侧是要打印的值。
以以下语句为例:
std::cout<<"Hello"<<endl;
第一个<<
运算符将“Hello”写到cout
中,其计算结果就是这个cout
。
第一个<<
运算符的结果(cout
这个对象)是第二个<<
运算符的左侧运算对象,其右侧运算符为endl
,即结束当前行。
这样,每个<<
运算符的左侧对象都是相同的,都是cout
。
问题:endl
与\n
的区别是什么?
答:endl
=\n
+flush()
=换行+刷新缓冲区。
>>
为输入运算符,接受一个istream
对象作为其左侧运算对象,接受一个对象作为其右侧运算对象。
以以下语句为例:
std::cin>>v1>>v2
第一个>>
运算符从cin
这个istream
的对象读入数据,并存入v1
中。
同样地,第一个>>
运算符的结果是其左侧运算对象,即cin
。所以cin
又作为第二个>>
运算符的左侧运算对象,读入数据并存入v2
。
所以,每个>>
运算符的左侧对象是相同的,都是这个cin
。
1.3 注释简介
两种注释方法
单行注释:以双斜线(//)开始,以换行符结束。这种注释可以包含任何文本,包括额外的双斜线。常用于半行或单行附注。
注释界定符:以/*
开始,以*/
结束。可以包含除*/
以外的任意内容,包括换行符。常用于多行注释。注释界定符不能嵌套。
1.4 控制流
while语句
while
语句反复执行一段代码,直至给定条件为假为止。
while(condition)
statement
while
语句的执行过程是交替地检测condition条件和执行关联的语句statement,直至condition为假时停止。
for语句
for
语句由循环头和循环体组成。循环头由初始化语句、循环条件、表达式组成。
读取数量不定的输入数
#include<iostream>
int main(){
int sum=0,value=0;
while(std::cin>>value)
sum+=value;
std::cout<<"Sum is:"<<sum<<std::endl;
retun 0;
}
while
的循环条件是std::cin>>value
,因为>>
运算符返回其左侧运算对象,故循环条件检测的其实是std::cin
。
当使用一个istream
的对象作为条件时,其效果是检测流的状态。如果流有效,那么检测成功。当遇到文件结束符时,或遇到一个无效输入时(如读入的值不是一个整数),条件为假。
Linux系统下,文件结束符输入是用Ctrl+D
。
问题
常见的编译错误
语法错误:Syntax error,比如语句结束漏写分号、字符串两侧漏加引号等等。
类型错误:Type error,比如给int类型变量传递字符串。
声明错误:Declaration error,比如标识符名字拼写错误、对来自标准库的名字忘记使用std::等等。
练习1.14:对比for循环和while循环,两种形式的优缺点各是什么?
答:for循环语句简洁;局部变量在循环结束后自动释放,节省内存;适用于循环次数已知的情况。
while循环形式不如for循环简洁,但可以对不确定循环次数的循环进行较好控制。
以下代码中给int型的v3赋值了一个字符类型的值‘t’,并且在后续代码中使用了它,计算
v1+v2+v3
,但是为什么不报错呢?这难道不是类型错误吗?而且我发现在计算v1+v2+v3
时,编译器自动把t转换成了ASCII码值116来参与计算。#include<iostream> int main() { int v1 = 0, v2 = 0; int v3 = 't'; //类型错误 type error std::cin >> v1 >> v2; std::cout << v1 + v2 + v3 << std::endl; return 0; }
if语句
第十六页WARNING中提到赋值运算符(=)和相等运算符(==)都可以出现在条件中。赋值运算符出现在条件中是什么意思?有什么作用?
关于C++的正确格式,我们的信条是,不存在唯一正确的风格,但保持一致性是非常重要的。
1.5 类简介
类(class):用来定义自己的数据结构。一个类定义了一个类型,以及与其关联的一组操作。
如何使用自己的类:使用头文件来访问自己所定义的类,通常使用.h
作为头文件的后缀。
标准库头文件通常不带后缀
关键概念:类定义了行为
一般而言,类的作者决定了类类型对象上可以使用的所有操作。
包含来自标准库的头文件时,用尖括号(< >)包围头文件名。对于不属于标准库的头文件,则用双引号(" ")包围。
如:
#include <iostream> //iostream来自标准库
#include "Sales_item.h" //Sales_item.h为用户自定义的头文件
文件重定向
使用文件重定向功能,将标准输入和标准输出与命名文件关联起来
$ addItem <infile >outfile
$
为系统提示符,addItem
为已经编译的可执行文件,则上述命令会从一个名为infile
的文件读取输入,并将输出结果写入到名为outfile
的文件内,两个文件都位于当前目录中。
类的成员函数有时也被称为方法(method)。通过<stron>(.)来表达类类型的对象的成员函数。通过调用运算符(())来调用一个函数。调用运算符是一对圆括号,里边放置实参列表(可能为空)。如:</stron>
Sales_item item1;
item1.isbn();
术语表
缓冲区(buffer):一个存储区域,用于保存数据。IO设施通常将输入或输出数据保存在一个缓冲区内。默认情况下,读cin
会刷新cout
。程序非正常终止也会刷新cout
。
cerr:一个ostream
对象,默认情况下,写到cerr
的数据是不缓冲的。
clog:一个ostream
对象,默认情况下,写到clog
的数据是被缓冲的。