• 正文
    • 一、linux應(yīng)用程序如何接收參數(shù)?
    • 二、選項(xiàng)
    • 三、getopt
    • 四、getopt_long
    • 五、getopt_long_only
    • 六、綜合實(shí)例
  • 推薦器件
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

Linux程序之可變參數(shù)&選項(xiàng)那些事!

2023/11/15
1756
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

一、linux應(yīng)用程序如何接收參數(shù)?

1. argc、argv

Linux應(yīng)用程序執(zhí)行時(shí),我們往往通過(guò)命令行帶入?yún)?shù)給程序,比如

ls?/dev/?-l??

其中參數(shù) ?/dev/ 、**-l**都是作為參數(shù)傳遞給命令 ls

應(yīng)用程序又是如何接收這些參數(shù)的?

通常應(yīng)用程序都是從main函數(shù)開(kāi)始執(zhí)行,傳統(tǒng)的main函數(shù)風(fēng)格如下:

int?main(int?argc,?char*?argv[])?
argc:
程序的命令行參數(shù)的數(shù)量,用于統(tǒng)計(jì)參數(shù)數(shù)量。?
argv:
是一個(gè)指向一個(gè)字符串?dāng)?shù)組的指針,數(shù)組包含了參數(shù),每個(gè)字符串就是一個(gè)參數(shù),最后一個(gè)元素為0。
過(guò)一般習(xí)慣使用多級(jí)指針來(lái)操作字符串。

*char argv[]有時(shí)候我們也寫(xiě)成char argv

**argv[]**是一個(gè)存放字符類(lèi)型元素地址的數(shù)組。

因?yàn)?C 中是有字符串的概念的:將每個(gè)字符存放在 char 數(shù)組,最后一個(gè)元素為****表示字符串的結(jié)束。

**printf(%s)**就是輸出字符串。

并且一般使用argv指針來(lái)訪問(wèn)、處理argv[]數(shù)組的內(nèi)容。

C語(yǔ)言中,數(shù)組就是一個(gè)指針加偏移量。

所以argv則是指向一個(gè)指針數(shù)組argv[]的指針,不用定義,直接可以用。

在argv[]數(shù)組中存放的的指針指向輸入命令的各部分(調(diào)用程序、選項(xiàng)、參數(shù))

2. 舉例

下面我們用一個(gè)實(shí)例來(lái)理解argc和argv

/*
*?argc:?命令行參數(shù)的個(gè)數(shù)
*?argv:?字符指針數(shù)組(指向各個(gè)命令行參數(shù)的字符指針?biāo)鶚?gòu)成的數(shù)組)
*/
int?main(int?argc,?char*?argv[])?//?接收命令行參數(shù)
{
?printf("argc=%dn",argc);
????for?(int?i?=?0;?i?<?argc;?i++)?{
????????printf("argv[%d]:?%sn",?i,?argv[i]);?//?遍歷字符指針數(shù)組argv
????}
????return?0;
}

執(zhí)行結(jié)果

peng@ubuntu:~/work$?./peng?arg1?arg2?arg3?
argc=4
argv[0]:?./peng
argv[1]:?arg1
argv[2]:?arg2
argv[3]:?arg3

參數(shù)與argc,argv關(guān)系如下:

二、選項(xiàng)

1. 選項(xiàng)含義

linux程序除了上述情況以外,我們還經(jīng)常會(huì)遇到一個(gè)使用方法就是選項(xiàng)應(yīng)用,

比如:ping命令

peng@ubuntu:~/work$?ping?-h
Usage:?ping?[-aAbBdDfhLnOqrRUvV]?[-c?count]?[-i?interval]?[-I?interface]
????????????[-m?mark]?[-M?pmtudisc_option]?[-l?preload]?[-p?pattern]?[-Q?tos]
????????????[-s?packetsize]?[-S?sndbuf]?[-t?ttl]?[-T?timestamp_option]
????????????[-w?deadline]?[-W?timeout]?[hop1?...]?destination

參數(shù)含義:

