在linux下编程时会发现main的控制台输入命令行参数写法有两种
- int main(int argc,char*argv[])
- int main(int argc,char**argv)
控制台可以方便地在终端中输入参数对程序进行控制,这在Java和linux内核的ioctl中也有相似的体现。
其中,argc是命令行总的参数个数,argv[]存储argc个对应的参数,其中第0个参数是程序的全名,第1、2、3..个参数分别是跟在.\program后面对应的参数。[1]
那么,为什么char *argv[]和char**argv等价呢?
char* []指针数组(字符数组),每一个数组元素包含一个指向字符的指针。
而char **是一个指向指针的指针。
##char **的意义## 为了说明char* 和char **的区别,写下面的测试程序说明。
<!-- lang: cpp -->
#include <stdio.h>
void main()
{
char buffer[4]={'w','z','l','d'};
char **argv=buffer;
printf("The address of char** increases\n");
printf("%p\n",argv);
argv++;
printf("%p\n",argv);
printf("The address of char* increases\n");
printf("%p\n",*argv);
(*argv)++;
printf("%p\n",*argv);
getchar();
}
分别打印出char** 和char*类型的变量加一后的地址变化,我们可以看到:
就是说char**加1,地址加四个字节(32bit)
char*加1,地址加一个字节(8bit)。
这是因为char *指向的地址存储的是指向存储char *类型的地址,它里面是一个地址。所以在32位PC机上是4个字节,假设是一个int类型。那么(char*)++的话指针会跨越一个字节。
而char*指向的是字符,它占用空间大小是一个字节。
##元素访问## 写下面一段测试程序:
<!-- lang: cpp -->
#include <stdio.h>
void main()
{
char *p[]={'wqyy','zq','lq','dq'};
printf("%x\n",p[0]);
}
打印出77717979,这分别是wqyy对应的ASCII码值。也就是说打印p[0]指针所指向的四个字节的内容。这是不是因为p[1]和p[0]的地址相差四个字节?printf("%x\n",*p)的结果同上。
但是有一个问题,是*p[]数组中的元素不能超过四个,比如不能写为char p[]={'wqqyy','zq','lq','dq'}。会出现报错:too many characters in constant。这是说在控制台程序里int main(int argc,charargv[])输入的参数值长度要小于4?等待考证。
写下面的代码进行验证。 <!-- lang: cpp --> #include <stdio.h> void main() {
char buff[4][4]={"abcd","wert","retr","rttt"}; char **argv=buff; printf("%c\n",argv[0]); printf("%c\n",argv[1]); printf("%c\n",argv[2]); printf("%c\n",argv[3]); } 打印出a,w,r,r。可是用argv[0][0]访问会出现程序错误,为什么不能访问?这个还没想清楚。这么说在控制台中键入参数时会自动生成适应大小的数组,就像buff[4][4]。然后用实参的大小去确定arg[m][n]大小,这样就可以像《Expert C Programming》 Page44里面一样if(argv[argc-1][0]=='-' || (argv[argc-2][1] =='f') )一样调用了。
##char **p和char *p[]##
先看一段程序[2].
<!-- lang: cpp -->
#include <iostream>
using namespace std;
void main()
{
// 第一种初始化方法
char **p = new char *[10];
// 赋值后正常使用
p[0] = "aaa";
cout<<p[0]<<endl;
// 值可以改变
p[0] = "bbb";
// 未赋值使用会崩。编译能过。
//cout<<p[1]<<endl;
// 越界赋值,编译能过,运行能过,输出时崩。
// 第二种初始化方法
unsigned int i = 0;
char** pP = NULL;
pP = (char**)calloc(128, sizeof(char*));
for (i = 0; i < 128; ++i)
{
pP[i] = (char*)calloc(128, sizeof(char));
}
// 这种初始化方法,好像不存在越界。
pP[1000] = "ddd";
cout<<pP[1000]<<endl;
}
很奇怪的是第二种方法不存在“越界”,pP[1000]可以改为pP[3000]。pP是一个指针,不是数组,应该不存在所谓的越界。
##Reference##
[1].http://www.cnblogs.com/avril/archive/2010/03/22/1691477.html
[2].http://blog.csdn.net/hackbuteer1/article/details/6706562
[3].http://www.cnblogs.com/greatverve/archive/2012/11/23/cpp-char-string.html
[4].http://blog.163.com/digoal@126/blog/static/163877040201271195312138/
[5].http://blog.sina.com.cn/s/blog_95bf1ccc01017c2h.html