c/c++中一些高级函数的使用

setvbuf

函数名: setvbuf
功 能: 把缓冲区与流相关
用 法: int setvbuf(FILE *stream, char *buf, int type, unsigned size);
参数:stream :指向流的指针
buf : 期望缓冲区的地址;
type : 期望缓冲区的类型:
_IOFBF(满缓冲):当缓冲区为空时,从流读入数据。或者当缓冲区满时,向流写入数 据。
_IOLBF(行缓冲):每次从流中读入一行数据或向流中写入一行数据。
_IONBF(无缓冲):直接从流中读入数据或直接向流中写入数据,而没有缓冲区。
size : 缓冲区内字节的数量。
注意:This function should be called once the file associated with the stream has already been opened but before any input or output operation has taken place.
意思是这个函数应该在打开流后,立即调用,在任何对该流做输入输出前
 
/* setvbuf example */
#include <stdio.h>

char sBuf[1024];

int main ()
{
FILE *pFile;
pFile=fopen ("myfile.txt","w");
setvbuf ( pFile , sBuf, _IOFBF , 1024 );

// File operations here
fclose (pFile);
return 0;
}
在这个例子中,每次写1024字节,所以只有缓冲区满了(有1024字节),才往文件写入数据,可以减少IO次数

~/gcyin/study/php/test/discuz/webbench-1.5/webbench.c:

        f=fdopen(mypipe[0],"r");
        if(f==NULL)
        {
            perror("open pipe for reading failed.");
            return 3;
        }
        setvbuf(f,NULL,_IONBF,0);


getopt_long

http://baike.baidu.com/view/906700.htm?fr=aladdin

GNU提供的getopt()函数的特点

http://blog.csdn.net/realduke2000/article/details/1812126

getopt被用来解析命令行选项参数。
getopt_long支持长选项的命令行解析,使用man getopt_long,得到其声明如下:
int getopt_long(int argc, char * const argv[],const char *optstring, const struct option *longopts,int *longindex);
函数中的argc和argv通常直接从main()的两个参数传递而来。optsting是选项参数组成的字符串:
字符串optstring可以下列元素:
1.单个字符,表示选项,
2.单个字符后接一个冒号:表示该选项后必须跟一个参数。参数紧跟在选项后或者以空格隔开。该参数的指针赋给optarg。
3 单个字符后跟两个冒号,表示该选项后可以有参数也可以没有参数。如果有参数,参数必须紧跟在选项后不能以空格隔开。该参数的指针赋给optarg。(这个特性是GNU的扩张)。
optstring是一个字符串,表示可以接受的参数。例如,"a:b:cd",表示可以接受的参数是a,b,c,d,其中,a和b参数后面跟有更多的参数值。(例如:-a host -b name)
参数longopts,其实是一个结构的实例:
struct option {
const char *name; //name表示的是长参数名
int has_arg; //has_arg有3个值,no_argument(或者是0),表示该参数后面不跟参数值
// required_argument(或者是1),表示该参数后面一定要跟个参数值
// optional_argument(或者是2),表示该参数后面可以跟,也可以不跟参数值
int *flag;
//用来决定,getopt_long()的返回值到底是什么。如果flag是null(通常情况),则函数会返回与该项option匹配的val值;如果flag不是NULL,则将val值赋予flag所指向的内存,并且返回值设置为0。
int val; //和flag联合决定返回值
}
参数longindex,表示当前长参数在longopts中的索引值。[1] 
给个例子:
struct option long_options[] = {
{"a123", required_argument, 0, 'a'},
{"c123", no_argument, 0, 'c'},
}
现在,如果命令行的参数是-a 123,那么调用getopt_long()将返回字符'a',并且将字符串123由optarg返回(注意注意!字符串123由optarg带 回!optarg不需要定义,在getopt.h中已经有定义),那么,如果命令行参数是-c,那么调用getopt_long()将返回字符'c',而 此时,optarg是null。最后,当getopt_long()将命令行所有参数全部解析完成后,返回-1。

 

required_argument(或者是1)时,参数输入格式为:--参数 值 或者 --参数=值。
optional_argument(或者是2)时,参数输入格式只能为:--参数=值。
static const struct option long_options[]=
{
    {"force",no_argument,&force,1},
    {"reload",no_argument,&force_reload,1},
    {"time",required_argument,NULL,'t'},
    {"help",no_argument,NULL,'?'},
    {"http09",no_argument,NULL,'9'},
    {"http10",no_argument,NULL,'1'},
    {"http11",no_argument,NULL,'2'},
    {"get",no_argument,&method,METHOD_GET},
    {"head",no_argument,&method,METHOD_HEAD},
    {"options",no_argument,&method,METHOD_OPTIONS},
    {"trace",no_argument,&method,METHOD_TRACE},
    {"version",no_argument,NULL,'V'},
    {"proxy",required_argument,NULL,'p'},
    {"clients",required_argument,NULL,'c'},
    {NULL,0,NULL,0}
};



