双引号的属性

Posted

技术标签:

【中文标题】双引号的属性【英文标题】:Properties of double quotes 【发布时间】:2018-02-22 22:44:32 【问题描述】:

我想知道双引号有什么属性,尤其是在初始化 char 指针方面。

char *ptr="hello";
char array[6]='h','e','l','l','o';
cout<<ptr<<endl<<array<<endl;

上面的代码打印 hello 两次。我知道使用双引号表示一个字符串,或者一个末尾带有空字符的 char 数组。由于 ptr 正在寻找要分配的内存地址 (char*),因此我猜测“hello”解析为“h”的内存地址,尽管您还填写了 char 值阵列的其余部分?如果是这样的话,是不是意味着在上面的代码中

char *ptr="hello";

双引号在内存中的某处创建一个字符串,然后将ptr分配给该字符串的第一个元素,而

char array[6]='h','e','l','l','o';

在内存中的某处创建一个数组,然后根据赋值运算符的右侧为每个索引分配值?

【问题讨论】:

您需要打开编译器警告。 char *ptr="hello"; 应该警告你或者错误提示它是不允许的。 @NathanOliver:尽管考虑到 C 字符串文字不是 const(尽管修改内容是未定义的行为),char *ptr = "hello"; 在 C 中是合法的,并且许多编译器在 C++ 中允许它(如只要你不分配它)除非警告被提高到迂腐的水平。 @ShadowRanger 该问题未标记为 C,并且该转换在 C++03(近 15 年前)中已弃用,此后已正式从该语言中删除。 【参考方案1】:

这里有两点需要注意。

char array[6]='h','e','l','l','o';

这将在堆栈上分配 6 个字节并将它们初始化为“hello\0”;以下是等价的:

char array[] = "hello";
char array[6] = "hello";

但是,以下情况有所不同。

char *ptr="hello";

这将在堆栈上分配一个指针,该指针指向常量字符串“hello\0”。这是一个重要的区别,如果您更改 ptr 指向的值,您将导致未定义的行为,因为您将更改它指向的常量值。

例子:

#include <stdio.h>

void testLocal()

  char s[] = "local"; // locally allocated 6 bytes initialized to "local\0"
  s[0] = 'L';
  printf("%s\n", s);


void testPointer()

  char *s = "pointer"; // locally allocated pointer, pointing to a constant
  // This segfaults on my system, but really the behavior is undefined.
  s[0] = 'P';
  printf("%s\n", s);


int main(int argc, char * argv[])

  testLocal();
  testPointer();

【讨论】:

我很确定你错了。第一个数组只是一个数组,不需要以空值结尾。第二个不会编译,除非你把它改成char ptr[] = "foo";。这仅在 GCC 上作为扩展 AFAIK 编译。 @razzorflame,Geoffrey 对array 的看法是正确的。第六个元素初始化为0 是的,它被初始化为 0 但它不需要。 char 数组并不意味着总是以零结尾。 @razzorflame,是的,但在这种情况下,数组中有一个额外的元素,语言要求将其初始化为零。 好吧,忽略我对第一个数组的部分评论,他是对的。但是,在 C++ 中将字符串文字分配给 char* 是无效的。【参考方案2】:

对于字符串,有一个特殊的终端字符\0 添加到末尾。这告诉它这是字符串的结尾。

所以,如果你有一个字符串“hello”,它会继续读取每个字符:“h”、“e”、“l”、“l”、“o”、“\0”,它告诉它停下来。

字符数组类似,但没有那个终结符。相反,数组本身的长度表示要读取多少个字符(不一定适用于所有方法)。

【讨论】:

问题在于变量在内存中的分配位置,而不是字符串终止符如何工作。

以上是关于双引号的属性的主要内容,如果未能解决你的问题,请参考以下文章

JS:JSON的属性名必须要加双引号吗?

单引号和双引号一起作为 HTML 属性值?

如何在标题属性中转义双引号

json的对象属性必须加双引号吗

json的对象属性必须加双引号吗

单引号而不是双引号?