繁体   English   中英

指针行为; 字符** 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)字节。 您正在有效地从程序的进程空间读取任意内存,这解释了正在打印的内容。

实际上有多个问题。

  1. 拜托,拜托,不要扎根。 只是不要。
  2. 您的语法( *argv + 9 )的字面意思是:“ deferference argv并移动指针9个字符”,实际上,如果您从./geip 1255移动9个字符,则会到达55 因此,要么使用argv[i]i = 1..N表示参数索引),要么如果您想用困难的方式进行操作,则必须添加括号: *(argv + i)
  3. 尝试更好地格式化您的代码-不仅对于stackoverflow的人,而且您的可读性都更高。

例如,当您运行./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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM