欢迎关注我的公众号 [极智视界],获取我的更多笔记分享
O_o
>_<
o_O
O_o
~_~
o_O
В этой статье представлена реализация связанного интерфейса поиска по связанным спискам option_find_xx в даркнете.
Даркнет будет использовать множество операций со связанными списками, например, в прошлый раз, когда я написал "[Искусство программирования] Анализ интерфейса read_data_cfg даркнета"Есть пример, в котором" = "до и после каждой строки данных в Voc.Data хранится в виде таблицы цепочки. О некоторых связанных списках и узлах построения, вставки связанного списка, реализации освобожденного списка можно увидеть».[Искусство программирования] Анализ реализации связанного списка C в даркнете", здесь мы в основном говорим об интерфейсе, связанном с поиском в связанном списке.
1. Определение интерфейса поиска по связному списку
Определения интерфейса, связанные с поиском по списку, в основном находятся в заголовке option_list.h:
/// option_list.h
#ifndef OPTION_LIST_H
#define OPTION_LIST_H
#include "darknet.h"
#include "list.h"
/// 你可以把它看成python中的字典,键-值对
typedef struct{
char *key;
char *val;
int used;
} kvp;
#ifdef __cplusplus
extern "C" {
#endif
list *read_data_cfg(char *filename);
int read_option(char *s, list *options);
void option_insert(list *l, char *key, char *val);
/// 这些就是关于链表查找相关接口的声明了
//////////////////////////////////////////////////////////////////
char *option_find(list *l, char *key); //
char *option_find_str(list *l, char *key, char *def); //
char *option_find_str_quiet(list *l, char *key, char *def); //
int option_find_int(list *l, char *key, int def); //
int option_find_int_quiet(list *l, char *key, int def); //
float option_find_float(list *l, char *key, float def); //
float option_find_float_quiet(list *l, char *key, float def); //
//////////////////////////////////////////////////////////////////
void option_unused(list *l);
//typedef struct {
// int classes;
// char **names;
//} metadata;
//LIB_API metadata get_metadata(char *file);
#ifdef __cplusplus
}
#endif
#endif
Давайте рассмотрим их один за другим.
2. вариант_найти
Давайте посмотрим на реализацию option_find:
/// option_list.c
// 链表查找,查找指定key对应的val,找到返回val,没找到返回NULL
char *option_find(list *l, char *key)
{
node *n = l->front; // 从链表头开始
while(n){ // 当节点不为NULL
kvp *p = (kvp *)n->val; // p为指向节点n值域的指针,值域为kvp*
if(strcmp(p->key, key) == 0){ // strcmp 比较p键和传入的key是否一致
p->used = 1; // 若一致则标记
return p->val; // 找到就返回p值
}
n = n->next; // 循环更新
}
return 0;
}
Приведенная выше логика относительно понятна, где strcmp — это функция сравнения строк на языке C, объявленная в string.h:
/// string.h
_Check_return_
int __cdecl strcmp(
_In_z_ char const* _Str1,
_In_z_ char const* _Str2
);
3. option_find_str и option_find_str_quiet
Это будет похоже на option_find, давайте посмотрим на реализацию option_find_str:
/// option_list.c
// 链表查找,查找指定key对应的val,找到返回val,没找到给输出提示并返回def
char *option_find_str(list *l, char *key, char *def)
{
char *v = option_find(l, key); // 调用option_find
if(v) return v; // 若找到,返回找到的字符串
if(def) fprintf(stderr, "%s: Using default '%s'\n", key, def); // 若未找到,使用默认传参def
return def;
}
option_find_str_quiet похож на option_find_str:
/// option_list.c
// 链表查找,查找指定key对应的val,找到返回val,没找到不给输出提示返回def
char *option_find_str_quiet(list *l, char *key, char *def)
{
char *v = option_find(l, key);
if (v) return v;
return def;
}
4. option_find_int и option_find_int_quiet
Взгляните на option_find_int:
/// option_list.c
// 链表查找,查找指定key对应的val,找到返回int val,没找到给输出提示并返回def
int option_find_int(list *l, char *key, int def)
{
char *v = option_find(l, key);
if(v) return atoi(v); // atoi将字符串转换成int
fprintf(stderr, "%s: Using default '%d'\n", key, def); // 没找到,输出错误信息,并返回def
return def;
}
Разница между этой и предыдущей строкой поиска в основном заключается в atoi, который преобразует строку в целое число, а остальные аналогичны.
Продолжайте смотреть на option_find_int_quiet, разница между option_find_int и option_find_int заключается в том, что сообщение об ошибке не выводится, а значение по умолчанию возвращается напрямую:
/// option_list.c
int option_find_int_quiet(list *l, char *key, int def)
{
char *v = option_find(l, key);
if(v) return atoi(v);
return def;
}
5. option_find_float и option_find_float_quiet
Наконец, посмотрите на option_find_float и option_find_float_quiet.
Реализация option_find_float выглядит следующим образом:
/// option_list.c
// 链表查找,查找指定key对应的val,找到返回float val,没找到给输出提示并返回def
float option_find_float(list *l, char *key, float def)
{
char *v = option_find(l, key);
if(v) return atof(v);
fprintf(stderr, "%s: Using default '%lf'\n", key, def);
return def;
}
Вышеприведенное похоже на option_find_int, так что option_find_float_quiet говорить особо не о чем, реализация следующая:
float option_find_float_quiet(list *l, char *key, float def)
{
char *v = option_find(l, key);
if(v) return atof(v);
return def;
}
Выше был проанализирован соответствующий интерфейс поиска по связанным спискам в даркнете, который относительно прост, но требует укрепления основы и извлечения уроков из прошлого.
【Передача по общему номеру】 "[Искусство программирования] Анализ связанного списка даркнета, чтобы найти интерфейс option_find_xx》