2 C++基础语法学习(1)之黑客攻击系统

遵循原则:从实战中学习知识
法律声明:本系统仅能攻击自己搭建的网站,作为学习使用,不会触犯法律
time:2020.01.20
author:姜海天
IDE:VS C++2010 Express

2.0 VS C++ 2010 Express的使用

2.1 子项目一:功能菜单

2.1.0 本节大纲与知识清单

2.1.0.1 大纲

大纲是最重要的,一定要仔细阅读,不可忽略!

  • 2.1.1~2.1.7是项目设计、实现、测试与优化部分,直接采用了数据结构知识,先不用管这是什么,先接受他的标题与设计过程。
  • 2.1.8及其后面的小节是知识点讲解部分

2.1.0.2 知识清单

本子项目涉及到的知识点如下

  • C++的知识
  • 数据结构的知识

2.1.1 项目需求

设计一个功能菜单,实现黑客攻击系统基本信息的输出
要求的必要信息: 实现网站404攻击,网站篡改攻击,DNS攻击,服务器重启攻击,且记录下来攻击记录

2.1.2 需求分析&整体架构设计

整体架构
设计一个能够输出信息的菜单

2.1.3 ADT模型构建(抽象)

ADT模型1:输出需求中所要求的信息
1. 网站404攻击
2. 网站篡改攻击
3. DNS攻击
4. 服务器重启攻击
5. 查看攻击记录

2.1.4 实现抽象

本项目过于简单,没有这一项

2.1.5 实现

HackerFuncMenu.cpp
#include <iostream>
#include <Windows.h>
using namespace std;int main()
{std::cout << "1. 网站404攻击" << std::endl;std::cout << "2. 网站篡改攻击" << std::endl;std::cout << "3. DNS攻击" << std::endl;cout << "4. 服务器重启攻击" << endl;cout << "5. 查看攻击记录" << endl;system("pause");return 0;
}

对于初学者并不知道我在干什么,没有关系,请先接受这些内容,后面的小节会详细讲解这些内容。

2.1.6 单元测试

这里只有一个ADT模型的实现,并且由于是初学,所以只是借用了软件工程中单元测试的名字,并不是标准的单元测试,只是单纯的验证程序结果的正确性

显然,程序运行结果是正确的,并且是符合要求的。

2.1.7 结果评价与程序优化

2.1.7.1 正确性

显然,程序的结果是正确的

2.1.7.2 效率

对于此程序,效率是不够高的,并且有一些冗杂的没有必要的代码。


思考:什么是高效率的程序?

在计算机工程中,需要综合考量时间复杂度和空间复杂度。
时间复杂度:程序耗时多少
空间复杂度:占用计算机内存多少


2.1.7.3 程序优化

改进后的高效率的程序应该是这样的

#include <iostream>
#include <Windows.h>
using std::cout;
using std::endl;int main()
{cout << "1. 网站404攻击" << endl;cout << "2. 网站篡改攻击" << endl;cout << "3. DNS攻击" << endl;cout << "4. 服务器重启攻击" << endl;cout << "5. 查看攻击记录" << endl;system("pause");return 0;
}

并且,经过单元测试后,没有问题。

不过对于初级的简单的项目来说,我们并不需要过多关注效率问题,而要关注于学习知识,因此,将上述代码中的

using std::cout;
using std::endl;

改为

using namespace std;

好吧到目前位置,你可能根本不知道我在说什么,没有关系,下面的小节中,我将会一点点详细讲给你!

2.1.8 程序的创建过程

本内容适合于初学者,介绍了程序创建的简易过程,内部细节暂时忽略,例如汇编过程等,并没有详细进行解释和展开,只需要了解即可。

2.1.9 头文件

我们先来放上代码,这样你就不需要再去前面翻阅了。

#include <iostream>
#include <Windows.h>
using namespace std;int main()
{cout << "1. 网站404攻击" << endl;cout << "2. 网站篡改攻击" << endl;cout << "3. DNS攻击" << endl;cout << "4. 服务器重启攻击" << endl;cout << "5. 查看攻击记录" << endl;system("pause");return 0;
}

2.1.9.1 头文件的格式

最上面的两行就是头文件

#include <iostream>
#include <Windows.h>

头文件的书写有两种形式

原始形式:
#include <头文件名称>
#include "头文件名称"

  1. 我们先来区分一下**< >" "**
  • 形式一:使用英文状态在的一对儿尖括号(<、>)
#include <iostream>
  • 形式二:使用英文状态下的一对儿双引号("、")
#include "iostream"

思考:两种格式的区别是什么?

看此答案前,我建议你先看完后面讲解头文件的作用以及库文件的小节。

先来一张表格,再详细解释

格式 查找路径 结果 使用
< > 编译器默认目录 找不到相应头文件则编译失败 使用C++标准库
" " 程序当前目录 找不到就去默认目录找,再找不到则编译失败 使用用户自定义头文件

对于使用尖括号< >:代表预处理器在替换头文件部分时候,查找头文件代码的位置是直接从编译器的默认目录查找的。

并且要知道的是,编译器的默认目录,根据编译器、IDE等的不同,它的位置也都是不一样的,我们不需要关心它具体在哪里。

对于使用双引号" ":代表预处理器在替换头文件部分的时候,查找头文件代码的位置,先从当前程序目录下查找,找到了就替换;如果没有找到,则再从编译器默认目录下查找,如果还找不到,则会编译失败。


2.1.9.1.1 查看学习C++标准库代码

VS C++2010 Express中,可以直接看到编译器的默认目录,然后我们可以找到他们看一看。

我们找一下这个路径,这也就是C++标准库了

这里的文件都可以使用VS C++2010打开,我们可以先尝试打开iostream看一下

也许你看不懂这些是什么,没有关系,随着知识的深入,这些内容你会明白的,不过你至少要明白的是,iostream头文件里面也是一堆代码,是的目前来说,明白这些就足够了,在2.1.9.3小节中会用的到这个知识。

补充知识:std命名空间源代码的位置

