[Искусство программирования] Анализ связанного списка даркнета, чтобы найти интерфейс option_find_xx

глубокое обучение
[Искусство программирования] Анализ связанного списка даркнета, чтобы найти интерфейс option_find_xx

欢迎关注我的公众号 [极智视界],获取我的更多笔记分享

O_o>_<  o_OO_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