c语言多级指针与const例子,C语言中的多级指针

前言

C语言中指针,可以算是最灵活,最强大的地方,同时也是最艰深的地方。用不好的话,什么段错误,内存违例等以前没见过的东西都会跳出来。最近看《UNIX系统编程》,感觉能把C语言用到这个水平,才能算是登堂入室。

一般来说,我们会把指针跟数组联系起来理解,比如*p就是一个一维数组,**p是两维数组等,而一般而言,见到两维的指针也算是难得了,更高维的只怕看一会就会晕掉。《UNIX系统编程》中有个关于参数列表的例子,感觉对指针运用的已经到出神入化的境地,所以贴出来大家参考一下。

指向指针的指针

在C语言的入口main函数中,有一个**argv参数,指明命令行参数,一般写法是这样:

C代码

intmain(intargc,char**argv){

/*

* code here.

*/

}

int main(int argc, char **argv){

/*

* code here.

*/

}

这个**argv,是一个指向指针的指针,用来将命令行参数保存下来,比如,输入一条命令:

prog -c -v 200

**argv中的内容即为 prog, -c, -v, 200. 因为prog, -c等的长度不等,就需要一个指针来引用他们,而prog后边接几个参数也是不定的,所以有需要有一个指针来引用,所以就是这里的二维指针了。画一个table可能看起来比较清晰一些:

prog

-c

-v

200

再考虑这样一种情况,shell程序,对于你会输多少行命令也是不知道的,那它就需要再多一个指针来引用你会有多少个命令输入。这就是我们今天要看的(***ptr)了。

指向"指针的指针"的指针

书中的例子是这样,先看下函数的原型:

C代码

intmakeargv(constchar*s,constchar*delimiters,char***argvp);

int makeargv(const char *s, const char *delimiters, char ***argvp);

函数接受三个参数,第一个是要分析的串,第二个是界定符序列,第三个是生成的"指针的指针"(即二维数组)的指针。实现比较简单,主要是看其中关于指针的用法:

C代码

/*

* author : juntao.qiu

*/

intmakeargv(constchar*s,constchar*delimiters,char***argvp){

interror;

inti;

intnumtokens;

constchar*snew;

char*t;

if((s == NULL) || (delimiters == NULL) || (argvp == NULL)){

error = EINVAL;

return-1;

}

*argvp = NULL;

snew = s + strspn(s, delimiters);

if((t = malloc(strlen(snew)+1)) == NULL)

return-1;

strcpy(t, snew);

numtokens = 0;

if(strtok(t, delimiters) != NULL)

for(numtokens = 1; strtok(NULL, delimiters)!= NULL; numtokens++);

if((*argvp = malloc((numtokens+1)*sizeof(char*))) == NULL){

error = errno;

free(t);

errno = error;

return-1;

}

if(numtokens == 0){

free(t);

}else{

strcpy(t, snew);

**argvp = strtok(t, delimiters);//注意此处的指针操作

for(i = 1;i 

*((*argvp)+i) = strtok(NULL, delimiters);//注意此处的指针操作

}

*((*argvp)+numtokens) = NULL;

returnnumtokens;

}

/*

* author : juntao.qiu

*/

int makeargv(const char *s, const char *delimiters, char ***argvp){

int error;

int i;

int numtokens;

const char *snew;

char *t;

if((s == NULL) || (delimiters == NULL) || (argvp == NULL)){

error = EINVAL;

return -1;

}

*argvp = NULL;

snew = s + strspn(s, delimiters);

if((t = malloc(strlen(snew)+1)) == NULL)

return -1;

strcpy(t, snew);

numtokens = 0;

if(strtok(t, delimiters) != NULL)

for(numtokens = 1; strtok(NULL, delimiters)!= NULL; numtokens++);

if((*argvp = malloc((numtokens+1)*sizeof(char *))) == NULL){

error = errno;

free(t);

errno = error;

return -1;

}

if(numtokens == 0){

free(t);

}else{

strcpy(t, snew);

**argvp = strtok(t, delimiters);//注意此处的指针操作

for(i = 1;i < numtokens;i++)

*((*argvp)+i) = strtok(NULL, delimiters);//注意此处的指针操作

}

*((*argvp)+numtokens) = NULL;

return numtokens;

}

程序的主体比较简单,就是按照传入的s,按照界定符delimiters对其进行分割,分割完成后将其放在一个二维数组中,第一维表示最后数组,第二维表示第一个数组中每一个元素的值。

测试

好了,我们测试一下其运行情况:

C代码

intmain(intargc,char**argv){

chardelim[] =" \t";

inti;

char**argvp;

intnumtokens;

char*test ="mine -c 10 2.0";

if((numtokens = makeargv(test, delim, &argvp)) == -1){

fprintf(stderr, "failed to parse the string you given:%s\n", test);

return1;

}

printf("argument contains :\n");

for(i = 0;i 

printf("%d:%s\n", i, argvp[i]);

return0;

}

int main(int argc, char **argv){

char delim[] = " \t";

int i;

char **argvp;

int numtokens;

char *test = "mine -c 10 2.0";

if((numtokens = makeargv(test, delim, &argvp)) == -1){

fprintf(stderr, "failed to parse the string you given:%s\n", test);

return 1;

}

printf("argument contains :\n");

for(i = 0;i < numtokens;i++)

printf("%d:%s\n", i, argvp[i]);

return 0;

}

运行结果如下:

C:\development\cpl\usp>ls

Makefile a.exe makeargv.c nbproject

C:\development\cpl\usp>a

argument contains :

0:mine

1:-c

2:10

3:2.0

个人感觉,能把指针用到这种熟练程度,才算是对C掌握了。《UNIX系统编程》中的代码非常优雅,从大二一直读到毕业,毕业后得空还在读。我会尽量陆续把体会贴出来,以供参考。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值