File: "C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\new.h" 2 occurrences found on 2 lines52: namespace std {75: namespace std {File: "C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\nothrow0.cpp" 1 occurrences found on 1 lines25: namespace std {File: "C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\stddef.h" 1 occurrences found on 1 lines38: namespace std { typedef decltype(__nullptr) nullptr_t; }
File: "C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\yvals.h" 2 occurrences found on 2 lines554:   #define _STD_BEGIN  namespace std {566:    #define _C_STD_BEGIN namespace std { /* only if *.c compiled as C++ */
File: "C:\Program Files\Microsoft Visual Studio 10.0\VC\include\new.h" 2 occurrences found on 2 lines42: namespace std {64: namespace std {File: "C:\Program Files\Microsoft Visual Studio 10.0\VC\include\stddef.h" 1 occurrences found on 1 lines38: namespace std { typedef decltype(__nullptr) nullptr_t; }
File: "C:\Program Files\Microsoft Visual Studio 10.0\VC\include\yvals.h" 2 occurrences found on 2 lines488:   #define _STD_BEGIN  namespace std {500:    #define _C_STD_BEGIN namespace std { /* only if *.c compiled as C++ */
  1. 头文件的名称约定
头文件类型 约定 实例 使用说明
C++旧式风格 扩展名为.h iostream.h C++98标准已经抛弃它
C旧式风格 扩展名为.h math.h C/C++中可以直接使用
C++新式风格 无扩展名 iostream C++中可以使用,需要引入namespace std使用
转换为C++新式风格的C 加上前缀c,无扩展名 cmath C++中可以使用,既可以按照C旧式风格直接使用,也可以引入namespace std使用

备注:此处参考了《C++ Primer Plus》中的表2.1

在C++风格的代码中,我们通常都会使用无扩展名的头文件,例如iostream和cmath,并且C++提倡引入命名空间(后面会解释这个),也就是C++风格的代码应该是这样的:

#include <iostream>    //而不是 iostream.h
#include <cstring>    //而不是 string.h
#include <cmath>  //而不是 math.h
#include <cstdio> //而不是 stdio.h
using namespace std;

值得一提的是,表格中的规则,我建议你掌握C++新风格的使用,至于旧风格,看到的时候能够认识即可

也就是,你只需要掌握这些

头文件类型 约定 实例 使用说明
C++新式风格 无扩展名 iostream C++中在namespace std中使用
转换为C++风格的C 无扩展名,前缀为c cstdio C++中直接使用或者在namespace std中使用

并且能够认识这些

头文件类型 约定 实例 使用说明
C旧式风格 以.h结尾 stdio.h C++中直接使用

不过也有一些特例,例如,Windows.h并没有cWindows这种写法,这涉及到Windows编程,先不用管它,你暂时只需要知道下面这两条即可。

#include <Windows.h>//头文件
system("pause");  //暂停功能,也可以写成cin.get();

顺便说一句,在常用的头文件中,有几个头文件很令人迷惑, 需要重点解释一下,它们是

  • string
  • string.h
  • cstring

其中,string是C++新增的头文件,与后两者一点关系都没有,只是长得像,而string.h与cstring是一类头文件,分别是旧式风格与转换后的风格.

并且还要注意的是,string数据类型,只有在string头文件中才有,C语言是没有这种数据类型的。

下面用一个表格来描述。

头文件类型 头文件名称 能否使用string数据类型
C++新式风格 string 能,并且必须使用std空间
转换为C++后的C cstring 不能,因为C语言没有string类型
C旧式风格 string.h 不能,因为C语言没有string类型

以上说了这么多,是帮助你深入理解头文件的使用规则和头文件名称约定,下面将会给出,我们在编程的时候应该如何使用它们。

这一点非常重要,很多的书籍给出了很多的原理,但是不告诉我们实战的时候应该怎么写,应该用在哪里,最后让人一头雾水,难以快速掌握知识。

写法一
#include <iostream>
#include <Windows.h>
#include <string>
#include <cstdio>
using namespace std;int main()
{cout << "你好!" << endl;printf("你好!\n");string a; //后面会解释它的含义system("pause");return 0;
}
写法二
#include <iostream>
#include <Windows.h>
#include <string>
#include <cstdio>
using std::cout;
using std::endl;
using std::string;
using std::printf;int main()
{cout << "你好!" << endl;printf("你好!\n");string a; //后面会解释它的含义system("pause");return 0;
}
写法三
#include <iostream>
#include <Windows.h>
#include <string>
#include <cstdio>int main()
{std::cout << "你好!" << std::endl;std::printf("你好!\n");printf("你好!\n");//这个不加std也可以std::string a; //后面会解释它的含义system("pause");return 0;
}

好的目前你已经知道这些写法了,但是还会有疑惑,就是,头文件有啥什么用?namespace std是什么?后面的小节会讲解,请先接受这些内容,学习了后面的章节(头文件的作用和命名空间的使用)后,再回看以上内容。


思考:这几种写法的区别是什么?

我建议你看懂上面讲述的内容后,再看思考此问题。

我先抽象出三种写法核心内容,再为你逐步拆解讲解,请注意,下面的代码只是一部分,不是完整的程序。

  • 形式1:
#include <iostream>
using namespace std;
cout << "你好!" << endl;
  • 形式2:
#include <iostream>
using std::cout;
cout << "你好!" << std::endl;
  • 形式3
#include <iostream>
std::cout << "你好!" << std::endl;

对于形式1,使用了完整的命名空间std,这样后面的程序就可以直接使用std中的任意内容,而不需要加上 std:: 前缀。

但是如果你在接下来的代码中,只是使用了cout命令,并且使用了例如100个之多,显然没有必要使用全部的命名空间,这很浪费,因此,可以使用形式2中的形式,单独使用命名空间中的某一项指令。

如果你只使用了一个cout命令,形式2也是浪费的,因此可以使用形式3

用一张表格来概括一下:

头文件 命名空间使用情况 应用举例 适用场景 使用建议
iostream using namespace std; cout、endl 不关注效率时(初学者)、大量使用std空间内容时 不建议
iostream using std::cout cout、std::endl 大量使用cout,但很少使用endl时 建议
iostream 不使用 std::cout、std::endl cout和endl使用都很少时 建议

说明一下,我们后续会详细讲解命名空间,之所以不建议使用第一种,是为了防止引发不必要的重名冲突,先了解一下即可,后续会深入讲解。
附上一个拓展学习链接:std命名空间


2.1.9.2 头文件的作用

关于头文件的格式,大家应该很清楚了,不过应该也有一些不太清楚的地方,下面我来讲解头文件的作用,然后,请你回看上一小节,并结合本节内容,重新进行理解。

如下程序是正确的,能够编译成功

#include <iostream>int main()
{std::cout << "你好!" << std::endl;return 0;
}

而如下程序,缺少了头文件,不能编译成功

int main()
{std::cout << "你好!" << std::endl;return 0;
}

启动VS C++2010编译后,会报错

此时,我们称编译器不能识别cout和endl,不能识别的原因:

  • 直接原因:没有添加iostream头文件
  • 根本原因:编译器不能识别cout和endl指令

思考:为什么加上头文件,编译器就能够识别这两个指令了?

很明显,就是因为加上了头文件iostream。


因此,头文件的作用,就是帮助编译器识别相应的指令。

但是这样描述并不专业,从专业的角度来说,头文件iostream本身能够实现cout指令,在程序编译过程中,预处理器将iostream文件包含了进来,因此程序可以使用cout,请看下一小节后,再来回看这一段内容,这样你就能够理解了。

2.1.9.3 头文件的预处理过程

对于程序员写好的代码,执行编译之后,会在编译过程进行之前,编译器会调用预处理器,进行预处理过程,请看下面的流程图。

执行编译
头文件部分被替换为头文件代码
源代码
编译器调用预处理器
执行编译过程

也就是说,预处理器将下面这段内容

#include <iostream>

替换为了iostream文件中的代码,也就是这些:

这时候,我们称预处理器将头文件内容包含进了该程序中。

还记得2.1.9.1.1小节学到的内容吗,如果忘记了请你回看一下,然后再来理解这一小节。

不过请注意,这种替换并不改变源代码文件,是一种隐性替换,不是真正的替换掉了,这种说法只是为了方便你理解这件事。

当然,你也不妨理解为添加头文件,就相当于添加了头文件中的代码,头文件只是一个“代号”。因此,该源程序文件能够使用头文件中的功能

2.1.9.4 头文件的使用

不管是单文件还是多文件,头文件一定要加在最前面,因为编译的顺序以及程序的执行顺序都是自上而下的,如果写成下面这样

std::cout << "你好!";
#include <iostream>

这样的程序是不能执行的,一般情况下都是后面的内容可以调用前面的内容(不是绝对的,学到后面你会明白),因此来说:头文件一定要写在最前面,不过后面学习到多文件的时候,你会遇到这样的命令

#pragma once

我先告诉你这代表该文件只能被编译一次,头文件需要在它的下面写。

2.1.9.5 头文件在项目中的使用方法

我先给出你目前水平的简单使用方法,再给出你专业的方法,专业的方法,我建议你学会了多文件的使用后再来回看。

  • 简单的方法
  1. 先写出必要的头文件,例如iostream和Windows.h,以确保你能够完成最基础的事情,例如下面这样
#include <iostream>
#include <Windows.h>
using namespace std;int main()
{cout << "你好!" << endl;system("pause");return 0;
}

这是基础款,必须要有的头文件。

  1. 在程序的编辑过程中,如果某些指令需要新的头文件支持,则再将头文件添加到最前面,比如需要string类型,则在最前面加上一个头文件
#include <iostream>
#include <Windows.h>
#include <string> // ② 新添加的
using namespace std;int main()
{cout << "你好!" << endl;string str;// ① 我们需要这条语句,因此加上头文件system("pause");return 0;
}
  • 专业的方法

    1. 根据设计好的架构,建立好多个头文件和源程序文件,每一个源程序文件代表一个功能模块,其中一个是包含main函数的文件
    2. 然后设计好头文件,注意加上#pragma once
    3. 每一个源程序文件,都要遵循上面说的简单的方法来添加头文件
    4. 先设计好模块文件,最后编辑包含main函数的文件,它会调用刚才编辑好的其他模块文件。

对于专业的方法,请掌握多文件之后,再来回看。

【C++学习之路】第二章——C++基础语法学习(1)之黑客攻击系统相关推荐

  1. D3.js学习指北--第二章,基础复习

    D3学习指北–第二章,基础复习 1.关于html的svg标签   html5里有很多个标签,但是关于D3的应用多用在一个标签上< svg >svg标签可以理解为一个绘画板,里面提供了各类的 ...

  2. Cyclone V SoC FPGA学习之路第二章:硬件篇

    Cyclone V SoC FPGA学习之路第二章:硬件篇(内部资源) 前言 上一章了解了<cycloneV device datasheet>,其中数据手册里重点介绍了电源要求,时序参数 ...

  3. 使用java实现面向对象编程第二章_java面向对象编程——第二章 java基础语法

    第二章 java基础语法 1.java关键字 abstract boolean break byte case catch char class const continue default do d ...

  4. JavaSE入门0基础笔记 第二章Java基础语法

    JavaSE入门0基础笔记 第二章Java基础语法 1.运算符 1.1算术运算符 1.1.1运算符和表达式 1.1.2 算术运算符 1.1.3字符的"+"操作 1.1.4 字符串中 ...

  5. 【python第一章 基础捋顺,第二章 python基础语法】

    第一章 基础捋顺,第二章 python基础语法 第一章 基础捋顺 第二章 python基础语法 2.1输入输出 2.2代码注释 2.3代码缩进 2.4命名规范 2.5变量 2.6基本数据类型 2.7数 ...

  6. 王亟亟的Python学习之路(三)-基础语法以及基本数据类型

    转载请注明出处:王亟亟的大牛之路 理论知识虽然很枯燥,但是你以后的高度取决于你基础的厚度 每种语言多多少少都有它的保留关键字 JAVA的: Python的: 那关键字是什么? 电脑语言里事先定义的,有 ...

  7. Cyclone V SoC FPGA学习之路第一章:综述

    Cyclone V SoC FPGA学习之路第一章:总体了解 关键词: adaptive logic modules – ALM 自适应逻辑模块 logic array block --LAB 逻辑阵 ...

  8. 第2章 Java基础语法

    JavaSE_第2章 Java基础语法 学习目标 会使用单行注释和多行注释 能够辨识关键字 理解标识符的含义,正确定义标识符 理解Java中的基本数据类型分类 能够理解常量的概念 能够定义8种基本数据 ...

  9. 鸟哥的Linux私房菜(基础篇)-第二章、 Linux 如何学习(二.2. 鸟哥的Linux苦难经验全都录)

    第二章. Linux 如何学习 最近更新日期:2009/08/06 2. 鸟哥的Linux苦难经验全都录 2.1 鸟哥的Linux学习之路 2.2 学习心态的分别 2.3 X window的学习 鸟哥 ...

最新文章

  1. 底部居中_4月9日小米9 SE布朗熊发布;小米新专利前置摄像挪屏幕底部
  2. es文件浏览器鸿蒙,手机文件一团糟 八款安卓文件管理器来救急
  3. 水平居中布局与滚动条跳动
  4. C++Exponential search指数搜索的实现算法(附完整源码)
  5. 0R电阻的12种妙用---摘自:俸禄的小三
  6. swagger openapi开放平台 pyhton3.7实现http发送请求,pyhon中代码中发送http请求控制4g物联网开关
  7. 18.2.28阿里前端实习生内推面补坑
  8. Hadoop学习之hdfs集群搭建详解
  9. ChinaPub地毯式搜索 - 数据库
  10. CPLEX:二次规划
  11. dnspod动态解析linux,NAS折腾记 篇一:五分钟搞定威联通DNSPOD动态域名解析-简单教程+问题解决...
  12. 什么是UserAgent
  13. 【建议背诵】2022下半年软考「高项」100题(2)
  14. UniApp 小程序实现PDF电子签名 拖拽
  15. windows环境下安装python安装pygame安装
  16. 小米10s开启录屏方法详细介绍
  17. Html5-画布(canvas)之常用绘图方法介绍
  18. MongoDB:PyMongo百万级数据去重
  19. 阿里架构师,谈对技术架构的理解,以及架构师角色的思考
  20. 角度距离计算坐标公式

热门文章

  1. Hexo之部署github
  2. (转)利用MS AJAX 扩展服务器端控件
  3. 公司培训文档-JavaScript[对象.属性]集锦
  4. ruhr启动mysql数据库_Mysql表类型(存储引擎)的选择
  5. html5 video修改默认样式,HTML5中将video设置为背景的方法
  6. 服务器怎么禁止iis静态文件,如何禁止IIS缓存静态文件
  7. Mysql函数访问oracle,Oracle与MySql函数
  8. native层 安卓_安卓逆向——拼xx协议java层分析
  9. 安卓app开发工具_怎么开发app软件需要多少钱?主流app开发工具盘点
  10. mysql 主从复制介绍_MySQL 主从复制介绍