typedef用于定义基本类型或者结构体,很简单
再看看怎么定义函数:
不使用typedef的:
#include <iostream>
using namespace std;
double besty(int);
double pam(int);
void estimate(int, double (*pf)( int ));
int main(void)
{
int code;
cout<<"How many lines of code do you need ?"<<endl;
cin >>code;
cout<<"Here is the besty's estimate!"<<endl;
estimate(code,besty);
cout<<"Here is the pam's estimate!"<<endl;
estimate(code,pam);
return 0;
}
double besty(int lns)
{
return 0.5*lns;
}
double pam(int lns)
{
return 0.03*lns+0.0004*lns*lns;
}
void estimate(int lines,double (*pf)(int))
{
cout<<lines<<"line will take!"<<endl;
cout<<(*pf)(lines)<<"hours"<<endl;
}
使用typedef的:
#include "stdafx.h"
#include <iostream>
using namespace std;
typedef double MM(int);
MM besty;
MM pam;
void estimate(int , MM *pf);
int main(void)
{
int code;
cout<<"How many lines of code do you need ?"<<endl;
cin >>code;
cout<<"Here is the besty's estimate!"<<endl;
estimate(code,besty);
cout<<"Here is the pam's estimate!"<<endl;
estimate(code,pam);
return 0;
}
double besty(int lns)
{
return 0.5*lns;
}
double pam(int lns)
{
return 0.03*lns+0.0004*lns*lns;
}
void estimate(int lines,MM *pf)
{
cout<<lines<<"line will take!"<<endl;
cout<<pf(lines)<<"hours"<<endl;
cout<<(*pf)(lines)<<"hours"<<endl;//使用pf()和(*pf)()效果是一样的,在引用函数的时候,这两者表示一个意思。
}
再estimate函数里面要把参数里面的函数定义成double (*pf)(int)也就是指向函数的指针。
因为只有这种函数才可以被其他的函数(同返同参)赋地址。
比如
double (*pf)(int);
double dd(int);
double cc(int);
pf=dd;是可以的可以被赋地址。
cc=dd;不可以。
同样在使用的时候上面的程序里面也带了说明,使用pf()和(*pf)()效果是一样的,在引用函数的时候,这两者表示一个意思。
就这个认识的也是有两个流派的,不过,现在两种都认为是对的,兼而容之!
今天修改一下,今天看到一个很不错的程序,linux下面的对目录进行访问的一个程序,里面typedef定义了的部分就很多。看看一下,typedefintMyfunc(const char *, const struct stat *, int);如果再使用Myfunc定义一个变量,那么其实就是定义了一个函数,表现的只是一个地址形式而已,这个函数具有Myfunc函数的所有参数以及返回类型!
看程序吧:
#include "apue.h"
#include <dirent.h>
#include <limits.h>
/* function type that is called for each filename */
typedefintMyfunc(const char *, const struct stat *, int);
static Myfuncmyfunc;
static intmyftw(char *, Myfunc *);
static intdopath(Myfunc *);
static longnreg, ndir, nblk, nchr, nfifo, nslink, nsock, ntot;
int
main(int argc, char *argv[])
{
intret;
if (argc != 2)
err_quit("usage: ftw <starting-pathname>");
ret = myftw(argv[1], myfunc);/* does it all */
ntot = nreg + ndir + nblk + nchr + nfifo + nslink + nsock;
if (ntot == 0)
ntot = 1;/* avoid divide by 0; print 0 for all counts */
printf("regular files = %7ld, %5.2f %%\n", nreg,
nreg*100.0/ntot);
printf("directories = %7ld, %5.2f %%\n", ndir,
ndir*100.0/ntot);
printf("block special = %7ld, %5.2f %%\n", nblk,
nblk*100.0/ntot);
printf("char special = %7ld, %5.2f %%\n", nchr,
nchr*100.0/ntot);
printf("FIFOs = %7ld, %5.2f %%\n", nfifo,
nfifo*100.0/ntot);
printf("symbolic links = %7ld, %5.2f %%\n", nslink,
nslink*100.0/ntot);
printf("sockets = %7ld, %5.2f %%\n", nsock,
nsock*100.0/ntot);
exit(ret);
}
/*
* Descend through the hierarchy, starting at "pathname".
* The caller's func() is called for every file.
*/
#defineFTW_F1/* file other than directory */
#defineFTW_D2/* directory */
#defineFTW_DNR3/* directory that can't be read */
#defineFTW_NS4/* file that we can't stat */
static char*fullpath;/* contains full pathname for every file */
static int/* we return whatever func() returns */
myftw(char *pathname, Myfunc *func)
{
int len;
fullpath = path_alloc(&len);/* malloc's for PATH_MAX+1 bytes */
/* ({Prog pathalloc}) */
strncpy(fullpath, pathname, len);/* protect against */
fullpath[len-1] = 0;/* buffer overrun */
return(dopath(func));
}
/*
* Descend through the hierarchy, starting at "fullpath".
* If "fullpath" is anything other than a directory, we lstat() it,
* call func(), and return. For a directory, we call ourself
* recursively for each name in the directory.
*/
static int/* we return whatever func() returns */
dopath(Myfunc* func)
{
struct statstatbuf;
struct dirent*dirp;
DIR*dp;
intret;
char*ptr;
if (lstat(fullpath, &statbuf) < 0)/* stat error */
return(func(fullpath, &statbuf, FTW_NS));
if (S_ISDIR(statbuf.st_mode) == 0)/* not a directory */
return(func(fullpath, &statbuf, FTW_F));
/*
* It's a directory. First call func() for the directory,
* then process each filename in the directory.
*/
if ((ret = func(fullpath, &statbuf, FTW_D)) != 0)
return(ret);
ptr = fullpath + strlen(fullpath);/* point to end of fullpath */
*ptr++ = '/';
*ptr = 0;
if ((dp = opendir(fullpath)) == NULL)/* can't read directory */
return(func(fullpath, &statbuf, FTW_DNR));
while ((dirp = readdir(dp)) != NULL) {
if (strcmp(dirp->d_name, ".") == 0 ||
strcmp(dirp->d_name, "..") == 0)
continue;/* ignore dot and dot-dot */
strcpy(ptr, dirp->d_name);/* append name after slash */
if ((ret = dopath(func)) != 0)/* recursive */
break;/* time to leave */
}
ptr[-1] = 0;/* erase everything from slash onwards */
if (closedir(dp) < 0)
err_ret("can't close directory %s", fullpath);
return(ret);
}
static int
myfunc(const char *pathname, const struct stat *statptr, int type)
{
switch (type) {
case FTW_F:
switch (statptr->st_mode & S_IFMT) {
case S_IFREG:nreg++;break;
case S_IFBLK:nblk++;break;
case S_IFCHR:nchr++;break;
case S_IFIFO:nfifo++;break;
case S_IFLNK:nslink++;break;
case S_IFSOCK:nsock++;break;
case S_IFDIR:
err_dump("for S_IFDIR for %s", pathname);
/* directories should have type = FTW_D */
}
break;
case FTW_D:
ndir++;
break;
case FTW_DNR:
err_ret("can't read directory %s", pathname);
break;
case FTW_NS:
err_ret("stat error for %s", pathname);
break;
default:
err_dump("unknown type %d for pathname %s", type, pathname);
}
return(0);
}
分享到:
相关推荐
在C语言中一般用typedef来为回调函数定义别名(参数名)。 别名通过宏定义typedef来实现,不是简单的宏替换。可以用作同时声明指针型的多个对象。 比如: 代码如下:char *pa,pb;//pa是一个char型指针,但pb是一个...
表示:ff(int)是一个函数,带有一个int型的形参,该函数返回int (*) (int *,int),它是一个指向函数的指针,所指向的函数返回int型并带有两个分别是Int*和int型的形参。使用typedef可使得定义更加易懂:typedef int ...
2.define的“函数定义” define 可以像函数那样接受一些参数,如下 #define max(x,y) (x)>(y)?(x):(y); 这个定义就将返回两个数中较大的那个,看到了吗?因为这个“函数”没有类型检查,就好像一个函数模 板似的,...
8.2 函数定义的一般形式 99 8.3 函数的参数和函数的值 100 8.3.1 形式参数和实际参数 101 8.3.2 函数的返回值 102 8.4 函数的调用 106 8.4.1 函数调用的一般形式 106 8.4.2 函数调用的方式 106 8.4.3 被调用函数的...
8.2 函数定义的一般形式 99 8.3 函数的参数和函数的值 100 8.3.1 形式参数和实际参数 101 8.3.2 函数的返回值 102 8.4 函数的调用 106 8.4.1 函数调用的一般形式 106 8.4.2 函数调用的方式 106 8.4.3 被调用函数的...
12.9 带一个参数的构造函数:特例 12.10 静态类成员 12.11 何时执行构造函数和析构函数 12.12 作用域分辨符 12.13 嵌套类 12.14 局部类 12.15 向函数传递对象 12.16 返回对象 12.17 对象赋值 第13章 数组、指针、...
成员members,成员可以是数据或函数定义,同时也可以包括允许范围标志 permission labels,范围标志可以是以下三个关键字中 任意一个:private:, public: 或 protected:。它们分别代表以下含义: ● private :class...
《c语言教程(原书第4版)》的一个鲜明特色就是结合大量示例描述c语言的重要特征,并对很多工作代码给出了逐步的分析,以这种独特的教学方法向读者解释新接触的编程元素及一些惯用法。 《c语言教程(原书第4版)》...
2.4怎样表示一个算法 2.4.1;用自然语言表示算法 2.4.2用流程图表示算法 2.4.3三种基本结构和改进的流程图 2.4.4用N-S流程图表示算法 2.4.5用伪代码表示算法 2.4.6用计算机语言表示算法 2.5结构化程序...
对于一个被映射的文件,主要是使用CreateFileMapping函数,利用他我们可以设定一些读写属性:PAGE_READONLY,PAGE_READWRITE,PAGE_WRITECOPY.第一参数指定只能对该映射文件进行读操作。任何写操作将导致内存访问错误。...
iUsrData, 一个用户定义的标识 注意: 1.短信服务器发送短信后,将用WM_COPYDATA的消息发送一个响应包到hWnd_notify, 响应包格式如下: typedef struct __qvdSmResp_t { int id; int iErr; } QVD_SM_RESP; ...
printf函数是一个由系统定义的标准函数,可在程序中直接调用。 【例1.2】 #include #include main() { double x,s; printf("input number:\n"); scanf("%lf",&x); s=sin(x); printf("sine of %lf is %lf\n",...
10.3.2怎样向文件读写一个字符串343 10.3.3用格式化的方式读写文件346 10.3.4用二进制方式向文件读写一组数据347 10.4随机读写数据文件351 10.4.1文件位置标记及其定位351 10.4.2随机读写 354 10.5文件读写的出错...
例如定义一个包含N个指向返回指向字符的指针的函数的指针的数组? 11 1.22 如何声明返回指向同类型函数的指针的函数?我在设计一个状态机,用函数表示每种状态,每个函数都会返回一个指向下一个状态的函数的指针...
例如定义一个包含N个指向返回指向字符的指针的函数的指针的数组? 1.22 如何声明返回指向同类型函数的指针的函数?我在设计一个状态机,用函数表示每种状态,每个函数都会返回一个指向下一个状态的函数的指针。可我...
主要步骤: 1 写一个DLL 2 写一个APP来调用DLL ------------------------------ 补充:对于动态调用,上面的例子只是适用于导出函数返回值是int 或void,并且参数是0的,至于其它类型,需要进行函数指针类型转换,...
下面是个显示调用的例子,假定你已经有一个Test.dll,并且DLL中有个函数名为Test,其声明式是void(); #include using namespace std; typedef void(*TEST )(); int main( char argc, char* argv[] ) { const ...