函数指针浅谈 ----- 表与函数指针完成命令行参数解析

函数指针浅谈 -----表与函数指针完成命令行参数解析

  个人认为C语言的精妙在于宏,指针。这使的C语言既可以与底层硬件打交道,又可以完成上层复杂的构架设计。而函数指针又是指针的一朵绚烂绽放的花。
  所谓函数指针,就是一个指向函数地址的指针变量,虽然这只是一个变量,但是在C语言中,这个变量可以做很多事情。

下面是一个函数指针的声明:
void (* param_handler) (char *value);
大家可以看到  param_handler 变量是指向下面函数类型的指针变量,这样,只要函数式满足下列条件,那么 param_handler就 可以指向它,执行指向的函数
void func (char *value);

  在命令行参数解析和执行中,我们常常要对不同的参数和参数带的value进行解析,通常我们用if-elseif-else语句来处理,但是这样会使判断条件很长,代码的可读性很差,而且当我们需要加新功能时,会使代码更加乱。
  我们可以分析一下,对不同参数的处理函数是不是大致长的差不多?可不可以抽象出来,提取一个公共的函数模板,然后让实现放在后面?
  这个时候,函数指针就派上用场了。在C++中便是虚函数了。
  当然,光函数指针是不够的,不然还是要在main函数中if-elseif-else,我们需要和参数绑定,这样我们可以循环地枚举,当匹配参数时,执行相应的函数。

下面是这个表元素的声明:
typedef struct
{
    char short_param[2];
    char full_param[64];
    void (* param_handler) (char *value);
    bool_t need_value;

} parameter_t;

下面是main函数中的枚举:  
int main(int argc, char **argv)
{
    int i, j;

    for(j=1; j<argc; j++)
    {
        for(i=0; i<array_max_len(parameter_t); i++)
        {
            if(str_equal(param_array[i].short_param, argv[j]) ||
               str_equal(param_array[i].full_param, argv[j]))
            {
                if(param_array[i].need_value) 
                {
                    param_array[i].param_handler(argv[++j]);
                }
                else
                {
                    param_array[i].param_handler("");
                }
            }
        }
    }

    return 0;

}

  现在,在main函数的逻辑中,我们并知道有什么参数,相应的逻辑是什么?这样低耦合就满足,下面就是面向功能的实现了。
  我们有如下需求:打印程序的版本,提供程序的帮助。以下我们可以轻松实现

void show_version(char *value)
{
    printf("This is a test version 1.0-*T*\n");
}

void show_help(char *value)
{
    printf("==============================\n");
    printf("-v  --version:   show version of this\n");
    printf("-h  --help:      show help of this\n");
    printf("==============================\n");
}
  
  现在我们需要绑定参数和参数的执行函数,我们可以在下面数据结构表的定义中定义。

下面是参数结构表:  
#define parameter_t_max_c 2
parameter_t param_array[parameter_t_max_c] = {
                        {.short_param = "-v", 
                         .param_handler = show_version,
                         .full_param = "--version",
                         .need_value = FALSE,
                        },
                        {
                        "-h", "--help", show_help, FALSE
                        },
};

  ^_^,我们可以执行了

neilhhw@neilhhw-laptop:/tmp$ ./test -v
This is a test version 1.0-*T*
neilhhw@neilhhw-laptop:/tmp$ ./test -v -h
This is a test version 1.0-*T*
==============================
-v  --version:   show version of this
-h  --help:      show help of this
-p  --print:     print the param value you input
==============================
  
  根据需求我们需要一个打印用户输入的功能,那么我们只需要加一个针对这个功能的函数,然后新加一个绑定。完全不用动main函数的代码~~

void print_value(char *value)
{
    printf("The value you input is: %s\n", value);
}

#define parameter_t_max_c 3
parameter_t param_array[parameter_t_max_c] = {
                        {.short_param = "-v", 
                         .param_handler = show_version,
                         .full_param = "--version",
                         .need_value = FALSE,
                        },
                        {
                        "-h", "--help", show_help, FALSE
                        },
                        {
                        "-p", "--print", print_value, TRUE
                        },
};

  附上全部代码:
#include <stdio.h>

typedef unsigned char bool_t;

#define TRUE  1
#define FALSE 0

typedef struct
{
    char short_param[2];
    char full_param[64];
    void (* param_handler) (char *value);
    bool_t need_value;

} parameter_t;


#include <stdlib.h>
#define str_equal(x, y) (strncmp(x, y, strlen(y)) == 0 ? 1 : 0)
#define array_max_len(x)    x##_max_c

void show_version(char *value)
{
    printf("This is a test version 1.0-*T*\n");
}

void show_help(char *value)
{
    printf("==============================\n");
    printf("-v  --version:   show version of this\n");
    printf("-h  --help:      show help of this\n");
    printf("-p  --print:     print the param value you input\n");
    printf("==============================\n");
}

void print_value(char *value)
{
    printf("The value you input is: %s\n", value);
}

#define parameter_t_max_c 3
parameter_t param_array[parameter_t_max_c] = {
                        {.short_param = "-v", 
                         .param_handler = show_version,
                         .full_param = "--version",
                         .need_value = FALSE,
                        },
                        {
                        "-h", "--help", show_help, FALSE
                        },
                        {
                        "-p", "--print", print_value, TRUE
                        },
};

int main(int argc, char **argv)
{
    int i, j;

    for(j=1; j<argc; j++)
    {
        for(i=0; i<array_max_len(parameter_t); i++)
        {
            if(str_equal(param_array[i].short_param, argv[j]) ||
               str_equal(param_array[i].full_param, argv[j]))
            {
                if(param_array[i].need_value) 
                {
                    param_array[i].param_handler(argv[++j]);
                }
                else
                {
                    param_array[i].param_handler("");
                }
            }
        }
    }

    return 0;

}





  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值