【C++学习之路】第二章——C++基础语法学习(1)之黑客攻击系统
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 "头文件名称"
- 我们先来区分一下**< >与" "**
- 形式一:使用英文状态在的一对儿尖括号(<、>)
#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++ */
- 头文件的名称约定
头文件类型 | 约定 | 实例 | 使用说明 |
---|---|---|---|
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 头文件在项目中的使用方法
我先给出你目前水平的简单使用方法,再给出你专业的方法,专业的方法,我建议你学会了多文件的使用后再来回看。
- 简单的方法
- 先写出必要的头文件,例如iostream和Windows.h,以确保你能够完成最基础的事情,例如下面这样
#include <iostream>
#include <Windows.h>
using namespace std;int main()
{cout << "你好!" << endl;system("pause");return 0;
}
这是基础款,必须要有的头文件。
- 在程序的编辑过程中,如果某些指令需要新的头文件支持,则再将头文件添加到最前面,比如需要string类型,则在最前面加上一个头文件
#include <iostream>
#include <Windows.h>
#include <string> // ② 新添加的
using namespace std;int main()
{cout << "你好!" << endl;string str;// ① 我们需要这条语句,因此加上头文件system("pause");return 0;
}
- 专业的方法
- 根据设计好的架构,建立好多个头文件和源程序文件,每一个源程序文件代表一个功能模块,其中一个是包含main函数的文件
- 然后设计好头文件,注意加上#pragma once
- 每一个源程序文件,都要遵循上面说的简单的方法来添加头文件
- 先设计好模块文件,最后编辑包含main函数的文件,它会调用刚才编辑好的其他模块文件。
对于专业的方法,请掌握多文件之后,再来回看。
【C++学习之路】第二章——C++基础语法学习(1)之黑客攻击系统相关推荐
- D3.js学习指北--第二章,基础复习
D3学习指北–第二章,基础复习 1.关于html的svg标签 html5里有很多个标签,但是关于D3的应用多用在一个标签上< svg >svg标签可以理解为一个绘画板,里面提供了各类的 ...
- Cyclone V SoC FPGA学习之路第二章:硬件篇
Cyclone V SoC FPGA学习之路第二章:硬件篇(内部资源) 前言 上一章了解了<cycloneV device datasheet>,其中数据手册里重点介绍了电源要求,时序参数 ...
- 使用java实现面向对象编程第二章_java面向对象编程——第二章 java基础语法
第二章 java基础语法 1.java关键字 abstract boolean break byte case catch char class const continue default do d ...
- JavaSE入门0基础笔记 第二章Java基础语法
JavaSE入门0基础笔记 第二章Java基础语法 1.运算符 1.1算术运算符 1.1.1运算符和表达式 1.1.2 算术运算符 1.1.3字符的"+"操作 1.1.4 字符串中 ...
- 【python第一章 基础捋顺,第二章 python基础语法】
第一章 基础捋顺,第二章 python基础语法 第一章 基础捋顺 第二章 python基础语法 2.1输入输出 2.2代码注释 2.3代码缩进 2.4命名规范 2.5变量 2.6基本数据类型 2.7数 ...
- 王亟亟的Python学习之路(三)-基础语法以及基本数据类型
转载请注明出处:王亟亟的大牛之路 理论知识虽然很枯燥,但是你以后的高度取决于你基础的厚度 每种语言多多少少都有它的保留关键字 JAVA的: Python的: 那关键字是什么? 电脑语言里事先定义的,有 ...
- Cyclone V SoC FPGA学习之路第一章:综述
Cyclone V SoC FPGA学习之路第一章:总体了解 关键词: adaptive logic modules – ALM 自适应逻辑模块 logic array block --LAB 逻辑阵 ...
- 第2章 Java基础语法
JavaSE_第2章 Java基础语法 学习目标 会使用单行注释和多行注释 能够辨识关键字 理解标识符的含义,正确定义标识符 理解Java中的基本数据类型分类 能够理解常量的概念 能够定义8种基本数据 ...
- 鸟哥的Linux私房菜(基础篇)-第二章、 Linux 如何学习(二.2. 鸟哥的Linux苦难经验全都录)
第二章. Linux 如何学习 最近更新日期:2009/08/06 2. 鸟哥的Linux苦难经验全都录 2.1 鸟哥的Linux学习之路 2.2 学习心态的分别 2.3 X window的学习 鸟哥 ...
最新文章
- 底部居中_4月9日小米9 SE布朗熊发布;小米新专利前置摄像挪屏幕底部
- es文件浏览器鸿蒙,手机文件一团糟 八款安卓文件管理器来救急
- 水平居中布局与滚动条跳动
- C++Exponential search指数搜索的实现算法(附完整源码)
- 0R电阻的12种妙用---摘自:俸禄的小三
- swagger openapi开放平台 pyhton3.7实现http发送请求,pyhon中代码中发送http请求控制4g物联网开关
- 18.2.28阿里前端实习生内推面补坑
- Hadoop学习之hdfs集群搭建详解
- ChinaPub地毯式搜索 - 数据库
- CPLEX:二次规划
- dnspod动态解析linux,NAS折腾记 篇一:五分钟搞定威联通DNSPOD动态域名解析-简单教程+问题解决...
- 什么是UserAgent
- 【建议背诵】2022下半年软考「高项」100题(2)
- UniApp 小程序实现PDF电子签名 拖拽
- windows环境下安装python安装pygame安装
- 小米10s开启录屏方法详细介绍
- Html5-画布(canvas)之常用绘图方法介绍
- MongoDB:PyMongo百万级数据去重
- 阿里架构师,谈对技术架构的理解,以及架构师角色的思考
- 角度距离计算坐标公式
热门文章
- Hexo之部署github
- (转)利用MS AJAX 扩展服务器端控件
- 公司培训文档-JavaScript[对象.属性]集锦
- ruhr启动mysql数据库_Mysql表类型(存储引擎)的选择
- html5 video修改默认样式,HTML5中将video设置为背景的方法
- 服务器怎么禁止iis静态文件,如何禁止IIS缓存静态文件
- Mysql函数访问oracle,Oracle与MySql函数
- native层 安卓_安卓逆向——拼xx协议java层分析
- 安卓app开发工具_怎么开发app软件需要多少钱?主流app开发工具盘点
- mysql 主从复制介绍_MySQL 主从复制介绍