-a:嘗試將IP地址解析為主機(jī)名。
-A:使用響應(yīng)數(shù)據(jù)包中的附加數(shù)據(jù)。
-b:允許ping廣播地址。
-B:不允許ping廣播地址。
-c?count:設(shè)置要發(fā)送的數(shù)據(jù)包數(shù)量。
-d:使用SO_DEBUG選項(xiàng)。
-D:不將socket設(shè)為分離模式。
-f:向目標(biāo)發(fā)送一個(gè)“強(qiáng)制”數(shù)據(jù)包。
-h:顯示幫助信息。
-i?interval:設(shè)置發(fā)送數(shù)據(jù)包之間的時(shí)間間隔。
-I?interface:設(shè)置要使用的網(wǎng)絡(luò)接口。
-l?preload:設(shè)置發(fā)送的數(shù)據(jù)包數(shù)量。
-m?mark:設(shè)置ping數(shù)據(jù)包的標(biāo)記。
-M?pmtudisc_option:設(shè)置MTU發(fā)現(xiàn)選項(xiàng)。
-n:不要將IP地址解析為主機(jī)名。
-O:?jiǎn)⒂迷驾敵觥?
-p?pattern:設(shè)置數(shù)據(jù)包的模式。
-Q?tos:設(shè)置服務(wù)類(lèi)型。
-r:不使用路由表,直接發(fā)送數(shù)據(jù)包到目標(biāo)主機(jī)。
-R:?jiǎn)⒂糜涗浡酚伞?
-s?packetsize:設(shè)置數(shù)據(jù)包的大小。
-S?sndbuf:設(shè)置套接字的發(fā)送緩沖區(qū)大小。
-t?ttl:設(shè)置數(shù)據(jù)包的TTL值。
-T?timestamp_option:設(shè)置時(shí)間戳選項(xiàng)。
-U:使用UDP數(shù)據(jù)包。
-v:顯示詳細(xì)的ping命令輸出。
-V:顯示ping命令的版本信息。
-w?deadline:設(shè)置等待響應(yīng)的時(shí)間。
-W?timeout:設(shè)置等待響應(yīng)的超時(shí)時(shí)間。

destination:指定要ping的目標(biāo)主機(jī)或IP地址。

這些 - 開(kāi)頭的都是選項(xiàng),
[]表示可選的意思

[-aAbBdDfhLnOqrRUvV]????是無(wú)參的選項(xiàng)
[-c?count]?[-i?interval]?[-I?interface]
[-m?mark]?[-M?pmtudisc_option]?[-l?preload]?[-p?pattern]?[-Q?tos]
[-s?packetsize]?[-S?sndbuf]?[-t?ttl]?[-T?timestamp_option]
[-w?deadline]?[-W?timeout]?[hop1?...]??這些都是有參數(shù)的選項(xiàng)
destination???必須填寫(xiě)的參數(shù)

前輩們利用這點(diǎn)發(fā)明了“UNIX 風(fēng)格”的命令,選項(xiàng)前面加一個(gè)橫杠-,用于區(qū)分選項(xiàng)和參數(shù)。

2. 程序如何區(qū)分參數(shù)和選項(xiàng)?

在程序的代碼實(shí)現(xiàn)中,按照 UNIX 的代碼慣例,上來(lái)直接跳過(guò)第一個(gè),然后判斷指針指向的字符串第一個(gè)字符是不是-,如果是的,那么進(jìn)入一個(gè)switch判斷,用case列出多種支持的情況下,應(yīng)該執(zhí)行什么代碼。

例如下面這樣就可以判斷選項(xiàng)和處理參數(shù):

int?c;
while?(--argc?>?0?&&?(*++argv)[0]?==?'-'?{
?while?(c?=?*++argv[0]?{
??switch(c){
??case?'x':
???...
???break;
??case?'n':
???...
???break;
??default:
???printf("xxx:?illegal?opyion?%cn",?c);
???...
???break;
??}
?}
}

3. getopt、getopt_long

事實(shí)這么處理選項(xiàng)參數(shù)是比較麻煩的,

linux提供了選項(xiàng)解析的函數(shù):

//?頭文件
#include<unistd.h>
#include<getopt.h>??????????/*所在頭文件?*/
int?getopt(intargc,?char?*?const?argv[],?const?char?*optstring);
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);
extern?char?*optarg;?????????/*系統(tǒng)聲明的全局變量?*/
extern?int?optind,?opterr,?optopt;

三、getopt

1. 定義:

int?getopt(int?argc,?char?*?const?argv[],?const?char?*optstring);
功能:
?getopt是用來(lái)解析命令行選項(xiàng)參數(shù)的,但是只能解析短選項(xiàng):?**-d?100**,不能解析長(zhǎng)選項(xiàng):**--prefix**
參數(shù)
?argc:
??main()函數(shù)傳遞過(guò)來(lái)的參數(shù)的個(gè)數(shù)
?argv:
??main()函數(shù)傳遞過(guò)來(lái)的參數(shù)的字符串指針數(shù)組
?optstring:
??選項(xiàng)字符串,告知?getopt()可以處理哪個(gè)選項(xiàng)以及哪個(gè)選項(xiàng)需要參數(shù)
返回:
?如果選項(xiàng)成功找到,返回選項(xiàng)字母;如果所有命令行選項(xiàng)都解析完畢,返回?-1;
?如果遇到選項(xiàng)字符不在?optstring?中,返回字符?‘?’;
?如果遇到丟失參數(shù),那么返回值依賴(lài)于?optstring?中第一個(gè)字符,
?如果第一個(gè)字符是?‘:’?則返回’:‘,否則返回’?'并提示出錯(cuò)誤信息。

2. optstring 含義 【重要】

下邊重點(diǎn)舉例說(shuō)明optstring的格式意義:

char*optstring?=?“ab:c::”;
單個(gè)字符a?????????表示選項(xiàng)a沒(méi)有參數(shù)????????????格式:-a即可,不加參數(shù)
單字符加冒號(hào)b:?????表示選項(xiàng)b有且必須加參數(shù)??????格式:-b?100或-b100,但-b=100錯(cuò)
單字符加2冒號(hào)c::???表示選項(xiàng)c可以有,也可以無(wú)?????格式:-c200,其它格式錯(cuò)誤

上面這個(gè) optstring 在傳入之后,getopt 函數(shù)將依次檢查命令行是否指定了 -a, -b, -c(這需要多次調(diào)用 getopt 函數(shù),直到其返回-1),當(dāng)檢查到上面某一個(gè)參數(shù)被指定時(shí),函數(shù)會(huì)返回被指定的參數(shù)名稱(chēng)(即該字母)

系統(tǒng)聲明的4個(gè)全局變量含義如下:

optarg?——?指向當(dāng)前選項(xiàng)參數(shù)(如果有)的指針。
optind?——?再次調(diào)用?getopt()?時(shí)的下一個(gè)?argv指針的索引。
optopt?——?最后一個(gè)未知選項(xiàng)。
opterr?-——?如果不希望getopt()打印出錯(cuò)信息,則只要將全域變量opterr設(shè)為0即可。

3. 實(shí)例

說(shuō)千道萬(wàn),不如來(lái)一個(gè)實(shí)例:

#include<stdio.h>
#include<unistd.h>
#include<getopt.h>
int?main(intargc,?char?*argv[])
{
????int?opt;
????char?*string?=?"a::b:c:d";
????while?((opt?=?getopt(argc,?argv,?string))!=?-1)
????{??
????????printf("opt?=?%ctt",?opt);
????????printf("optarg?=?%stt",optarg);
????????printf("optind?=?%dtt",optind);
????????printf("argv[optind]?=?%sn",argv[optind]);
????}??
}
    正確輸入?yún)?shù),執(zhí)行結(jié)果如下:
peng@ubuntu:~/work/test$?./peng?-a100?-b?200?-c?300?-d
opt?=?a??optarg?=?100??optind?=?2??argv[optind]?=?-b
opt?=?b??optarg?=?200??optind?=?4??argv[optind]?=?-c
opt?=?c??optarg?=?300??optind?=?6??argv[optind]?=?-d
opt?=?d??optarg?=?(null)??optind?=?7??argv[optind]?=?(null)

或者

ork/test$?./peng?-a100?-b200?-c300?-d?
opt?=?a??optarg?=?100??optind?=?2??argv[optind]?=?-b200
opt?=?b??optarg?=?200??optind?=?3??argv[optind]?=?-c300
opt?=?c??optarg?=?300??optind?=?4??argv[optind]?=?-d
opt?=?d??optarg?=?(null)??optind?=?5??argv[optind]?=?(null)
    輸入選項(xiàng)參數(shù)錯(cuò)誤的情況
