回调函数是什么
回调函数 程序员常常需要实现回调。本文将讨论函数指针的基本原则并说明如何使用函数指针实现回调。注意这里针对的是普通的函数,不包括完全依赖于不同语法和语义规则的类成员函数(类成员指针将在另文中讨论)。声明函数指针 回调函数是一个程序员不能显式调用的函数;通过将回调函数的地址传给调用者从而实现调用。要实现回调,必须首先定义函数指针。尽管定义的语法有点不可思议,但如果你熟悉函数声明的一般方法,便会发现函数指针的声明与函数声明非常类似。请看下面的例子:void f();// 函数原型上面的语句声明了一个函数,没有输入参数并返回void。那么函数指针的声明方法如下:void (*) (); 让我们来分析一下,左边圆括弧中的星号是函数指针声明的关键。另外两个元素是函数的返回类型(void)和由边圆括弧中的入口参数(本例中参数是空)。注意本例中还没有创建指针变量-只是声明了变量类型。目前可以用这个变量类型来创建类型定义名及用sizeof表达式获得函数指针的大小:// 获得函数指针的大小unsigned psize = sizeof (void (*) ()); // 为函数指针声明类型定义typedef void (*pfv) ();pfv是一个函数指针,它指向的函数没有输入参数,返回类行为void。使用这个类型定义名可以隐藏复杂的函数指针语法。指针变量应该有一个变量名:void (*p) (); //p是指向某函数的指针 p是指向某函数的指针,该函数无输入参数,返回值的类型为void。左边圆括弧里星号后的就是指针变量名。有了指针变量便可以赋值,值的内容是署名匹配的函数名和返回类型。例如:void func() {/* do something */} p = func; p的赋值可以不同,但一定要是函数的地址,并且署名和返回类型相同。传递回调函数的地址给调用者 现在可以将p传递给另一个函数(调用者)- caller(),它将调用p指向的函数,而此函数名是未知的:void caller(void(*ptr)()){ptr(); /* 调用ptr指向的函数 */ }void func();int main(){p = func; caller(p); /* 传递函数地址到调用者 */} 如果赋了不同的值给p(不同函数地址),那么调用者将调用不同地址的函数。赋值可以发生在运行时,这样使你能实现动态绑定。调用规范 到目前为止,我们只讨论了函数指针及回调而没有去注意ANSI C/C++的编译器规范。许多编译器有几种调用规范。如在Visual C++中,可以在函数类型前加_cdecl,_stdcall或者_pascal来表示其调用规范(默认为_cdecl)。C++ Builder也支持_fastcall调用规范。调用规范影响编译器产生的给定函数名,参数传递的顺序(从右到左或从左到右),堆栈清理责任(调用者或者被调用者)以及参数传递机制(堆栈,CPU寄存器等)。 将调用规范看成是函数类型的一部分是很重要的;不能用不兼容的调用规范将地址赋值给函数指针。例如:// 被调用函数是以int为参数,以int为返回值__stdcall int callee(int); // 调用函数以函数指针为参数void caller( __cdecl int(*ptr)(int)); // 在p中企图存储被调用函数地址的非法操作__cdecl int(*p)(int) = callee; // 出错指针p和callee()的类型不兼容,因为它们有不同的调用规范。因此不能将被调用者的地址赋值给指针p,尽管两者有相同的返回值和参数列。
VS2013中c语言md5加密函数怎么调用
1、主要就是调用库函数,MD5加密说到底也是函数计算,没有什么思路的问题,了解md5的发明算法,本质是一个数学问题。
2、例程:
#ifndef MD5_H#define MD5_H typedef struct{ unsigned int count; unsigned int state; unsigned char buffer; }MD5_CTX;#define F(x,y,z) ((x & y) | (~x & z))#define G(x,y,z) ((x & z) | (y & ~z))#define H(x,y,z) (x^y^z)#define I(x,y,z) (y ^ (x | ~z))#define ROTATE_LEFT(x,n) ((x 《《 n) | (x 》》 (32-n)))#define FF(a,b,c,d,x,s,ac) \ { \ a += F(b,c,d) + x + ac; \ a = ROTATE_LEFT(a,s); \ a += b; \ }#define GG(a,b,c,d,x,s,ac) \ { \ a += G(b,c,d) + x + ac; \ a = ROTATE_LEFT(a,s); \ a += b; \ }#define HH(a,b,c,d,x,s,ac) \ { \ a += H(b,c,d) + x + ac; \ a = ROTATE_LEFT(a,s); \ a += b; \ }#define II(a,b,c,d,x,s,ac) \ { \ a += I(b,c,d) + x + ac; \ a = ROTATE_LEFT(a,s); \ a += b; \ } void MD5Init(MD5_CTX *context);void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen);void MD5Final(MD5_CTX *context,unsigned char digest);void MD5Transform(unsigned int state,unsigned char block);void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len);void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len); #endif源文件md5.c#include 《memory.h》#include “md5.h“ unsigned char PADDING={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; void MD5Init(MD5_CTX *context){ context-》count = 0; context-》count = 0; context-》state = 0x67452301; context-》state = 0xEFCDAB89; context-》state = 0x98BADCFE; context-》state = 0x10325476;}void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen){ unsigned int i = 0,index = 0,partlen = 0; index = (context-》count 》》 3) & 0x3F; partlen = 64 - index; context-》count += inputlen 《《 3; if(context-》count 《 (inputlen 《《 3)) context-》count++; context-》count += inputlen 》》 29; if(inputlen 》= partlen) { memcpy(&context-》buffer[index],input,partlen); MD5Transform(context-》state,context-》buffer); for(i = partlen;i+64 《= inputlen;i+=64) MD5Transform(context-》state,&input[i]); index = 0; } else { i = 0; } memcpy(&context-》buffer[index],&input[i],inputlen-i);}void MD5Final(MD5_CTX *context,unsigned char digest){ unsigned int index = 0,padlen = 0; unsigned char bits; index = (context-》count 》》 3) & 0x3F; padlen = (index 《 56)?(56-index):(120-index); MD5Encode(bits,context-》count,8); MD5Update(context,PADDING,padlen); MD5Update(context,bits,8); MD5Encode(digest,context-》state,16);}void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len){ unsigned int i = 0,j = 0; while(j 《 len) { output[j] = input[i] & 0xFF; output[j+1] = (input[i] 》》 8) & 0xFF; output[j+2] = (input[i] 》》 16) & 0xFF; output[j+3] = (input[i] 》》 24) & 0xFF; i++; j+=4; }}void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len){ unsigned int i = 0,j = 0; while(j 《 len) { output[i] = (input[j]) | (input[j+1] 《《 8) | (input[j+2] 《《 16) | (input[j+3] 《《 24); i++; j+=4; }}void MD5Transform(unsigned int state,unsigned char block){ unsigned int a = state; unsigned int b = state; unsigned int c = state; unsigned int d = state; unsigned int x; MD5Decode(x,block,64); FF(a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */ FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */ FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */ FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */ FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */ FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */ FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */ FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */ FF(a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */ FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */ FF(c, d, a, b, x, 17, 0xffff5bb1); /* 11 */ FF(b, c, d, a, x, 22, 0x895cd7be); /* 12 */ FF(a, b, c, d, x, 7, 0x6b901122); /* 13 */ FF(d, a, b, c, x, 12, 0xfd987193); /* 14 */ FF(c, d, a, b, x, 17, 0xa679438e); /* 15 */ FF(b, c, d, a, x, 22, 0x49b40821); /* 16 */
一个指数函数的积分
连续函数的原函数不一定能用初等函数表示,比如exp(x^2),这个题目估计没有初等函数形式的解。这个函数应该是一致收敛的,可以求级数解,比如将被积函数展开成泰勒级数,对每项分别积分