[英]const char **a = {“string1”,“string2”} and pointer arithametic
main()
{
const char **a = {"string1","string2"};
printf("%c", *a); /* prints s */
printf("%s", a); /* prints string1 */
printf("%s", a+1);/* prints ng1 */
}
GCC v4.8.3打印最后一个printf的“%s”,其中http://codepad.org/打印“ ng1”。
我认为该代码将创建一个指向两个字符串的指针数组,并将基地址分配给a,从而允许进行常规指针运算。 但是这个假设似乎有问题。第一个printf表示我的假设是错误的。 谁能解释为什么观察到这种行为? (请注意,VS 2012抛出了一个错误,提示太多的初始化器,因为GCC发出了不兼容的指针分配警告)。 我知道由于指针分配不兼容而产生的警告。
const char **a
不是指向两个字符串的指针数组。 它声明a
为指向const char
指针。
const char **a = {"string1","string2"}; //No memory is allocated to store string literals
将调用未定义的行为,您可能会得到预期或意外的结果。
要将a
声明为两个指针的数组,您需要将声明更改为
const char *a[] = {"string1","string2"};
程序堆栈中的内存范围如下所示:(请注意,分配错误之前未分配它)
char** a = {s, t, r, i, n ,g, 1, \0, s, t, r, i, n, g, 2, \0}
因此,当您打印命令时:
printf("%c", *a);
您正在取消引用字符串的第一个字符“ s”。
另一方面,当您打印命令时:
printf("%s", a);
您正在打印一个从指针a开始并以'\\ 0'结尾的字符串。 这就是为什么您看到输出'string1'的原因。
最后,当您键入“ a + 1”时,将一步增加指针(此处的示例: 如何增加指针地址和指针的值? )。 在这种情况下,因为char **是一个指针,并且每个指针都是4个字节,所以“ +1”向前跳4个字符。 因此,当您打印命令时:
printf("%s", a+1);
printf从指针“ a” + 4个字节开始,并以“ \\ 0”结束。 这就是为什么输出为“ ng1”的原因。
希望它足够清楚。
这是由于GCC进行了以下特殊初始化。 请参阅int q = {1,2}; 特殊的初始化清单 。 语句const char ** a = {“ string1”,“ string2”}; 导致被视为const char ** a =“ string1”。 这解决了这个谜团,因为* a将打印's',a将打印string1。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.