peng@ubuntu:~/work/test$?./peng?-a?100?-b?200?-c?300?-d
opt?=?a??optarg?=?(null)??optind?=?2??argv[optind]?=?100
opt?=?b??optarg?=?200??optind?=?5??argv[optind]?=?-c
opt?=?c??optarg?=?300??optind?=?7??argv[optind]?=?-d
opt?=?d??optarg?=?(null)??optind?=?8??argv[optind]?=?(null)

導(dǎo)致解析錯(cuò)誤,第一個(gè) optarg = null,實(shí)際輸入?yún)?shù) 100,由于格式不正確造成的(可選參數(shù)格式固定)

    參數(shù)丟失,也會(huì)導(dǎo)致錯(cuò)誤
peng@ubuntu:~/work/test$?./peng?-a?-b?200?-c?
opt?=?a??optarg?=?(null)??optind?=?2??argv[optind]?=?-b
opt?=?b??optarg?=?200??optind?=?4??argv[optind]?=?-c
./peng:?option?requires?an?argument?--?'c'
opt?=????optarg?=?(null)??optind?=?5??argv[optind]?=?(null)

c選項(xiàng)是必須有參數(shù)的

    命令行選項(xiàng)未定義,-e選項(xiàng)未在optstring中定義,會(huì)報(bào)錯(cuò):
peng@ubuntu:~/work/test$?./peng?-t
./peng:?invalid?option?--?'t'
opt?=????optarg?=?(null)??optind?=?2??argv[optind]?=?(null)

四、getopt_long

1. 定義:

int?getopt_long(int?argc,?char?*?const?argv[],?const?char?*optstring,
const?struct?option?*longopts,int?*longindex);
功能:
?包含?getopt?功能,增加了解析長(zhǎng)選項(xiàng)的功能如:--prefix?--help
參數(shù):
?longopts?
??指明了長(zhǎng)參數(shù)的名稱(chēng)和屬性
?longindex?
??如果longindex非空,它指向的變量將記錄當(dāng)前找到參數(shù)符合longopts里的第幾個(gè)元素的描述,即是?longopts?的下標(biāo)值
返回:
?對(duì)于短選項(xiàng),返回值同?getopt?函數(shù);
?對(duì)于長(zhǎng)選項(xiàng),
??如果?flag?是?NULL?,返回?val?,否則返回?0?;
?對(duì)于錯(cuò)誤情況返回值同?getopt?函數(shù)

2. struct option

struct?option?{
?const?char??*name;???????/*?參數(shù)名稱(chēng)?*/
?int??????????has_arg;????/*?指明是否帶有參數(shù)?*/
?int??????????*flag;??????/*?flag=NULL時(shí),返回value;不為空時(shí),*flag=val,返回0?*/
?int??????????val;????????/*?用于指定函數(shù)找到選項(xiàng)的返回值或flag非空時(shí)指定*flag的值?*/
};?

參數(shù)has_arg 說(shuō)明:
has_arg ?指明是否帶參數(shù)值,其數(shù)值可選:

?no_argument?
??表明長(zhǎng)選項(xiàng)不帶參數(shù),如:–name,?--help
?required_argument?
??表明長(zhǎng)選項(xiàng)必須帶參數(shù),如:–prefix?/root或?--prefix=/root
?optional_argument?
??表明長(zhǎng)選項(xiàng)的參數(shù)是可選的,如:–help或?–prefix=/root,其它都是錯(cuò)誤

3. 實(shí)例

#include<stdio.h>
#include<unistd.h>
#include<getopt.h>
int?main(intargc,?char?*argv[])
{
????int?opt;
????int?digit_optind?=?0;
????int?option_index?=?0;
????char?*string?=?"a::b:c:d";
????static?struct?option?long_options[]?=
????{??
????????{"reqarg",?required_argument,NULL,?'r'},
????????{"optarg",?optional_argument,NULL,?'o'},
????????{"noarg",??no_argument,?????????NULL,'n'},
????????{NULL,?????0,??????????????????????NULL,?0},
????};?
????while((opt?=getopt_long_only(argc,argv,string,long_options,&option_index))!=?-1)
????{??
????????printf("opt?=?%ctt",?opt);
????????printf("optarg?=?%stt",optarg);
????????printf("optind?=?%dtt",optind);
????????printf("argv[optind]?=%stt",?argv[optind]);
????????printf("option_index?=?%dn",option_index);
????}??
}
    正確執(zhí)行命令
