您的位置:首页 > 大数据 > 人工智能

<2012 11 6> 调C记录 <int main(int argc,char **argv)中的“char **argv”怎么理解?>

2012-11-06 13:32 337 查看
int main(int argc,char **argv)


中的“char **argv”怎么理解?

这个形参还可以写成这样: char *argv[]。先来看这种写法。
我们知道实际上从系统环境传过来的参数,是若干个字符串。
比如“ ls -l /root”这个命令,传递给ls这个应用程序的参数就是“ls” “-l” “/root”这三个字符串,int argc表示字符串的个数,这里是3(程序的名字算作第一个参数)。那么实际上参数char *argv[]被这样赋值:

char *argv[0] = "ls";
char *argv[1] = "-l";
char *argv[2] = "/root";


这个过程是编译器自动完成的。因此char *argv[]很显然就是一个指针数组,其中每个指针(每个数组项)都指向一个字符串。

那么char **argv怎么理解呢?其实表示意思是相同的。首先argv是一个指针,它指向的内存区也存放了一个指针,第二个指针才最终指向了字符串。这就是指向指针的指针,即二重指针。
这个数据结构关系在内存中可以这样表示:

【argv】---> 【pointer 1】--->【string 1】


那么怎么实现多个字符串呢?其实只要argv这个指针+1,则指向了第二个指针(这个指针其实是隐含的)的下一个地址,这里地址里也存放了一个指针,指向下一个字符串。像这样:

【argv】 ---> 【pointer 0】--->【string 0】
   +1 ---> 【pointer 1】--->【string 1】
   +2 ---> 【pointer 2】--->【string 2】


那么在上面那个例子中:
string 0 就是“ls”,string 1就是“-l”,string 2就是“/root”。这些操作也都是编译器自动完成的。

最后再来看一下这个问题,即怎样定义一个字符串:
第一种方法:

char string[] = "It's a string!";


第二种方法:

char *string = "It's a string!";


刚才我们用的是第二种定义方法。那么这两种定义方法的是显然不同的。
第一种方法实实在在定义了一个数组,里面存贮这一个字符串,我们可以对这个数组和里面存贮的字符串进行任何操作。

但是第二种方法,我们其实只是定义了一个指针,这个指针指向内存中的某一个位置,这个位置存放了一个字符串。由于这个位置是编译器隐含分配的,程序并不知道,因此去修改这个字符串的内容的结果是没有定义的。我们仅仅能够操作这个指针而已。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: