繁体   English   中英

const char ** a = {“ string1”,“ string2”}和指针

[英]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.

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