![](/img/trans.png)
[英]Pointer to array of pointer to char vs. pointer to pointer to char (or char** argv vs. char* (*argv)[])
[英]behaviour of pointer ; char ** argv
当我测试双指针行为时,我得到的结果是我不太了解。
==>代码1:
int main (int argc , char **argv)
{
if(*argv+1 ==NULL)
{
printf("NULL pointer \n");
exit(0) ;
}
else
{
printf("test double pointer[] : %s \n ",*argv+1);
}
return(0);
}
====>结果1
root@root:/home/aa/test# ./geip 1255
test double pointer[] : /geip
root@root:/home/aa/test#
===>代码2:
int main (int argc , char **argv)
{
if(*argv+9 ==NULL)
{
printf("NULL pointer \n");
exit(0) ;
}
else
{
printf("test double pointer[] : %s \n ",*argv+9);
}
return(0);
}
==>结果2:
root@root:/home/aa/test# ./geip 1255
test double pointer[] : 55
root@root:/home/aa/test#
==>结果3:
root@root:/home/aa/test# ./geip
test double pointer[] : ELL=/bin/bash
root@root:/home/aa/test#
看来printf从第n个字(第1和第9个字)显示,如何解释指针的这种行为?
您使用错了。
*argv+1
将被解释为(argv[0])+1
,由于argv[0]
是“ ./geip”,因此您会得到“ / geip”。
*argv+9
将被解释为(argv[0])+9
但是由于argv[0]
仅具有长度6,因此结果不确定。
在您的情况下,argv可能存储为:
. / g e i p \0 1 2 5 5 \0
0 1 2 3 4 5 6 7 8 9 10 11
这就解释了为什么+9
会让您“ 55”
但是您应该真正忘记这一点,因为它永远不会有用! 这是未定义的行为,永远不要使用。
char **argv
是指向char *
的指针(有时更简单地称为字符串)。 执行*argv
时,可以取消引用此指针。 取消引用的结果是char *
或者换句话说,它是char
的地址。 对结果进行加法运算时,您的代码正在计算一个新地址。 因此,例如, *argv
将是字符串中第一个字符的地址, *argv+1
是字符串中第二个字符的地址。
当您添加的数字长于字符串的长度时,您将退出“安全性”。 请记住,C将使您能够进行指针运算,使您经过字符串的结尾。 在第二个示例中,您要让printf从*argv
的开头开始经过9个字节,然后从那里打印字符到下一个\\0
(或NULL)字节。 您正在有效地从程序的进程空间读取任意内存,这解释了正在打印的内容。
实际上有多个问题。
*argv + 9
)的字面意思是:“ deferference argv并移动指针9个字符”,实际上,如果您从./geip 1255
移动9个字符,则会到达55
。 因此,要么使用argv[i]
( i = 1..N
表示参数索引),要么如果您想用困难的方式进行操作,则必须添加括号: *(argv + i)
。 例如,当您运行./geip abc 123
:
argv[0]
是保存程序名称的string
./geip
argv[1]
是string
保持第一个参数- a
argv[2]
是包含第二个参数的string
b
argv[3]
是包含第三个参数的string
c
argv[4]
是包含第四个参数的string
123
argv[5]
为NULL,因为argc将bw 5
(请参阅注释) argv[>5]
并不是一个好主意,因为没有更多参数了。 因此,最好检查argc
以查看有多少个参数。 您只需执行指针算术:** argv是指向指针列表的指针* argv是列表的头
//char **argv is given from outthere
char *p;
p = *argv; // the same as "p = *argv[0]"
for (int i = 0; i < 100) {
printf("Next: %s\n", p+i);
}
尝试运行它并查看内存的转储,从列表的开头到下一个100字节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.