博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[C++]初识
阅读量:517 次
发布时间:2019-03-06

本文共 6017 字,大约阅读时间需要 20 分钟。

说明

关于C++的内容,都是在已经了解了C语言的基础之上总结的,所以有不少C++的基础,因为也是C语言的基础,所以不会特意说明。

输入输出

首先是一个简单的例子:

#include 
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 standard stream   *  objects.  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.exeEnter two numbers:1 2The sum of 1 and 2 is 3F:\Codes\cppprimer>IoStream.exeEnter two numbers:1 2aThe sum of 1 and 2 is 3F:\Codes\cppprimer>IoStream.exeEnter two numbers:a bThe 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.exe1 2 3^ZThe 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.exe1The 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 beforeprivate:    std::string bookNo;      // implicitly initialized to the empty string    unsigned units_sold = 0; // explicitly initialized    double revenue = 0.0;};

几点说明:

  1. 类使用class关键字定义;

  2. >>,<<(这两个在这里指的是输入输出运算符,不是位运算符),<和==这些基本运算符被重载(Override)了,但是因为它们其实不是当前类拥有的接口,所以不能直接放到类里面,需要作friend声明。

  3. public声明类公开的接口,private声明类的私有数据;

  4. 第一个public下是构造函数;

  5. 第二个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 booloperator==(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 booloperator!=(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 ISBNSales_itemoperator+(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}

关于这个问题,目前没有找到答案。似乎可以是成员变量、也可以不是成员变量。

此外还有很多的知识点,比如构造函数、引用等,后面深入的时候再说明。

转载地址:http://akodz.baihongyu.com/

你可能感兴趣的文章