总结
在这里,由于面试中MySQL问的比较多,因此也就在此以MySQL为例为大家总结分享。但是你要学习的往往不止这一点,还有一些主流框架的使用,Spring源码的学习,Mybatis源码的学习等等都是需要掌握的,我也把这些知识点都整理起来了
arg_hdr
typedef struct arg_hdr {
char flag; /* Modifier flags: ARG_TERMINATOR, ARG_HASVALUE. */
const char* shortopts; /* String defining the short options */
const char* longopts; /* String defiing the long options */
const char* datatype; /* Description of the argument data type */
const char* glossary; /* Description of the option as shown by arg_print_glossary function */
int mincount; /* Minimum number of occurences of this option accepted */
int maxcount; /* Maximum number of occurences if this option accepted */
void* parent; /* Pointer to parent arg_xxx struct */
arg_resetfn* resetfn; /* Pointer to parent arg_xxx reset function */
arg_scanfn* scanfn; /* Pointer to parent arg_xxx scan function */
arg_checkfn* checkfn; /* Pointer to parent arg_xxx check function */
arg_errorfn* errorfn; /* Pointer to parent arg_xxx error function */
void* priv; /* Pointer to private header data for use by arg_xxx functions */
} arg_hdr_t;
最基本的一个类型,所有的其他类型都包含这个类型。一一解释下里面的参数的含义:
-
shortopts: 参数的短名称,比如ls -a 中的a就是短名称;
-
longopts: 参数中的长名称,比如ls —all 中的all就是长名称;
-
datatype: 参数的数据类型有, , NULL, ,(时间类型传入format字符串),(rex类型传入匹配串),等;
-
glossary: 对于参数的描述;
-
mincount: 参数最少的个数(可以规定是否必须有参数比如设置为0为非必须,1…n为必须);
-
maxcount: 参数最多的个数,采用Unix风格的,如kernel.exe -l 1 -l 2 -l 3
-
其他参数非必须。
arg_xxx结构体族
// 整数
struct arg_int
{
struct arg_hdr hdr;
int count;
int *ival;
};
// 文字
struct arg_lit
{
struct arg_hdr hdr;
int count;
};
// 双精度浮点数
struct arg_dbl
{
struct arg_hdr hdr;
int count;
double *dval;
};
// 字符串
struct arg_str
{
struct arg_hdr hdr;
int count;
const char **sval;
};
struct arg_rex
{
struct arg_hdr hdr;
int count;
const char **sval;
};
struct arg_file
{
struct arg_hdr hdr;
int count;
const char **filename;
const char **basename;
const char **extension;
};
struct arg_date
{
struct arg_hdr hdr;
const char *format;
int count;
struct tm *tm_val;
};
详细介绍 arg_int
struct arg_int
{
struct arg_hdr hdr;
int count;
int *ival;
};
结构体的第一个数据成员hdr保存了 Argtable3 库函数使用的私有数据。它包含参数的标签字符串等内容(可以理解为元数据)。
直接公开地访问这些数据是可以的,但很少需要这样做。
它的ival成员变量指向持有从命令行提取出的数组,count为数组的长度。ival 数组的存储在arg_int构造时分配。
这必须通过arg_int构造函数完成。
注意,你永远不应该自己手动实例化任何arg_xxx结构,而是始终使用提供的构造函数来分配结构,并在完成后使用 arg_freetable 释放它。
- 举例
struct arg_int *s;
s = arg_intn(NULL, “scalar”, “”, 3, 5, “foo value”);
完成s后将指向一个包含5 个元素数组的内存块的结构体arg_int。
甚至,你还可以设置多个别名,短选项被赋予一串单个字符,而长选项被赋予一个逗号分隔的字符串。
例如:s = arg_intn("kKx", "scalar,foo", "<n>", 3, 5, "foo value");
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vo3FZ9oz-1633800152784)(example.png)]
如图所示,该s->hdr
结构保留对构造函数的字符串参数的引用等。
该s->count
变量初始化为零,因为它表示s->ival
解析命令行后存储在数组中的有效值的数量。
s->ival
数组的大小由s->hdr.maxcount
给出。
- 实例代码
// 引入 argtable3
#include “argtable3.h”
/* global arg_xxx structs */
struct arg_int *int_arrays;
struct arg_end *end;
int main(int argc, char *argv[]) {
/* the global arg_xxx structs are initialised within the argtable */
void *argtable[] = {
int_arrays = arg_intn(“a”, “array”, “”, 2, 3, “please input an integer”),
end = arg_end(20)
};
int exitcode = -1;
int nerrors = arg_parse(argc, argv, argtable);
if (nerrors == 0) {
exitcode = 0;
int *a = int_arrays->ival;
int len = int_arrays->count;
printf(“input numbers are as following:\n”);
for (int i = 0; i < len; ++i) {
printf("%d ", a[i]);
}
}
return exitcode;
}
运行
./argtable -a 1 -a 2 --array 3
输出
input numbers are as following:
1 2 3
其他的参数结构体使用方法大同小异。
The Argument Table (参数表)
在构建完各种类型参数的结构体之后,我们需要统一将它们组装到一个结构体数组里面,类型为void **
。
struct arg_lit *a = arg_litn(“a”, NULL, 0, 1, “the -a option”);
struct arg_lit *b = arg_litn(“b”, NULL, 0, 1, “the -b option”);
struct arg_lit *c = arg_litn(“c”, NULL, 0, 1, “the -c option”);
struct arg_int *scal = arg_intn(NULL, “scalar”, “”, 0, 1, “foo value”);
struct arg_lit *verb = arg_litn(“v”, “verbose”, 0, 1, “verbose output”);
struct arg_file *o = arg_filen(“o”, NULL,“myfile”, 0, 1, “output file”);
struct arg_file *file = arg_filen(NULL, NULL, “”, 1, 2, “input files”);
struct arg_end *end = arg_end(20);
// 这就是我们的参数列表
void *argtable[] = {a, b, c, scal, verb, o, file, end};
其中,arg_end
结构体是一个特殊的结构体,因为它不代表任何命令行选项。
它主要标记 argtable 数组的结尾,同时它也存储在处理命令行参数时遇到的任何解析器错误。
传递给arg_end构造函数的整数参数是它将存储的最大错误数,任何更多的错误都将被丢弃并替换为单个错误消息“错误太多”。
arg_end
必须要有。
你还可以使用arg_nullcheck
检查参数表中是否有空指针,(感觉这个功能很鸡肋)
if (arg_nullcheck(argtable) != 0)
printf(“error: insufficient memory\n”);
解析命令行
我们使用arg_parse
函数来做到这一点,它返回它遇到的解析错误的数量。
int nerrors = arg_parse(argc, argv, argtable);
如果没有错误的话(nerrors == 0
),那么我们已经成功解析了命令行,你想要在命令行中提取的数据也都存在了参数表这个void**
里面,正常地访问它即可。
设置默认值
对此的解决方法很简单,直接在调用arg_parse
之前设置arg_table
的值,在命令行中有用户输入的值才会被覆盖。
其余的,就是你一开始设置的默认值。
错误处理
如果 arg_parse 函数报告错误,那么我们需要显示它们,因为 arg_parse 本身不会这样做。
使用arg_print_errors
即可,arg_end的内部结构无需关心。
函数定义
void arg_print_errors(FILE* fp, struct arg_end* end, const char* progname);
最后如何让自己一步步成为技术专家
说句实话,如果一个打工人不想提升自己,那便没有工作的意义,毕竟大家也没有到养老的年龄。
当你的技术在一步步贴近阿里p7水平的时候,毫无疑问你的薪资肯定会涨,同时你能学到更多更深的技术,交结到更厉害的大牛。
推荐一份Java架构之路必备的学习笔记,内容相当全面!!!
成年人的世界没有容易二字,前段时间刷抖音看到一个程序员连着加班两星期到半夜2点的视频。在这个行业若想要拿高薪除了提高硬实力别无他法。
你知道吗?现在有的应届生实习薪资都已经赶超开发5年的程序员了,实习薪资26K,30K,你没有紧迫感吗?做了这么多年还不如一个应届生,真的非常尴尬!
进了这个行业就不要把没时间学习当借口,这个行业就是要不断学习,不然就只能被裁员。所以,抓紧时间投资自己,多学点技术,眼前困难,往后轻松!
【关注】+【转发】+【点赞】支持我!创作不易!
5532380874)]
成年人的世界没有容易二字,前段时间刷抖音看到一个程序员连着加班两星期到半夜2点的视频。在这个行业若想要拿高薪除了提高硬实力别无他法。
你知道吗?现在有的应届生实习薪资都已经赶超开发5年的程序员了,实习薪资26K,30K,你没有紧迫感吗?做了这么多年还不如一个应届生,真的非常尴尬!
进了这个行业就不要把没时间学习当借口,这个行业就是要不断学习,不然就只能被裁员。所以,抓紧时间投资自己,多学点技术,眼前困难,往后轻松!
【关注】+【转发】+【点赞】支持我!创作不易!