linux下char指针赋值,二维char**指针用法

本文探讨了Linux环境下,main函数中char* argv[]和char** argv两种命令行参数表示方式。通过示例程序,解释了char**作为指向指针的指针的含义,展示了它们在地址变化和元素访问上的区别。同时,讨论了char**数组的初始化和使用,以及在不同情况下可能出现的问题,如越界访问。文章还提到了控制台程序参数长度限制的猜测,并提供了验证方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在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 **的区别,写下面的测试程序说明。

#include

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*类型的变量加一后的地址变化,我们可以看到:

3162db0164d75550c40a9e20dc27bfb5.png 就是说char**加1,地址加四个字节(32bit)

char*加1,地址加一个字节(8bit)。

这是因为char *指向的地址存储的是指向存储char *类型的地址,它里面是一个地址。所以在32位PC机上是4个字节,假设是一个int类型。那么(char*)++的话指针会跨越一个字节。

而char*指向的是字符,它占用空间大小是一个字节。

##元素访问## 写下面一段测试程序:

#include

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?等待考证。

写下面的代码进行验证。 #include 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].

#include

using namespace std;

void main()

{

// 第一种初始化方法

char **p = new char *[10];

// 赋值后正常使用

p[0] = "aaa";

cout<

// 值可以改变

p[0] = "bbb";

// 未赋值使用会崩。编译能过。

//cout<

// 越界赋值,编译能过,运行能过,输出时崩。

// 第二种初始化方法

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]可以改为pP[3000]。pP是一个指针,不是数组,应该不存在所谓的越界。

##Reference##

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值