技术宅程序猿大本营c++

C++代码训练营 | 鸟枪终于换炮了

2016-11-10  本文已影响1724人  天花板

之前的C语言学习系列中,我们仔细讲解了C语言的一些基础知识。之后又写了21天C语言代码训练营系列,大家反馈很有收获。

从今天起,我们开始学习C++编程。C++的知识点并不比C语言少,如果从零开始讲解有些困难。幸好我的理念一直是通过具体的项目教大家学习编程。让我们跟着项目走,相信你一定能够迅速掌握最实用的C++技巧。

希望大家在初步学习C++之后再来学习这个系列,一定会让你爱上C++编程。


C++的价值

各种程序设计语言

在这里我们用最简单的方式阐述一下究竟为什么C++比C语言高级。从功能的角度讲,用C++写的程序C语言也能够实现。那么C++究竟高级在哪儿呢?它就高级在引入了更加人性化的编程方式。

人们常说C是面向过程的语言,而C++在此基础上引入了面向对象和泛型两种全新的编程方式。而这两种新的编程方式更加接近我们现实中解决问题的思想,因此C++更好用一些。

编程语言高下之争一直是业内一个主要争论话题,多年以来从未停止。随着各种新语言的诞生,参加争论的派系也越来越多。

其实,我们大可不必纠结于语言,所有的语言都是为程序员服务的,解决现实中的问题才是我们最终的目的。所以,语言没有高下之分,只不过是使用语言的人参差不齐而已。

在我们学习C++时,千万不要把它和C语言分割开来,我们要把C++想象成为C语言的一个扩展,所有C语言的东西在这里都能继续使用。

创建C++项目

我们用Visual Studio来创建一个标准的控制台程序工程。创建过程请参考。与C语言项目的唯一区别是新建文件时要以cpp为后缀名。

第一段C++代码

我们在新创建的main.cpp文件中加入下面这段C++代码:

// main.cpp
#include <iostream>

using namespace std;

int main()
{
    string str = "Hello World!";
    cout << str.c_str() << endl;
    
    return 0;
}

这是一个最基本的标准的C++源代码,在屏幕上打印“Hello World!”语句。大体上看和C语言的区别不大。我们来看看几个细节上的不同。

1. 头文件

C++的标准输入输出库不再是stdio.h,而是iostream。需要注意的是这里用的是<>而不是“”。原因我们在C语言教程中讲过了。值得注意的是,C++的标准库引用不需要加后缀名。

2. 命名空间

using namespace std;

这句话看着比较陌生。

C++中引入了命名空间的概念,std就是一个常用的命名空间。有了这行代码,后面的string和cout关键字才能正确被引用。如果没有这句话,我们在使用是需要这样写。

    std::string str = "Hello World!";
    std::cout << str.c_str() << std::endl;

“::”这个符号叫做域运算符,能够帮助我们引用某个命名空间下的任意关键字。

3. string类

C++一个非常大的进步是拥有了string类(字符串类),它能帮助我们处理最常用的字符串数据类型。

在《21天C语言代码训练营》中,我们通过C语言自己实现了一个string类型来管理字符串,如今这个工作C++标准库已经帮我们做好了。

4. 标准输入输出

在C++中,我们用cout和cin进行标准输入输出。它们代替了printf和scanf。具体的用法我们会在使用中慢慢了解。

Visual Studio代码调试

Visual Studio

下面我们来运行一下前面这段代码。

1. 快捷键F6

这个快捷键的作用是编译项目中的全部代码。如果要看看有没有语法错误,就直接按这个键。

PS:如果在安装过程中,VS发现这个快捷键有冲突,也许会自动调整成别的键。在BUILD菜单中能够查看到这个快捷键。

2. 快捷键F5

调试运行代码。如果源代码没有编译,它会先进行编译之后运行。执行过程中,遇到断点会停下来。

3. 快捷键F9

增加或删除断点,方便调试。不要问我什么是断点,在C语言学习中你就该知道的。

4. 快捷键F10,F11

这两个快捷键负责单步调试,就是按一下执行一句话。前者遇到函数调用一次执行完,后者遇到函数调用会进入函数内部单步执行。

在调试代码时,这两个键非常有用。

5. 快捷键Ctrl + F5

忽略断点执行。就是不在断点处停下直接执行结束。

现在,我们在VS中使用“Ctrl+F5”运行我们刚才的代码。看到了下面的窗口。

实现第一个C++类

在《21天C语言代码训练营》中,很多人都说我们自己实现的string功能非常好用。下面是之前的头文件:

#ifndef STRING_H_INCLUDED
#define STRING_H_INCLUDED

#define BUF_SIZE 100

typedef struct _tagString
{
    char buf[BUF_SIZE];
    int len;
}String;

void StringInit(String* pStr);
void StringSet(String* pStr, char* pBuf);
char* StringGetBuffer(String* pStr);
void StringAppend(String* pStr, char* pBuf);

#endif // STRING_H_INCLUDED

今天,我们用C++的类来封装这一组功能。功能的实现也不用之前的代码了,我们用C++自己的string来完成。

1. 头文件

新建String.h文件,加入下面代码。

#ifndef STRING_H_INCLUDED
#define STRING_H_INCLUDED

#include <iostream>

using namespace std;

class String
{
public:
    String(){}
    ~String(){}

    void Init(char* pStr);
    void Init(String str);
    const char* GetBuffer();
    void Append(char* pBuf);

private:
    string m_str;
};

#endif // STRING_H_INCLUDED

这个头文件中,全部的功能代码都变成了String类的成员函数,这样,我们就可以用每一个String类的对象管理一个相应的字符串了。

这里需要注意,成员函数的函数名不再需要加上类名作为前缀了。也就是说不用再出现SringInit,StringAppend这样的函数名称了。

2. 源码文件

接下来我们实现String类的成员函数。创建String.cpp文件,代码如下:

#include "String.h"

void String::Init(char* pStr)
{
    m_str = pStr;
}

void String::Init(String str)
{
    m_str = (char*)str.GetBuffer();
}

const char* String::GetBuffer()
{
    return m_str.c_str();
}

void String::Append(char* pBuf)
{
    m_str.append(pBuf);
}

字符串实际上是保存在String的私有成员变量m_str中的,因此所有的功能其实是调用std::string给我们提供的API。

接下来我们写一段程序来测试一下我们的第一个C++类。在main.cpp中加入下面代码。

#include <iostream>

#include "String.h"

int main()
{
    char a[] = "ABCDE";
    char b[] = "FGHIJ";

    String str;

    str.Init(a);

    cout << str.GetBuffer() << endl;

    str.Append(b);

    cout << str.GetBuffer() << endl;

    String str1;
    str1.Init(str);

    cout << str1.GetBuffer() << endl;
    
    return 0;
} 

按Ctrl + F5看看结果吧。

其实,我们自己实现这个String类从功能角度来说意义不大,因为C++已经为我们提供了功能更强大的string类,但通过这段代码,我们能够清楚地看到在引入了类之后,C++的代码能够得到更好的封装,这对我们后面开发C++程序至关重要。

我是天花板,让我们一起在软件开发中自我迭代。
如有任何问题,欢迎与我联系。


下一篇:C++代码训练营 | 经典绘图工具EasyX

上一篇下一篇

猜你喜欢

热点阅读