一、前言

在学习一些项目代码时,尤其涉及到命令行传参的代码,经常遇到getopt相关的函数,对这一类函数可以说是既陌生又熟悉。陌生是因为不知道它是干啥的,熟悉呢,是因为经常遇到。于是乎在追踪了多天ipsec配置文件解析流程之后,准备学习下这一类命令行解析利器。

这么多命令行参数,需要解析,想象都让人头大,如果再没有一个好的解析方式,那就雪上加霜了。辛亏有了一类命令行解析函数,可以让这些解析操作变得容易一点点。下面就简单的介绍下这一类函数,主要有getopt、getopt_long、getopt_long_only。

Man 手册信息如下:

NAME
       getopt, getopt_long, getopt_long_only, optarg, optind, opterr, optopt - Parse command-line options SYNOPSIS
       #include <unistd.h>
       int getopt(int argc, char * const argv[],
                  const char *optstring);        extern char *optarg;
       extern int optind, opterr, optopt;        #include <getopt.h>
       int getopt_long(int argc, char * const argv[],
                  const char *optstring,
                  const struct option *longopts, int *longindex);        int getopt_long_only(int argc, char * const argv[],
                  const char *optstring,
                  const struct option *longopts, int *longindex);

先从最简单的,最基本的getopt函数开始。然后再介绍增强版的getopt_long函数。

二、getopt函数

2.1 函数简介:

int getopt(int argc, char * const argv[], const char *optstring);

各项参数解释如下:

函数功能

用来解析命令行选项参数,只适用于短选项:-d /root; 不能解析长选项--arch, --help等

Argc

通过命令行传给main函数参数的个数

argv

通过命令行传给main函数参数组成的字符串指针数组

optstring

选项字符串。用来告诉getopt可以解析哪些选项,哪些选项需要参数以及函数返回值等(字符后面紧跟一个冒号则需要参数,而两个则表示参数可选)

返回值

如果成功返回选项字母;命令行解析完毕返回-1;如果选项未定义,则提示错误信息,并返回'?';如果参数缺失,第一个字符是':'则返回':', 否则返回'?'

对于optstring字符串格式做一个简单说明:

单个字符,表示没有参数

单个字符紧跟1个冒号,表示必须有参数,格式:-d xxx或者-dxxx

单个字符紧跟2个冒号,表示参数可选,格式:-dxxx

Char *optstring="ab:c::";

说明:此选项指定了三个选项,分别为'a'、'b'、'c'。其中

a选项无需参数,格式:-a即可

b选项必须有参数,格式:-d xxx

c选项参数可选,格式:-c ooo

在此类函数中,需要几个重要的变量共同配合才能完成命令行参数解析工作:

变量名称

作用

Char *optarg

指向当前选项参数的指针

Int optind

用来记录当前已遍历选项的索引,方便下次调用时直接找到下一个选项

Int opterr

正常情况,解析失败会有错误信息,如果不需要此错误信息,将opterr置0即可

Int optopt

最后一个未知选项

2.2 举例说明:

代码如下:


/*************************************************************************
> File Name: getopt.c
> Author: Toney
> Mail: vip_13031075266@163.com
> Created Time: 2021年01月30日 星期六 21时50分45秒
************************************************************************/ #include <stdio.h>
#include <unistd.h>
#include <getopt.h> void main(int argc, char **argv)
{
int flags, opt; while((opt = getopt(argc, argv, "ab:c::")) != -1){ switch(opt){
case 'a':
printf("Input %d parameter is -a=%s\n", optind, optarg);
break;
case 'b':
printf("Input %d parameter is -b=%s\n", optind, optarg);
break;
case 'c':
printf("Input %d parameter is -c=%s\n", optind, optarg);
break;
default:
printf("Not match!!!");
}
} return ; }

三、getopt_long函数

3.1 函数简介:

int getopt_long(int argc, char * const argv[], const char *optstring,const struct option *longopts, int *longindex);

各项参数解释如下:

函数功能

用来解析命令行选项参数,除了getopt函数支持的短选项,还支持长选项,如--help, --prefix

Argc

通过命令行传给main函数参数的个数

argv

通过命令行传给main函数参数组成的字符串指针数组

optstring

选项字符串。用来告诉getopt可以解析哪些选项,哪些选项需要参数以及函数返回值等(字符后面紧跟一个冒号则需要参数,而两个则表示参数可选)

longopts

长选项参数的名称、属性、以及解析后的返回值等结构信息

longindex

