C语言从零写个校验器(很牛的校验器)

手把手教你写一个校验器
使用场景
其实就相当于一个工具,比如范围校验器:对某范围(x,y)的范围内进行数据校验,比如奇偶校验器 对该数值进行奇偶判断

要求是分层思想,可扩展。代入参数为void *。

代码构思思路(复习用)
第一步:定义结构体变量(包含函数指针,变量)
第二步:书写奇偶校验器,范围校验器(必须要能处理结构体数据)
第三步:#define初始值赋值。
第四步:运行

青铜版
bool rangeCheck(int min, int max, int value)
{
if(value < min || value > max)
return false;
else
return true;
}
1
2
3
4
5
6
7
详解
范围校验器,核心参数为最大值、最小值,比较值。问题来了,对于优秀的程序员来说看到参数这么多不免想要优化的打算,请看黄金版。

运行结果

黄金版
#include “stdio.h”
#include
struct _Range{
const int min;
const int max;
}range = {0,9}; //相比升级版直接赋初值
bool rangeCheck(struct _Range rangeValidator, int value)
{
return (rangeValidator.min <= value) && (value <= rangeValidator.max);
}
int main()
{
bool result = rangeCheck(range, 11);
printf(“result = %d\n”,result);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
改进点
相比于青铜版,黄金版我们这边定义了一个结构体,变量为range,顺便给结构体赋了初值0~9。
但是还是有改进的空间,比如假如代入的参数的结构体,
注意:C语言的参数传址调用要求将参数 的一份拷贝传递给函数,假如结构体成员有128个呢 妈的贼大!!快给我升级!!!!
解决方法:传递结构体的指针!!
改进见钻石版

运行结果

钻石版
#include “stdio.h”
#include

#define newRangeCheck(min,max) {(min),(max)} //初始化引用define

typedef struct _Range{
const int min;
const int max;
}Range;
bool rangeCheck(Range *rangeValidator, int value) //改进版 指针结构体带入
{
return (rangeValidator->min <= value) && (value <= rangeValidator->max);
}
int main()
{
Range range = newRangeCheck(0,9); //初始化程序
bool result = rangeCheck(&range, 11);//改进加&
printf(“result = %d\n”,result);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
改进点
引入typedef:有什么好处呢
typedef struct _Range{
const int min;
const int max;
}Range;

1
2
3
4
5
注意:该结构体有重要的含义1、“结构体布局”,相当于告诉编译器怎么表示数据但是它没有让编译器分配实际的地址

bool rangeCheck(Range *rangeValidator, int value)
1
Range *rangeValidator: 定义了一个数据类型为指向结构体的指针变量Range(注意这个时候代入的地址大小才为4)。
来来来!这时候又来了一个新需求,比如我这边还有加一个奇偶校验器怎么办??

所以我们这边要有一个核心的思想:如何把程序写成通用版本。 哈哈哈,把媳妇介绍给你 “void *”。 请看王者版

王者版
#include “stdio.h”
#include

#define newRangeCheck(min,max) {(min),(max)} //初始化引用define
typedef struct _Range{
const int min;
const int max;
}Range;
typedef struct _OddEven{ //加了奇偶校验器
bool isEven;
}OddEven;
typedef bool(*Validate)(void *pDate,int value); //应该是回调函数 void 变量
bool rangeCheck(void *pthis, int value) //Range rangeValidator 你要改变!!!
{ //void *pthis
Range *pRange = (Range *)pthis; //强制转化 来适应参数void
return (pRange->min <= value) && (value <= pRange->max);
}
bool oddEvenCheck(void *pthis, int value) //范围校验器
{
OddEven *pOddEven = (OddEven *)pthis;
return (!pOddEven->isEven && (value % 2)) || (pOddEven->isEven && !(value % 2));
}
int main()
{
Range range = newRangeCheck(0, 9); //初始化变量参数
Validate ValidateRange = rangeCheck; //把要运行的函数指针给ValidateRange
printf(“result = %d\n”, ValidateRange(&range,3));
ValidateRange = oddEvenCheck;
printf(“result = %d\n”, ValidateRange(&range,5));
return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
改进点
增加了奇偶校验器,核心思想和范围校验器一样。
// An highlighted block
bool oddEvenCheck(void *pthis, int value) //范围校验器
{
OddEven *pOddEven = (OddEven *)pthis;
return (!pOddEven->isEven && (value % 2)) || (pOddEven->isEven && !(value % 2));
}
1
2
3
4
5
6
各种校验器参数变成了 void 输入–还有增加typedef
typedef bool(*const Validate)(void *pDate,int value); //应该是回调函数 void 变量

  • bool rangeCheck(void *pthis, int value) //Range rangeValidator 你要改变!!!
    { //void *pthis
    Range *pRange = (Range *)pthis; //强制转化 来适应参数void
    return (pRange->min <= value) && (value <= pRange->max);
    }
    1
    2
    3
    4
    5
    6
    7
    但你以为这就结束了??? 请看最终版。

运行结果

最终版
#include “stdio.h”
#include

// 初始化数据结构—初值赋值
#define newRangeValidator(min, max) {{validateRange}, (min), (max)}
#define newOddEvenValidator(isEven) {{validateOddEven}, (isEven)}

// 定义了一个函数指针
// 相当于函数类型重定义 bool validateOddEven(void *pThis, int value)
// bool validateRange(void *pThis, int value)
typedef bool(*const Validate)(void *pThis, int value);

//范围校验器–变量
typedef struct{
Validate isa;
const int min;
const int max;
} RangeValidator;
//奇偶校验器 --变量
typedef struct{
Validate isa;
bool isEven;
}OddEvenValidator;

// 数据结构类型处理函数

bool validateRange(void *pThis, int value)
{
RangeValidator *pRangeValidator = (RangeValidator *)pThis;
return pRangeValidator -> min <= value && value <= pRangeValidator -> max;
}
// 数据结构类型处理函数
bool validateOddEven(void *pThis, int value)
{
OddEvenValidator *pOddEvenValidator = (OddEvenValidator *)pThis;
return (!pOddEvenValidator -> isEven && (value % 2)) ||
(pOddEvenValidator -> isEven && !(value % 2));
}

bool rangeCheck(void *pValidator, int value)
{
Validate validate = *((Validate *)pValidator);
return validate(pValidator, value);
}

int main()
{
RangeValidator rangevalidator = newRangeValidator(3,6);// 初始化变量参数
OddEvenValidator oddevenvalidator = newOddEvenValidator(3);
printf(“result = %d\n”, rangeCheck(&rangevalidator,3));
printf(“result = %d\n”, validateOddEven(&oddevenvalidator,3));
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
最终版-编程思想说明
main()函数是怎么运行的

变量说明:RangeValidator rangevalidator = newRangeValidator(3,6);
相当于RangeValidator rangeValidator = {(validateRange), (0), (9) };
说明:该结构变量既有函数指针,还有变量。
如何运行:rangeCheck()函数首先将该结构体指针变为函数指针并将地址赋值给validate
-(**Validate validate = ((Validate )pValidator); )
然后再运行函数return validate(pValidator, value); 因为此时pValidator参数传入的validateRange函数,这是运行该函数。
进入validateRange函数,这个时候强制转化为结构体 OddEvenValidator *pOddEvenValidator = (OddEvenValidator *)pThis;
return (!pOddEvenValidator -> isEven && (value % 2)) ||
(pOddEvenValidator -> isEven && !(value % 2));
然后这边将结果返回。
你有没发现,我这边时候写的rangeCheck()已经不依赖于任何任何具体的校验器的。
牛!

总结
总体老说各个函数围绕 结构体进行操作,每次都是对该地址进行进行强制转化

点赞
1

评论

分享

收藏

手机看

关注
JFinal极速开发企业实战视频教程
01-22
本课程着重深入源码Debug模式讲解JFinal核心架构和运行原理,手把手从零开始带大家开发一个整站,通过本课程的学习可以深入理解WEB开发核心流程,深入理解JFinal核心架构设计原理,熟练使用JFinal开发项目,掌握企业实战技巧
bv1315008634的博客
4060

用C语言实现CRC校验
1、原理假如每次参和CRC计算的信息为一个字节,该信息字节加到16位的累加器中去时,只有累加器的高8位或低8位和信息字节相互作用(异或),相互作用(异或)的结果记为组合值,那么累加器中的新值等于组合值加上(按模2异或)累加器中未改变的那一半即为新的CRC值。组合值只有256种可能,因此可利用硬件模拟算法先算好他们的CRC值预先填入一张表中,该表的每一单元对应相对值的CRC。2、程序…

s扫描器c语言源代码01-10 s扫描器C语言源代码 typedef struct _iphdr { unsigned char h_lenver; //4位首部长度+4位IP版本号 unsigned char tos; //8位服
Ymodem协议C语言实现08-11 XMODEM协议是一种使用拨号调制解调器的个人计算机通信中广泛使用的异步文件运输协议。这种协议以128字节块的形式传输数据,并且每个块都使用一个校验和过程来进行错误检测。
自定义校验器实例 - hhtq的博客 - CSDN博客
11-3

2.注册校验器在src目录下创建validators.xml。注:一旦创建自定义校验器,则系统默认的校验器会失效,必须将系统默认的校验器注册在validators.xml文件中,才会生效。
使用Validator校验器_JDIT的博客-CSDN博客
3-7

【Struts2学习笔记】12:Field-Validator(校验器)的使用 阅读数 573 简述校验器的使用校验器用来在申请Action的方法进行处理前校验用户的提交是否合法,使用它不需要…
4285

CRC校验的快速算法的C语言实现
CRC校验的快速算法的C语言实现 摘要:CRC循环冗余校验算法,是一种在数据存储和数据通讯领域中使用十分广泛的编码算法,具有强力的检错和纠错能力,并且开销比较小。本文从CRC基本原理出发,介绍了CRC快速算法的原理,以C语言为实…
weixin_30709061的博客
224

c语言实现CRC校验和
最近在摄像头采集的数据清晰度上需要加强,则在每一帧传输的数据包后边加了CRC校验和。CRC校验和有16位的,也有32位的。至于CRC校验和算法原理,我是在百度上学习的,其实网上有很多这种资料。简单的说就是CRC校验和就是将一段二进制数据进行加密(乘以一个多项式),然后得到一个校验码。将这个校验码添加在这段二进制数据后边就行了。然后接收方在接收到数据之后,再对这个校验码进行解码。下面我就将今天的…
让代码写的更优雅(一)- java之校验器_pengjunlee的博客-CSDN博客
7-6

一个既简单的校验框架 05-27 主要的技术上使用了注解, 然后通过反射再利用注解解析器来进行解析进行校验 校验器每个方法返回this,可以使用更优雅的代码来完成校验…
内建校验器(1) - weixin_34269583的博客 - CSDN博客
12-26

Struts 2提供了大量的内建校验器,这些内建的校验器可以满足大部分应用的校验需求,开发者只需要使用这些校验器即可。如果应用有一个特别复杂的校验需求,而且该校验有…
烟雨博客
9079

C语言实现密码的设置及验证
#include /定义密码输入函数/void password_set(unsigned int *passwordArrary){ int enter_counter; /定义密码输入计数器/ /for循环实现密码的输入/ printf(“请输入6位数字密码\n”); for (enter_counter = 0; enter_count
qq_41989372的博客
557

CRC校验之查表法C语言实现
本文主要参考:http://www.cnblogs.com/esestt/archive/2007/08/09/848856.html ,实现查表法快速计算CRC7.CRC7应用在SD、MMC的数据校验,生成多项式x^7 + x^3 + 1,生成的校验值为7bit.很容易想到数据以 1byte 为单位进行计算比较方便.C语言代码实现#include #…
关于CCR测评器的自定义校验器(Special Judge) - weixin…_CSDN博客
11-13

在CCR测评器中,SPJ是用一项叫做自定义校验器的功能实现的。CCR的文档没有写明校验器的语法,网上也没有这一类的信息。于是,我在CCR的源代码中找到了CCR的默认…
校验器 - CSDN博客
9-8

写博客发Chat传资源登录注册原 校验器 2016年10月…会显得很麻烦,我们可以封装一个简单的校验器,把每.
weixin_33898876的博客
88

循环冗余校验(CRC)【C语言 位运算】
 【应用场景:数据链路层差错检验】     送数据M,有k位;除数P(对应一个生成多项式),有n位;M右移n-1位的M’;计算M’/P的余数R(帧校验序列FCS);发送帧:M’+FCS 计算余数的二进制除法(异或)第一步:要在数据位(被除数)后边补 0 , 0 的个数比除数(生成多项式)少一位。第二步:做除法(异或操作),从被除数的头五位减去五位的除数。除数…
u012302322的专栏
3155

C语言写的DDOS工具
#include #include #include #include #include #includeusing namespace std;#pragma comment(lib,“ws2_32.lib”)#define PacketNum 1024int MaxThread; //最大线程数量 int CurrentThread = 0; //当前活
几种常见的校验算法_strongerHuang-CSDN博客
7-6

下面就介绍几种常见的校验算法。 一、校验和 校验和是最基本,也是嵌入式工程师…crc16几种标准校验算法及c语言代码一、CRC16校验码的使用现选择最常用的CRC-16…
内建校验器(1) - weixin_34128411的博客 - CSDN博客
12-28

Struts 2提供了大量的内建校验器,这些内建的校验器可以满足大部分应用的校验需求,开发者只需要使用这些校验器即可。如果应用有一个特别复杂的校验需求,而且该校验有…
c语言100题(5)_weixin_30954607的博客-CSDN博客
12-31

趣味100道C语言程序题num one 阅读数 572 每天坚持写几个C语言程序题,会有效提高程序编程能力。今天的例题: 在歌星大赛里,有10个评委打分,分数从1
————————————————
版权声明:本文为CSDN博主「墨客Y」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_38179373/article/details/107492617

你可能感兴趣的:(C语言从零写个校验器(很牛的校验器))