指针的行为; char ** argv

时间:2013-07-12 14:22:17

标签: c linux pointers 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#

似乎是第n个字(1和9)的printf显示 我们如何解释指针的这种行为?

4 个答案:

答案 0 :(得分:10)

你错了。

*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”

但是你应该忘记它,因为它永远不会有用!这是未定义的行为,不应该被使用。

答案 1 :(得分:1)

char **argv是指向char *的指针(有时简称为字符串)。执行*argv时取消引用此指针。此取消引用的结果是char *,换句话说,它是char的地址。当您对结果进行添加时,您的代码将计算新地址。因此,例如,当*argv是字符串中第一个字符的地址时,*argv+1是字符串中第二个字符的地址。

当您添加一个长度超过字符串长度的数字时,您将退出“安全”状态。请记住,C将允许您执行指针运算,使您超过字符串的结尾。在第二个示例中,您要求printf在*argv的开头超过9个字节,并从那里打印字符到下一个\0(或NULL)字节。您正在从程序的进程空间中有效地读取任意内存,这可以解释正在打印的内容。

答案 2 :(得分:1)

实际上存在多个问题。

  1. 拜托,请不要以root身份工作。只是不要。
  2. 你的语法(*argv + 9)的字面意思是:“defference argv并移动指针9个字符”,实际上,如果你从./geip 1255移动9个字符,你将到达55。因此,使用argv[i]i = 1..N表示参数索引)或者如果您想要这么做,您必须添加括号:*(argv + i)
  3. 尝试更好地格式化你的代码 - 它不仅对stackoverflow人更有可读性,而且对你来说也更具可读性。
  4. 例如,当您运行./geip a b c 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将会5(见评论)
    • argv[>5]不是一个好主意,因为没有更多的论据。因此,您最好检查argc以查看有多少参数。

答案 3 :(得分:0)

你只是做一个指针算术: ** 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字节的内存转储。