static void usage(void)
{
    fprintf(stderr,
            "webbench [option]... URL
"
            "  -f|--force               Don't wait for reply from server.
"
            "  -r|--reload              Send reload request - Pragma: no-cache.
"
            "  -t|--time <sec>          Run benchmark for <sec> seconds. Default 30.
"
            "  -p|--proxy <server:port> Use proxy server for request.
"
            "  -c|--clients <n>         Run <n> HTTP clients at once. Default one.
"
            "  -9|--http09              Use HTTP/0.9 style requests.
"
            "  -1|--http10              Use HTTP/1.0 protocol.
"
            "  -2|--http11              Use HTTP/1.1 protocol.
"
            "  --get                    Use GET request method.
"
            "  --head                   Use HEAD request method.
"
            "  --options                Use OPTIONS request method.
"
            "  --trace                  Use TRACE request method.
"
            "  -?|-h|--help             This information.
"
            "  -V|--version             Display program version.
"
           );  
};


int main(int argc, char *argv[])
{
    int opt=0;
    int options_index=0;
    char *tmp=NULL;

    if(argc==1)
    {
        usage();
        return 2;
    } 

    while((opt=getopt_long(argc,argv,"912Vfrt:p:c:?h",long_options,&options_index))!=EOF )
    {
        switch(opt)
        {
            case  0 : break;
            case 'f': force=1;break;
            case 'r': force_reload=1;break;
            case '9': http10=0;break;
            case '1': http10=1;break;
            case '2': http10=2;break;
            case 'V': printf(PROGRAM_VERSION"
");exit(0);
            case 't': benchtime=atoi(optarg);break;
            case 'p':
                      /* proxy server parsing server:port */
                      tmp=strrchr(optarg,':');
                      proxyhost=optarg;
                      if(tmp==NULL)
                      {
                          break;
                      }
                      if(tmp==optarg)
                      {
                          fprintf(stderr,"Error in option --proxy %s: Missing hostname.
",optarg);
                          return 2;
                      }
                      if(tmp==optarg+strlen(optarg)-1)
                      {
                          fprintf(stderr,"Error in option --proxy %s Port number is missing.
",optarg);
                          return 2;
                      }
                      *tmp='';
                      proxyport=atoi(tmp+1);break;
            case ':':
            case 'h':
            case '?': usage();return 2;break;
            case 'c': clients=atoi(optarg);break;
        }
    }
}

转载:http://hi.baidu.com/freelonely/blog/item/340341077c4d287302088189.html

预对齐内存的分配

在大多数情况下,编译器和C库透明地帮你处理对齐问题。POSIX 标明了通过malloc( )calloc( ), 和 realloc( ) 返回的地址对于任何的C类型来说都是对齐的。在Linux中,这些函数返回的地址在32位系统是以8字节为边界对齐,在64位系统是以16字节为边界对齐的。有时候,对于更大的边界,例如页面,程序员需要动态的对齐。虽然动机是多种多样的,但最常见的是直接块I/O的缓存的对齐或者其它的软件对硬件的交互,因此,POSIX 1003.1d提供一个叫做posix_memalign( )的函数:

/* one or the other -- either suffices */
#define _XOPEN_SOURCE 600
#define _GNU_SOURCE
#include <stdlib.h>
int posix_memalign (void **memptr,
                    size_t alignment,
                    size_t size);
* See http://perens.com/FreeSoftware/ElectricFence/ and http://valgrind.org, respectively.

调用posix_memalign( )成功时会返回size字节的动态内存,并且这块内存的地址是alignment的倍数。参数alignment必须是2的幂,还是void指针的大小的倍数。返回的内存块的地址放在了memptr里面,函数返回值是0.

调用失败时,没有内存会被分配,memptr的值没有被定义,返回如下错误码之一:

EINVAL

参数不是2的幂,或者不是void指针的倍数。

ENOMEM

没有足够的内存去满足函数的请求。

要注意的是,对于这个函数,errno不会被设置,只能通过返回值得到。

posix_memalign( )获得的内存通过free( )释放。用法很简单:

char *buf;
int ret;
/* allocate 1 KB along a 256-byte boundary */
ret = posix_memalign (&buf, 256, 1024);
if (ret) {
    fprintf (stderr, "posix_memalign: %s
",
             strerror (ret));
    return -1;
}
/* use 'buf'... */
free (buf);

其它和对齐有关的

与对齐有关的问题的范围要超过标准类型的自然对齐和动态存储器地分配。例如,非标准和复杂的类型比标准类型有更复杂的要求。另外,对对齐的关注在给指向不同类型的指针赋值和使用强转时显得加倍的重要。

非标准类型。非标准和复杂的数据类型的对齐比简单的自然对齐有着更多的要求。这里四个有很有用的方法:

•一个结构的对齐要求是和它的成员中最大的那个类型一样的。例如,一个结构中最大的是以4字节对齐的32bit的整形,那么这个结构至少以4字节对齐。

•结构也引入了填充的需要,用来保证每一个成员都符合自己的对齐要求。所以,如果一个char (可能以1字节对齐)后跟着一个int (可能以4字节对齐),编译器会自动地插入3个字节作为填充来保证int以4字节对齐。

程序员有时候排列结构里面的成员-例如,以大小来递减-来是使用作填充的垃圾空间最少。GCC的选项- Wpadded能对这些努力有帮助,因为它使得在编译器偷偷插入填充时产生警告。

•一个联合的对齐和联合里最大的类型一样。

•一个数组的对齐和数组里的元素一样。所以,数组的对齐并不比单单的一个成员严格,这样能使数组里面的所有成员都是自然对齐的。


 
原文地址:https://www.cnblogs.com/jingzhishen/p/3995358.html