[C++]初识
Posted jiangwei0512
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[C++]初识相关的知识,希望对你有一定的参考价值。
说明
关于C++的内容,都是在已经了解了C语言的基础之上总结的,所以有不少C++的基础,因为也是C语言的基础,所以不会特意说明。
输入输出
首先是一个简单的例子:
#include <iostream>
int main()
{
int v1 = 0, v2 = 0;
std::cout << "Enter two numbers:" << std::endl;
std::cin >> v1 >> v2;
std::cout << "The sum of " << v1 << " and " << v2 << " is " << v1 + v2 << std::endl;
return 0;
}
cout是标准输出,cin是标准输入,此外还有cerr是标准错误,clog是标准日志记录,对应的头文件:
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @name Standard Stream Objects
*
* The <iostream> header declares the eight <em>standard stream
* objects</em>. For other declarations, see
* http://gcc.gnu.org/onlinedocs/libstdc++/manual/io.html
* and the @link iosfwd I/O forward declarations @endlink
*
* They are required by default to cooperate with the global C
* library's @c FILE streams, and to be available during program
* startup and termination. For more information, see the section of the
* manual linked to above.
*/
//@{
extern istream cin; /// Linked to standard input
extern ostream cout; /// Linked to standard output
extern ostream cerr; /// Linked to standard error (unbuffered)
extern ostream clog; /// Linked to standard error (buffered)
#ifdef _GLIBCXX_USE_WCHAR_T
extern wistream wcin; /// Linked to standard input
extern wostream wcout; /// Linked to standard output
extern wostream wcerr; /// Linked to standard error (unbuffered)
extern wostream wclog; /// Linked to standard error (buffered)
#endif
//@}
// For construction of filebuffers for cout, cin, cerr, clog et. al.
static ios_base::Init __ioinit;
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
可以看到在cout、cin之前加了std,它是命名空间的名称,使用它是为了防止全局命名的冲突,这样写当然比较麻烦,如果一直使用的都是std这个命名空间,就可以直接在开头导入:
using namespace std;
还有一个endl,它是一个操纵符,写入endl的效果是结束当前行,并将与设备关联的缓冲区中的内容刷写到设备中,而不是仅停留在内存。
<<和>>是输出运算符和输入运算符。<<接收两个运算对象,左边是ostream对象,右边是需要输出的值。<<运算符的返回值是左边的ostream对象,这样才可以像代码中那样连续多次使用<<。>>也类似,接收两个对象,左侧是istream对象,右侧是一个普通对象来接收读入的数据,并返回左侧的istream对象。
代码执行的结果:
F:\\Codes\\cppprimer>IoStream.exe
Enter two numbers:
1 2
The sum of 1 and 2 is 3
F:\\Codes\\cppprimer>IoStream.exe
Enter two numbers:
1 2a
The sum of 1 and 2 is 3
F:\\Codes\\cppprimer>IoStream.exe
Enter two numbers:
a b
The sum of 0 and 0 is 0
从上面的程序中其实是可以看到一些可疑的点的,这个涉及更复杂的内容,将在后续进一步介绍。
控制流
这里只介绍与C语言有差异的。
首先是for:
int main()
{
for (int i = 0; i < 10; i++)
{
cout << i << endl;
}
return 0;
}
主要的区别在于i这个变量,C++中可以直接放到for循环语句中;C语言中其实也可以这么用,但是似乎有版本限制,且一般也不这么用。这里还需要注意i只在for循环对应的代码块中才有效,在其外是无效的。
其次是结合输入的控制流:
int main()
{
int sum = 0;
int value;
while (cin >> value)
{
sum += value;
}
cout << "The sum is: " << sum << endl;
return 0;
}
执行结果:
F:\\Codes\\cppprimer>Control.exe
1 2 3
^Z
The sum is: 6
这里的while循环会一直持续,直到按下Ctrl+z再加Enter为止,这表示了输入的结束,然后执行后续的打印结果。这里是while的例子,cin也可以用在if中:
int main()
{
int value;
if (cin >> value)
{
cout << "The input: " << value << endl;
}
return 0;
}
这里只获取第一个输入,然后打印值,结果如下:
F:\\Codes\\cppprimer>Control.exe
1
The input: 1
C语言当也可以通过scanf完成类似的写法
类简介
类用来定义自己的数据结构及关联的操作。下面是一个例子:
class Sales_item {
// these declarations are explained section 7.2.1, p. 270
// and in chapter 14, pages 557, 558, 561
friend std::istream& operator>>(std::istream&, Sales_item&);
friend std::ostream& operator<<(std::ostream&, const Sales_item&);
friend bool operator<(const Sales_item&, const Sales_item&);
friend bool operator==(const Sales_item&, const Sales_item&);
public:
// constructors are explained in section 7.1.4, pages 262 - 265
// default constructor needed to initialize members of built-in type
Sales_item() = default;
Sales_item(const std::string &book): bookNo(book) { }
Sales_item(std::istream &is) { is >> *this; }
public:
// operations on Sales_item objects
// member binary operator: left-hand operand bound to implicit this pointer
Sales_item& operator+=(const Sales_item&);
// operations on Sales_item objects
std::string isbn() const { return bookNo; }
double avg_price() const;
// private members as before
private:
std::string bookNo; // implicitly initialized to the empty string
unsigned units_sold = 0; // explicitly initialized
double revenue = 0.0;
};
几点说明:
-
类使用class关键字定义;
-
>>,<<(这两个在这里指的是输入输出运算符,不是位运算符),<和==这些基本运算符被重载(Override)了,但是因为它们其实不是当前类拥有的接口,所以不能直接放到类里面,需要作friend声明。
-
public声明类公开的接口,private声明类的私有数据;
-
第一个public下是构造函数;
-
第二个public下是普通的公开接口;
这里有几个问题需要解决。
一是为什么需要将==等运算符Override?原因很简单,因为对于Sales_item这个自定义的数据类型,两个类对象是无法比较的,如下面的代码:
int main()
{
Sales_item item1, item2;
if (item1 == item2)
std::cout << "==" << std::endl;
else
std::cout << "!=" << std::endl;
return 0;
}
编译时直接报错:
F:\\Codes\\cppprimer\\1\\add_item.cc: In function 'int main()':
F:\\Codes\\cppprimer\\1\\add_item.cc:37:15: error: no match for 'operator==' (operand types are 'Sales_item' and 'Sales_item')
if (item1 == item2)
可以看到直接提示没有匹配的operator==。
二是Override的时候为什么还要将operator==设置为友元,这主要就得看它的实现:
inline bool
operator==(const Sales_item &lhs, const Sales_item &rhs)
{
// must be made a friend of Sales_item
return lhs.units_sold == rhs.units_sold &&
lhs.revenue == rhs.revenue &&
lhs.isbn() == rhs.isbn();
}
从代码可以看到,只有当Sales_item中的units_sold、revenue和isbn()函数的返回值都相等,才表示两个Sales_item对象相等。但是问题在于units_sold和revenue是私有变量,operator==是不能直接访问的。为了访问能够成功,在定义Sales_item的时候就需要显式地声明operator==为友元。这也是为什么operator!=不需要声明为友元的缘故,如下所示:
inline bool
operator!=(const Sales_item &lhs, const Sales_item &rhs)
{
return !(lhs == rhs); // != defined in terms of operator==
}
在operator!=的实现中不需要访问Sales_item的私有数据,也就不需要声明为友元了。
三是为什么operator+=却被定义成了Sales_item的公共接口,还有一个operator+放在了Sales_item定义之外:
// nonmember binary operator: must declare a parameter for each operand
// assumes that both objects refer to the same ISBN
Sales_item
operator+(const Sales_item& lhs, const Sales_item& rhs)
{
Sales_item ret(lhs); // copy (|lhs|) into a local object that we'll return
ret += rhs; // add in the contents of (|rhs|)
return ret; // return (|ret|) by value
}
关于这个问题,目前没有找到答案。似乎可以是成员变量、也可以不是成员变量。
此外还有很多的知识点,比如构造函数、引用等,后面深入的时候再说明。
以上是关于[C++]初识的主要内容,如果未能解决你的问题,请参考以下文章