peng@ubuntu:~/work/test$?./long?--reqarg?100?--optarg=200?--noarg
opt?=?r??optarg?=?100??optind?=?3??argv[optind]?=--optarg=200??option_index?=?0
opt?=?o??optarg?=?200??optind?=?4??argv[optind]?=--noarg??option_index?=?1
opt?=?n??optarg?=?(null)??optind?=?5??argv[optind]?=(null)??option_index?=?2

或者

peng@ubuntu:~/work/test$?./long?–reqarg=100?--optarg=200?--noarg
opt?=?o??optarg?=?200??optind?=?3??argv[optind]?=--noarg??option_index?=?1
opt?=?n??optarg?=?(null)??optind?=?4??argv[optind]?=(null)??option_index?=?2
    可選選項(xiàng)可以不給參數(shù)
peng@ubuntu:~/work/test$?./long?--reqarg?100?--optarg?--noarg
opt?=?r??optarg?=?100??optind?=?3??argv[optind]?=--optarg??option_index?=?0
opt?=?o??optarg?=?(null)??optind?=?4??argv[optind]?=--noarg??option_index?=?1
opt?=?n??optarg?=?(null)??optind?=?5??argv[optind]?=(null)??option_index?=?2
    輸入長(zhǎng)選項(xiàng)錯(cuò)誤的情況
peng@ubuntu:~/work/test$?./long?--reqarg?100?--optarg?200?--noarg
opt?=?r??optarg?=?100??optind?=?3??argv[optind]?=--optarg??option_index?=?0
opt?=?o??optarg?=?(null)??optind?=?4??argv[optind]?=200??option_index?=?1
opt?=?n??optarg?=?(null)??optind?=?6??argv[optind]?=(null)??option_index?=?2

五、getopt_long_only

getopt_long_only 函數(shù)與 getopt_long 函數(shù)使用相同的參數(shù)表,在功能上基本一致

只是 getopt_long 只將 --name 當(dāng)作長(zhǎng)參數(shù),但 getopt_long_only 會(huì)將 --name 和 -name 兩種選項(xiàng)都當(dāng)作長(zhǎng)參數(shù)來(lái)匹配

getopt_long_only 如果選項(xiàng) -name 不能在 longopts 中匹配,但能匹配一個(gè)短選項(xiàng),它就會(huì)解析為短選項(xiàng)。

六、綜合實(shí)例

下面這個(gè)例子,是一口君從開(kāi)源項(xiàng)目ifplug提取出來(lái)的命令提取小例子,

大家可以根據(jù)自己需要,基于這個(gè)框架,定制自己的程序。

#define?_GNU_SOURCE
#include?<stdlib.h>
#include?<stdio.h>
#include?<string.h>
#include?<unistd.h>
#include?<errno.h>
#include?<getopt.h>
#include?<sys/param.h>

#define?ETHCHECKD_VERSION?"1.1"


int?delay_up?=?0;
char?*interface?=?"eth0";


void?usage(char?*p)?{
????if?(strrchr(p,?'/'))
????????p?=?strchr(p,?'/')+1;

????printf("%s?[options]n"
???????????"???-i?--iface=IFACE??????????Specify?ethernet?interface?(%s)n"?
???????????"???-d?--delay-up=SECS????????Specify?delay?time?(%i)n"
???????????"???-h?--help?????????????????Show?this?helpn",
???????????p,
???????????interface,
???????????delay_up);
}

void?parse_args(int?argc,?char?*argv[])?{
????static?struct?option?long_options[]?=?{

????????{"iface",????????????????required_argument,?0,?'i'},
????????{"delay-up",?????????????required_argument,?0,?'d'},
????????{"help",?????????????????no_argument,?0,?'h'},
????????{"version",??????????????no_argument,?0,?'v'},
????????{0,?0,?0,?0}
????};
????int?option_index?=?0;
????int?help?=?0,?_kill?=?0,?_check?=?0,?_version?=?0,?_suspend?=?0,?_resume?=?0,?_info?=?0;
????
????for?(;;)?{
????????int?c;
????????
????????if?((c?=?getopt_long(argc,?argv,?"i:d:hv",?long_options,?&option_index))?<?0)
????????????break;

????????switch?(c)?{
????????????case?'i'?:
????????????????interface?=?strdup(optarg);
????printf("interface?%sn",interface);
????????????????break;
????????????case?'d':
????????????????delay_up?=?atoi(optarg);
????printf("delay_up?%dn",delay_up);
????????????????break;
????????????case?'h':
????????????????usage(argv[0]);
????????????????break;
?????????????case?'v':
????????????????printf("peng?"ETHCHECKD_VERSION"n");
????????????????break;
????????????default:
????????????????fprintf(stderr,?"Unknown?parameter.n");
????????????????exit(1);
????????}
????}
????
}

