正常的开发情况下,我们不会这样写
char **prgv ="liujun"; //1
正确的写法应该是
char *p ="liujun";
char **cp = &p; //2
或者
char *ar[] ={"11","12",NULL};
CHAR **prgv=ar;
我现在故意用第1种写法来测试,如下图,标红的地方是命令执行情况。
从运行结果来看,gcc编译的时候会报警,但是没有报错。
第2个标红的地方是运行,第3个标红的地方是部分代码
从运行结果来看,我发现双指针变量prgv中存储的地址就是字符串"liujun"的首地址(换句话说,就是双指针变量prgv指向的地址就是"liujun"的首地址)
运行的最后一行代码是报错了,我当初预测这个地方应该会打印"liujun"的首地址,我是受二维数组的思想启发的,在二维数组中,比如a[0][0] 的地址等同于a[0]的地址也等同于a的地址(双指针是可以指向二维数组的),为什么我这样弄,就不可以呢?
<p>二维数组和双重指针是两码事,分开理解。</p>
二重指针是指向指针的指针,解引用指向指针的指针得到的是指针,中间走了两次间接。
int main()
{
int a=1;
int *p=&a;
int **pp=&p;
}
以上例来说,pp储存的是 p 的地址,p储存的是 a 的地址,解引用pp得到的是p,p指向a。
你的代码里用的是字符串,那么再考虑字符串的情况下又是怎么一回事。
int main()
{
char *pointer_to_str="abc";
char **pointer_to_pointer_to_str = pointer_to_str;
return 0;
}
简单分析,双重指针解引用后得到的是指针,换句话说,你解引用了一个指向"abc"的指针,然后把内存里的 "abc" (0x61626300)当成了一个指针,传递给了printf函数,printf函数在访问0x61626300这个地址的时候就出错了。
二维数组不同于双重指针,以原始数组而言,无论你写几个维度的数组,int a[][][][],它都是一段连续内存,在数组退化的情况下,它也是退化成普通指针 int* 而不会变成 int ****。把二维数组理解成双重指针是错的,它本质上没有两次间接的过程,它索引元素的时候没有 Addr1=>Addr2=>element 这样的过程,而是 Addr1 + Row * Length + Column => Element
回复 <a class="referer" target="_blank">@uniqptr</a> : 谢谢。
回复 <a class="referer" target="_blank">@tcxu</a> : 如果你说的字符串指针是`char*`而不是之前提到的`char**`,那么*((char*)p)得到的是一个char没错。如果是char**并且指向"a"的话,即使"a"只有两个字节,但它还是会尝试访问以"a"开头的四个字节,并把它当成一个指针值。
回复 <a class="referer" target="_blank">@uniqptr</a> : 谢谢答复。如果字符串长度是 1,比如"a", 而目标平台指针长度是4, 那就无法读取了。所以我认为,一个字符串指针的解引用,是这个字符串第一个字符的ASCII码的值。对吗?
回复 <a class="referer" target="_blank">@tcxu</a> : 看目标平台指针长度,也就是sizeof(void*)。
回复 <a class="referer" target="_blank">@uniqptr</a> : 谢谢答复。如果不是"abc", 而是"abcdefg",连续内存从'a'开始,0x61 0x62 0x63 0x64.. 0x00, 共8个字节,那么强制转换又将是多少?
<p>有人吗?</p>
<ol>
<li>你的这个情况,字符串“Liujun”的地址,即字符串第一个字符的地址,可以用 :&*prgv,prgv,或者 "Liujun", 来表示。</li>
<li>最后出错的原因是,若要打印出这个字符串,应当用以上任何一种形式来表示字符串的地址,而不是用 *prgv (字符指针的地址),即</li>
printf("*prgv:%s\n", prgv);
printf("&*prgv:%s\n", &*prgv);
printf("*prgv:%s\n", "Liujun");
<p>既然</p>
printf("*prgv:%s\n", prgv); 打印出正确结果,意味着prgv就是指向了liujun的首地址,
*prgv 的结果就是l
而 printf("*prgv:%s\n", *prgv); //其含义是把l当做地址来再次解析,所以会报错。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。