为什么我不能声明和定义一个char-pointer变量来指向char-array?

时间:2016-05-19 11:14:29

标签: c arrays pointers initialization

下面的代码中s2的初始化有什么问题?

#include <stdio.h>

int main()
{
  char *s1 = "foo";
  char *s2 = {'f', 'o', 'o', '\0'};

  printf("%c\n", s1[1]);
  printf("%c\n", s2[1]);
  return 0;
}

我想因为我可以按照上面的方式初始化s1s2的初始化也可以正常工作。

但是这段代码会导致编译时警告以及运行时分段错误。

$ gcc foo.c
foo.c: In function ‘main’:
foo.c:6: warning: initialization makes pointer from integer without a cast
foo.c:6: warning: excess elements in scalar initializer
foo.c:6: warning: (near initialization for ‘s2’)
foo.c:6: warning: excess elements in scalar initializer
foo.c:6: warning: (near initialization for ‘s2’)
foo.c:6: warning: excess elements in scalar initializer
foo.c:6: warning: (near initialization for ‘s2’)
$ ./a.out
o
Segmentation fault (core dumped)

3 个答案:

答案 0 :(得分:4)

是的,因为{'f', 'o', 'o', '\0'};是大括号括起的初始化列表。它不能用于以任何方式初始化指针变量。但是,它可用于初始化char数组,如

 char s2[] = {'f', 'o', 'o', '\0'};

因为 数组不是指针

对于您的情况,您可以尝试使用compound literal作为解决方法。

这样的东西
  char *s2 = (char []){'f', 'o', 'o', '\0'};

只是添加一些额外的信息,这些信息可能在阅读完这个答案后出现,就像为什么/如何用字符串文字初始化一个数组,比如

  char s3[] = "Hello";

是可能的,因为如C11中所述,章节§6.7.9,初始化

  

字符类型数组可以用字符串文字或UTF-8字符串初始化   文字,可选择括在括号中。字符串文字的连续字节(包括   如果有空间或数组的大小未知,则终止空字符)初始化   数组的元素。

答案 1 :(得分:4)

一个更好的问题是为什么你可以初始化一个带有字符串文字的指针,因为无法使用数组初始化程序初始化指针应该不足为奇:毕竟,数组不是指针。

然而,字符串文字是特殊的。 C允许您使用它们来初始化数组和指针,以便为创建以null结尾的字符串提供方便的语法。这就是为什么你的第一个语法适用于字符数组和字符指针。

答案 2 :(得分:1)

Designated initializers {}初始化=左侧的数据。例如

int a[6] = { 0, 0, 15, 0, 29, 0 };

初始化6个整数的数组,这就是初始化列表中每个元素都是整数的原因。

在你的

示例中
char *s2 = {'f', 'o', 'o', '\0'};

因此,您将尝试使用整数值字符初始化指向char的指针,这不是您想要的。要初始化字符数组,您可以使用

char s2[] = {'f', 'o', 'o', '\0'};

语法或

char s2[] = "foo"; /* also allowed in C, as dasblinkenlight noted - the better
                    * question would be why this works and Sourav Ghosh gave
                    * the answer */