简体   繁体   English

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

[英]Why can't I declare and define a char-pointer variable to point to a char-array?

What's wrong with the initialization of s2 in the code below? 在下面的代码中初始化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;
}

I thought because I could initialize s1 the way I did above, the initialization of s2 should work fine as well. 我想,因为我可以像上面那样初始化s1s2的初始化也应该正常工作。

But this code leads to compile-time warnings as well as run-time segmentation fault. 但是这段代码会导致编译时警告以及运行时分段错误。

$ 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)

Yes, because {'f', 'o', 'o', '\\0'}; 是的,因为{'f', 'o', 'o', '\\0'}; is a brace-enclosed intializer list. 是一个括号封闭的初始化列表。 It cannot be used to initialize a pointer variable , in any way. 它不能以任何方式用于初始化指针变量 However, it can be used to initialize a char array, like 但是,它可以用于初始化char数组,例如

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

because arrays are not pointers . 因为数组不是指针

For your case, you can try using a compound literal instead as a workaround. 对于您的情况,您可以尝试使用复合文字作为变通方法。

Something like 就像是

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

Just to add some additional info, which can arise after reading this answer, like then why / how it is possible to initialize an array with string literal, like 只是添加一些额外的信息,这些信息可能在读完这个答案后出现,就像为什么/如何用字符串文字初始化一个数组,比如

  char s3[] = "Hello";

is possible, because as mentioned in C11 , chapter §6.7.9, initialization 是可能的,因为如C11第6章第9.7节所述, 初始化

An array of character type may be initialized by a character string literal or UTF−8 string literal, optionally enclosed in braces. 字符类型数组可以由字符串文字或UTF-8字符串文字初始化,可选地用大括号括起来。 Successive bytes of the string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array. 字符串文字的连续字节(如果有空间或数组大小未知,则包括终止空字符)初始化数组的元素。

A better question to ask is why you can initialize a pointer with a string literal, because inability to initialize a pointer using an array initializer should come as no surprise: after all, arrays are not pointers. 一个更好的问题是为什么你可以初始化一个带有字符串文字的指针,因为无法使用数组初始化程序初始化指针应该不足为奇:毕竟,数组不是指针。

String literals, however, are special. 但是,字符串文字是特殊的。 C lets you use them to initialize both arrays and pointers in order to provide a convenient syntax for creating null-terminated strings. C允许您使用它们来初始化数组和指针,以便为创建以null结尾的字符串提供方便的语法。 That is why your first syntax works with both an array of characters and a character pointer. 这就是为什么你的第一个语法适用于字符数组和字符指针。

Designated initializers {} initialize the data on the left of = . 指定的初始值设定项 {}初始化=左侧的数据。 For example 例如

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

initializes array of 6 integers, that is why each of elements in initializer list is integer. 初始化6个整数的数组,这就是初始化列表中每个元素都是整数的原因。

In your example of 在你的例子中

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

you would therefore attempt to initialize pointer to char with integer values of characters which is not what you wanted. 因此,您将尝试使用不是您想要的整数字符值初始化指向char的指针。 To initialize character array you can use 要初始化字符数组,您可以使用

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

syntax, or 语法,或

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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