static?volatile?int?alarmed?=?0;

int?main(int?argc,?char*?argv[])?{

????parse_args(argc,?argv);
????return?0;
}

下面是測(cè)試結(jié)果

    短選項(xiàng)
peng@ubuntu:~/work/test$?./param?-h
param?[options]
???-i?--iface=IFACE??????????Specify?ethernet?interface?(eth0)
???-d?--delay-up=SECS????????Specify?delay?time?(0)
???-h?--help?????????????????Show?this?help
peng@ubuntu:~/work/test$?./param?-v
peng?1.1

peng@ubuntu:~/work/test$?./param?-vh
peng?1.1
param?[options]
???-i?--iface=IFACE??????????Specify?ethernet?interface?(eth0)
???-d?--delay-up=SECS????????Specify?delay?time?(0)
???-h?--help?????????????????Show?this?help??
???
peng@ubuntu:~/work/test$?./param?-i?eth3?-d?15
interface?eth3
delay_up?15?


peng@ubuntu:~/work/test$?./param?-i?eth3?-d?15?-h
interface?eth3
delay_up?15
param?[options]
???-i?--iface=IFACE??????????Specify?ethernet?interface?(eth3)
???-d?--delay-up=SECS????????Specify?delay?time?(15)
???-h?--help?????????????????Show?this?help
    長(zhǎng)選項(xiàng)
peng@ubuntu:~/work/test$?./param?--help
param?[options]
???-i?--iface=IFACE??????????Specify?ethernet?interface?(eth0)
???-d?--delay-up=SECS????????Specify?delay?time?(0)
???-h?--help?????????????????Show?this?help
???
peng@ubuntu:~/work/test$?./param?--version
peng?1.1

peng@ubuntu:~/work/test$?./param?--iface?eth3?--delay-up?15
interface?eth3
delay_up?15
talk?is?cheap!
test?this?code!

快操練起來(lái)吧?。?!

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊(cè) ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
TORX194 1 Toshiba America Electronic Components Fiber Optic Receiver, FIBER OPTIC RECEIVER, 10Mbps, THROUGH HOLE MOUNT
$23.13 查看
ECS-160-10-42-CKM-TR 1 ECS International Inc Parallel - Fundamental Quartz Crystal,
$5.71 查看
DS24B33G+T&R 1 Maxim Integrated Products EEPROM, 4KX1, Serial, CMOS, 6 X 6 MM, 0.90 MM HEIGHT, ROHS COMPLIANT, SFN-2
$3.07 查看

相關(guān)推薦

登錄即可解鎖
  • 海量技術(shù)文章
  • 設(shè)計(jì)資源下載
  • 產(chǎn)業(yè)鏈客戶(hù)資源
  • 寫(xiě)文章/發(fā)需求
立即登錄

公眾號(hào)『一口Linux』號(hào)主彭老師,擁有15年嵌入式開(kāi)發(fā)經(jīng)驗(yàn)和培訓(xùn)經(jīng)驗(yàn)。曾任職ZTE,某研究所,華清遠(yuǎn)見(jiàn)教學(xué)總監(jiān)。擁有多篇網(wǎng)絡(luò)協(xié)議相關(guān)專(zhuān)利和軟件著作。精通計(jì)算機(jī)網(wǎng)絡(luò)、Linux系統(tǒng)編程、ARM、Linux驅(qū)動(dòng)、龍芯、物聯(lián)網(wǎng)。原創(chuàng)內(nèi)容基本從實(shí)際項(xiàng)目出發(fā),保持原理+實(shí)踐風(fēng)格,適合Linux驅(qū)動(dòng)新手入門(mén)和技術(shù)進(jìn)階。