用来记录解析到的当前长选项的索引,也就是longopts的下标。

返回值

对于短选项,返回值同getopt函数;对于长选项,如果flag是NULL,返回val,否则返回0;对于错误情况返回值同getopt函数

Struct option结构体:

struct option {
const char  *name;       /* 参数名称 */
int          has_arg;    /* 指明是否带有参数 */
int          *flag;      /* flag=NULL时,返回value;不为空时,*flag=val,返回0 */
int          val;        /* 用于指定函数找到选项的返回值或flag非空时指定*flag的值 */
};

其中has_arg类型取值有如下几种:

No_argument

不需要参数

Required_argument

必须带参数

Optional_argument

参数可选

在此类函数中,需要几个重要的变量共同配合才能完成命令行参数解析工作:

变量名称

作用

Char *optarg

指向当前选项参数的指针

Int optind

用来记录当前已遍历选项的索引,方便下次调用时直接找到下一个选项

Int opterr

正常情况,解析失败会有错误信息,如果不需要此错误信息,将opterr置0即可

Int optopt

最后一个未知选项

3.2 ipsec项目中的一个例子:

先看看在openswan源码中,有关使用getopt_long解析命令行的一个例子(各位把住坐稳了):

static const struct option long_opts[] = {
# define OO OPTION_OFFSET
/* name, has_arg, flag, val */ { "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' },
{ "optionsfrom", required_argument, NULL, '+' },
{ "label", required_argument, NULL, 'l' }, { "ctlbase", required_argument, NULL, OPT_CTLBASE + OO },
{ "name", required_argument, NULL, OPT_NAME + OO },
{ "connalias", required_argument, NULL, OPT_CONNALIAS + OO }, { "keyid", required_argument, NULL, OPT_KEYID + OO },
{ "addkey", no_argument, NULL, OPT_ADDKEY + OO },
{ "pubkeyrsa", required_argument, NULL, OPT_PUBKEYRSA + OO }, { "myid", required_argument, NULL, OPT_MYID + OO }, { "route", no_argument, NULL, OPT_ROUTE + OO },
{ "unroute", no_argument, NULL, OPT_UNROUTE + OO }, { "initiate", no_argument, NULL, OPT_INITIATE + OO },
{ "terminate", no_argument, NULL, OPT_TERMINATE + OO },
{ "delete", no_argument, NULL, OPT_DELETE + OO },
{ "deletestate", required_argument, NULL, OPT_DELETESTATE + OO + NUMERIC_ARG },
{ "crash", required_argument, NULL, OPT_DELETECRASH + OO },
{ "listen", no_argument, NULL, OPT_LISTEN + OO },
{ "unlisten", no_argument, NULL, OPT_UNLISTEN + OO },
{ "purgeocsp", no_argument, NULL, OPT_PURGEOCSP + OO }, { "rereadsecrets", no_argument, NULL, OPT_REREADSECRETS + OO },
{ "rereadcacerts", no_argument, NULL, OPT_REREADCACERTS + OO },
{ "rereadaacerts", no_argument, NULL, OPT_REREADAACERTS + OO },
{ "rereadocspcerts", no_argument, NULL, OPT_REREADOCSPCERTS + OO },
{ "rereadacerts", no_argument, NULL, OPT_REREADACERTS + OO }, { "rereadcrls", no_argument, NULL, OPT_REREADCRLS + OO },
{ "rereadall", no_argument, NULL, OPT_REREADALL + OO },
{ "status", no_argument, NULL, OPT_STATUS + OO },
{ "shutdown", no_argument, NULL, OPT_SHUTDOWN + OO },
{ "xauthname", required_argument, NULL, OPT_XAUTHNAME + OO },
{ "xauthuser", required_argument, NULL, OPT_XAUTHNAME + OO },
{ "xauthpass", required_argument, NULL, OPT_XAUTHPASS + OO },
{ "tpmeval", required_argument, NULL, OPT_TPMEVAL + OO }, { "oppohere", required_argument, NULL, OPT_OPPO_HERE + OO },
{ "oppothere", required_argument, NULL, OPT_OPPO_THERE + OO }, { "asynchronous", no_argument, NULL, OPT_ASYNC + OO }, /* list options */ { "utc", no_argument, NULL, LST_UTC + OO },
{ "checkpubkeys", no_argument, NULL, LST_CHECKPUBKEYS + OO },
{ "listpubkeys", no_argument, NULL, LST_PUBKEYS + OO },
{ "listcerts", no_argument, NULL, LST_CERTS + OO },
{ "listcacerts", no_argument, NULL, LST_CACERTS + OO },
{ "listacerts", no_argument, NULL, LST_ACERTS + OO },
{ "listaacerts", no_argument, NULL, LST_AACERTS + OO },
{ "listocspcerts", no_argument, NULL, LST_OCSPCERTS + OO },
{ "listgroups", no_argument, NULL, LST_GROUPS + OO },
{ "listcrls", no_argument, NULL, LST_CRLS + OO },
{ "listocsp", no_argument, NULL, LST_OCSP + OO },
{ "listpsks", no_argument, NULL, LST_PSKS + OO },
{ "listevents", no_argument, NULL, LST_EVENTS + OO },
{ "listpairs", no_argument, NULL, LST_HOSTPAIRS + OO },
{ "listhostpairs", no_argument, NULL, LST_HOSTPAIRS + OO },
{ "listall", no_argument, NULL, LST_ALL + OO }, /* options for an end description */ { "host", required_argument, NULL, END_HOST + OO },
{ "id", required_argument, NULL, END_ID + OO },
{ "cert", required_argument, NULL, END_CERT + OO },
{ "ca", required_argument, NULL, END_CA + OO },
{ "groups", required_argument, NULL, END_GROUPS + OO },
{ "ikeport", required_argument, NULL, END_IKEPORT + OO + NUMERIC_ARG },
{ "nexthop", required_argument, NULL, END_NEXTHOP + OO },
{ "client", required_argument, NULL, END_CLIENT + OO },
{ "clientwithin", required_argument, NULL, END_CLIENTWITHIN + OO },
{ "clientprotoport", required_argument, NULL, END_CLIENTPROTOPORT + OO },
{ "dnskeyondemand", no_argument, NULL, END_DNSKEYONDEMAND + OO },
{ "srcip", required_argument, NULL, END_SRCIP + OO },
{ "updown", required_argument, NULL, END_UPDOWN + OO },
{ "tundev", required_argument, NULL, END_TUNDEV + OO + NUMERIC_ARG }, /* options for a connection description */ { "to", no_argument, NULL, CD_TO + OO }, { "psk", no_argument, NULL, CD_PSK + OO },
{ "rsasig", no_argument, NULL, CD_RSASIG + OO }, { "encrypt", no_argument, NULL, CD_ENCRYPT + OO },
{ "authenticate", no_argument, NULL, CD_AUTHENTICATE + OO },
{ "compress", no_argument, NULL, CD_COMPRESS + OO },
{ "overlapip", no_argument, NULL, CD_OVERLAPIP + OO },
{ "tunnel", no_argument, NULL, CD_TUNNEL + OO },
{ "tunnelipv4", no_argument, NULL, CD_TUNNELIPV4 + OO },
{ "tunnelipv6", no_argument, NULL, CD_TUNNELIPV6 + OO },
{ "pfs", no_argument, NULL, CD_PFS + OO },
{ "sha2_truncbug", no_argument, NULL, CD_SHA2_TRUNCBUG + OO },
{ "aggrmode", no_argument, NULL, CD_AGGRESSIVE + OO },
{ "disablearrivalcheck", no_argument, NULL, CD_DISABLEARRIVALCHECK + OO },
{ "initiateontraffic", no_argument, NULL
, CD_SHUNT0 + (POLICY_SHUNT_TRAP >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
{ "pass", no_argument, NULL
, CD_SHUNT0 + (POLICY_SHUNT_PASS >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
{ "drop", no_argument, NULL
, CD_SHUNT0 + (POLICY_SHUNT_DROP >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
{ "reject", no_argument, NULL
, CD_SHUNT0 + (POLICY_SHUNT_REJECT >> POLICY_SHUNT_SHIFT << AUX_SHIFT) + OO },
{ "failnone", no_argument, NULL
, CD_FAIL0 + (POLICY_FAIL_NONE >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
{ "failpass", no_argument, NULL
, CD_FAIL0 + (POLICY_FAIL_PASS >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
{ "faildrop", no_argument, NULL
, CD_FAIL0 + (POLICY_FAIL_DROP >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
{ "failreject", no_argument, NULL
, CD_FAIL0 + (POLICY_FAIL_REJECT >> POLICY_FAIL_SHIFT << AUX_SHIFT) + OO },
{ "dontrekey", no_argument, NULL, CD_DONT_REKEY + OO },
{ "forceencaps", no_argument, NULL, CD_FORCEENCAPS + OO },
{ "dpddelay", required_argument, NULL, CD_DPDDELAY + OO + NUMERIC_ARG },
{ "dpdtimeout", required_argument, NULL, CD_DPDTIMEOUT + OO + NUMERIC_ARG },
{ "dpdaction", required_argument, NULL, CD_DPDACTION + OO },
#ifdef XAUTH
{ "xauth", no_argument, NULL, END_XAUTHSERVER + OO },
{ "xauthserver", no_argument, NULL, END_XAUTHSERVER + OO },
{ "xauthclient", no_argument, NULL, END_XAUTHCLIENT + OO },
#endif
#ifdef MODECFG
{ "modecfgpull", no_argument, NULL, CD_MODECFGPULL + OO },
{ "modecfgserver", no_argument, NULL, END_MODECFGSERVER + OO },
{ "modecfgclient", no_argument, NULL, END_MODECFGCLIENT + OO },
#ifdef MODECFG_DNSWINS
{ "modecfgdns1", required_argument, NULL, CD_MODECFGDNS1 + OO },
{ "modecfgdns2", required_argument, NULL, CD_MODECFGDNS2 + OO },
{ "modecfgwins1", required_argument, NULL, CD_MODECFGWINS1 + OO },
{ "modecfgwins2", required_argument, NULL, CD_MODECFGWINS2 + OO },
{ "modeconfigserver", no_argument, NULL, END_MODECFGSERVER + OO },
{ "modeconfigclient", no_argument, NULL, END_MODECFGCLIENT + OO },
#endif
#endif
{ "metric", required_argument, NULL, CD_METRIC + OO + NUMERIC_ARG },
{ "mtu", required_argument, NULL, CD_CONNMTU + OO + NUMERIC_ARG },
{ "sendcert", required_argument, NULL, END_SENDCERT + OO },
{ "certtype", required_argument, NULL, END_CERTTYPE + OO + NUMERIC_ARG },
{ "ipv4", no_argument, NULL, CD_CONNIPV4 + OO },
{ "ipv6", no_argument, NULL, CD_CONNIPV6 + OO }, { "ikelifetime", required_argument, NULL, CD_IKELIFETIME + OO + NUMERIC_ARG },
{ "ipseclifetime", required_argument, NULL, CD_IPSECLIFETIME + OO + NUMERIC_ARG },
{ "rekeymargin", required_argument, NULL, CD_RKMARGIN + OO + NUMERIC_ARG },
{ "rekeywindow", required_argument, NULL, CD_RKMARGIN + OO + NUMERIC_ARG }, /* OBSOLETE */
{ "rekeyfuzz", required_argument, NULL, CD_RKFUZZ + OO + NUMERIC_ARG },
{ "keyingtries", required_argument, NULL, CD_KTRIES + OO + NUMERIC_ARG },
{ "ike", required_argument, NULL, CD_IKE + OO },
{ "ikealg", required_argument, NULL, CD_IKE + OO },
{ "pfsgroup", required_argument, NULL, CD_PFSGROUP + OO },
{ "esp", required_argument, NULL, CD_ESP + OO },
{ "remote_peer_type", required_argument, NULL, CD_REMOTEPEERTYPE + OO},
#ifdef HAVE_NM
{ "nm_configured", no_argument, NULL, CD_NMCONFIGURED + OO},
#endif
#ifdef HAVE_LABELED_IPSEC
{ "loopback", no_argument, NULL, CD_LOOPBACK + OO},
{ "labeledipsec", no_argument, NULL, CD_LABELED_IPSEC + OO},
{ "policylabel", required_argument, NULL, CD_POLICY_LABEL + OO },
#endif
#ifdef DEBUG
{ "debug-none", no_argument, NULL, DBGOPT_NONE + OO },
{ "debug-all", no_argument, NULL, DBGOPT_ALL + OO },
{ "debug-raw", no_argument, NULL, DBGOPT_RAW + OO },
{ "debug-crypt", no_argument, NULL, DBGOPT_CRYPT + OO },
{ "debug-parsing", no_argument, NULL, DBGOPT_PARSING + OO },
{ "debug-emitting", no_argument, NULL, DBGOPT_EMITTING + OO },
{ "debug-control", no_argument, NULL, DBGOPT_CONTROL + OO },
{ "debug-lifecycle", no_argument, NULL, DBGOPT_LIFECYCLE + OO },
{ "debug-klips", no_argument, NULL, DBGOPT_KLIPS + OO },
{ "debug-netkey", no_argument, NULL, DBGOPT_KLIPS + OO },
{ "debug-xfrm", no_argument, NULL, DBGOPT_KLIPS + OO },
{ "debug-dns", no_argument, NULL, DBGOPT_DNS + OO },
{ "debug-oppo", no_argument, NULL, DBGOPT_OPPO + OO },
{ "debug-oppoinfo", no_argument, NULL, DBGOPT_OPPOINFO + OO },
{ "debug-whackwatch", no_argument, NULL, DBGOPT_WHACKWATCH + OO },
{ "debug-controlmore", no_argument, NULL, DBGOPT_CONTROLMORE + OO },
{ "debug-pfkey", no_argument, NULL, DBGOPT_PFKEY + OO },
{ "debug-nattraversal", no_argument, NULL, DBGOPT_NATT + OO },
{ "debug-natt", no_argument, NULL, DBGOPT_NATT + OO },
{ "debug-nat_t", no_argument, NULL, DBGOPT_NATT + OO },
{ "debug-nat-t", no_argument, NULL, DBGOPT_NATT + OO },
{ "debug-x509", no_argument, NULL, DBGOPT_X509 + OO },
{ "debug-dpd", no_argument, NULL, DBGOPT_DPD + OO },
{ "debug-private", no_argument, NULL, DBGOPT_PRIVATE + OO }, { "impair-delay-adns-key-answer", no_argument, NULL, DBGOPT_IMPAIR_DELAY_ADNS_KEY_ANSWER + OO },
{ "impair-delay-adns-txt-answer", no_argument, NULL, DBGOPT_IMPAIR_DELAY_ADNS_TXT_ANSWER + OO },
{ "impair-bust-mi2", no_argument, NULL, DBGOPT_IMPAIR_BUST_MI2 + OO },
{ "impair-bust-mr2", no_argument, NULL, DBGOPT_IMPAIR_BUST_MR2 + OO },
{ "impair-sa-fail", no_argument, NULL, DBGOPT_IMPAIR_SA_CREATION + OO },
{ "impair-die-oninfo", no_argument, NULL, DBGOPT_IMPAIR_DIE_ONINFO + OO },
{ "impair-jacob-two-two", no_argument, NULL, DBGOPT_IMPAIR_JACOB_TWO_TWO + OO },
{ "impair-major-version-bump", no_argument, NULL, DBGOPT_IMPAIR_MAJOR_VERSION_BUMP + OO },
{ "impair-minor-version-bump", no_argument, NULL, DBGOPT_IMPAIR_MINOR_VERSION_BUMP + OO },
{ "impair-retransmits", no_argument, NULL, DBGOPT_IMPAIR_RETRANSMITS + OO },
{ "impair-send-bogus-isakmp-flag", no_argument, NULL, DBGOPT_IMPAIR_SEND_BOGUS_ISAKMP_FLAG + OO },
{ "whackrecord", required_argument, NULL, OPT_WHACKRECORD + OO},
{ "whackstoprecord", no_argument, NULL, OPT_WHACKSTOPRECORD + OO},
#endif
# undef OO
{ 0,0,0,0 }
};

这是whack命令解析时的一个结构信息,可以想象它的配置命令是有多少,而具体实现差不多800行左右的C代码。这里需要注意的是:struct option结构中的val取值通常是单个字符或者数字。由于单字符数量有限,参数比较少时可以使用字符,但是如果像上面辣么多参数,通常采用枚举类型,方便扩展。

四、getopt_long_only函数

getopt_long_only 函数与 getopt_long 函数使用相同的参数表,在功能上基本一致,只是 getopt_long 只将 --name 当作长参数,但 getopt_long_only 会将 --name 和 -name 两种选项都当作长参数来匹配。getopt_long_only 如果选项 -name 不能在 longopts 中匹配,但能匹配一个短选项,它就会解析为短选项。

命令行解析函数:getopt_long、getopt的更多相关文章

  1. C语言命令行解析函数:getopt/getopt_long

    命令行工具下的参数选项有两种,长选项和短选项.短选项以-开头,后面跟单个字母:长选项以--开头,后面可跟多个字母. 一. getopt() 1.功能:解析命令行短选项参数 2.函数原型: #inclu ...

  2. 命令行解析函数:getopt/getopt_long

    参考: http://blog.csdn.net/zhangyang0402/article/details/5671410 http://www.cnblogs.com/gnuhpc/archive ...

  3. 【C】命令行参数解析——getopt、getopt_long及getopt_long_only

    前言 在linux下学习开源代码Webbench,遇到get_long等函数的用法,一时有点懵,故想深入了解这类命令行解析函数,并记此博文. 1.getopt getopt主要用来处理短命令行选项,例 ...

  4. [转]Python 命令行参数和getopt模块详解

    FROM : http://www.tuicool.com/articles/jaqQvq 有时候我们需要写一些脚本处理一些任务,这时候往往需要提供一些命令行参数,根据不同参数进行不同的处理,在Pyt ...

  5. Python 命令行参数和getopt模块详解

    有时候我们需要写一些脚本处理一些任务,这时候往往需要提供一些命令行参数,根据不同参数进行不同的处理,在Python里,命令行的参数和C语言很类似(因为标准Python是用C语言实现的).在C语言里,m ...

  6. linux 中解析命令行参数(getopt_long用法)

    linux 中解析命令行参数(getopt_long用法) http://www.educity.cn/linux/518242.html 详细解析命令行的getopt_long()函数 http:/ ...

  7. shell 命令行参数(getopt和getopts)

    getopt 命令 使用getopt命令,可以解析任何命令行选项和参数,但是用法比较复杂.getopt的命令用法如下: $ getopt --help 用法: getopt optstring par ...

  8. 命令行参数处理-getopt()和getopt_long()

    在实际编程当中,自己编写代码处理命令行参数是比较麻烦且易出错的.一般我们会直接使用getopt()和getopt_long()函数,下文将介绍具体的使用方法. getopt() getopt()用于处 ...

  9. 命令行解析getopt_long

    getopt_long函数可以轻松的解析main函数的命令行参数. int getopt_long(int argc,char * const argv[],const char *optstring ...

随机推荐

  1. 重返MySQL之MySQL基础

    重返MySQL之MySQL基础 本章详细介绍了,什么是数据库,常见的关系型数据库有哪些,什么是MySQL,及MySQL中DDL操作表,DML操作表记录. 1.0 数据库概述 1.1 数据存储的方式 目 ...

  2. 用好WinSCP,无惧Linux命令

    很多人惧怕Linux系统的命令操作模式.实际上对于普通用户来说用到命令的概率非常小. 我们在实践过程中发现管理Linux系统,最多使用如下两个工具: WinSCP(必用):可视化界面工具,实现文件管理 ...

  3. tensorflow踩坑合集2. TF Serving & gRPC 踩坑

    这一章我们借着之前的NER的模型聊聊tensorflow serving,以及gRPC调用要注意的点.以下代码为了方便理解做了简化,完整代码详见Github-ChineseNER ,里面提供了训练好的 ...

  4. OpenGL学习笔记(六)坐标系统

    目录 一.衔接 二.概述 三.各个坐标系统 局部空间 世界空间 观察空间 裁剪空间 四.两种投影矩阵 正射投影 透视投影 五.把它们都组合到一起 六.编码实现 1. 实现卡片旋转 2. 实现正方体旋转 ...

  5. javaSE面向对象编程

    面向对象编程 构造器 构造器就是和类名相同但无返回类型的方法. public class Person { //一个类即使什么都不写,它也会存在一个方法 //显示的定义构造器 String name; ...

  6. [论文阅读] LCC-NLM(局部颜色校正, 非线性mask)

    [论文阅读] LCC-NLM(局部颜色校正, 非线性mask) 文章: Local color correction using non-linear masking 1. 算法原理 如下图所示为, ...

  7. Shell-05-函数

    函数 函数定义 shell中函数的定义格式如下 [ function ] funname [()] { action; [return int;] } 说明: 1.可以带function fun() ...

  8. Java 常用类库与技巧【笔记】

    Java 常用类库与技巧[笔记] Java异常体系 Java异常相关知识 Java在其创立的时候就设置了比较有效的处理机制,其异常处理机制主要回答了三个问题:what,where,why what表示 ...

  9. 做iOS自动化测试必须知道的一些知识

    WDA facebook wda 2015年Facebook 开源了一款 iOS 移动测试框架WebDriverAgent,WebDriverAgent 在 iOS 端实现了一个 WebDriver ...

  10. NOIP 模拟 6 考试总结

    T1 这道题是一道裸的暴力,考场写挂了 \(5pts\) 原因竟是忘了删注释,难受 题解 T2 这道题是一道启发式合并,没想出来,拿了个暴力分跑了 题解 T3 这道题就是一道数学期望,想出来就水得很, ...