对字符串常量和字符串变量感到困惑

时间:2018-11-10 12:24:05

标签: c arrays string

RelatedTerms

term.select('RelatedTerms > Term')

为什么不能修改* pm?

我看到有人说: char指针是地址的副本, char数组是内容的副本,即“ hello”。

我的问题是这个

  1. 为什么import json from bs4 import BeautifulSoup xml_file = './xml.xml' btree = BeautifulSoup(open(xml_file, 'r'), "xml") Terms = btree.select('Terms > Term') jsonObj = {"thesaurus": []} for term in Terms: termDetail = { "Description": term.find('Description').text, "Title": term.find('Title').text } RelatedTerms = term.select('RelatedTerms > Term') if RelatedTerms: termDetail["RelatedTerms"] = [] for rterm in RelatedTerms: termDetail["RelatedTerms"].append({ "Title": rterm.find('Title').text, "Relationship": rterm.find('Relationship').text }) jsonObj["thesaurus"].append(termDetail) print json.dumps(jsonObj, indent=4) 是内容的副本。
  2. m本身也是数组的第一个地址,为什么常量字符串“ hello”将它们分配给不同的效果?
  3. char m[] = "hello";char *pm = "hello";的语法糖;

2 个答案:

答案 0 :(得分:1)

char m[] = "hello";说:

  • 定义名为char的{​​{1}}数组。
  • 使用字符串文字m初始化数组。这与其他初始化有所不同。有一个从字符串文字中初始化字符数组的规则,该规则可从字符串文字中的字符初始化数组元素。
  • 根据字符串文字的大小(包括终止的空字符)设置数组的大小。
  • 最终结果是一个数组"hello",您可以对其进行修改。

m说:

  • 定义一个名为char *pm = "hello";的指向char的指针。
  • 使用字符串文字pm初始化指针。由于它不是要初始化的字符数组,因此不适用于字符数组的规则。相反,"hello"是一个表达式。由于字符串文字本身就是数组,因此适用将数组转换为指针的规则。因此"hello"被转换为指向其第一个字符的指针。然后"hello"被初始化为该指针的值。
  • 最终结果是pm指向字符串文字的数组,您不能对其进行修改。

关于您的问题:

  

m本身也是数组的第一个地址,为什么常量字符串“ hello”将它们分配给不同的效果?

首先,数组的名称不是数组的第一个元素的地址。在许多情况下,它实际上是那样的,但是存在差异。在表达式中使用数组时,会将数组自动转换为指向其第一个元素的指针,但如果它是pm或一元sizeof的操作数,则不会。 (如果它是用于初始化数组的字符串文字,则也不是。)因此,在&中,sizeof m不是指向其第一个元素的指针。它是整个数组,m产生整个数组的大小,而不是指针的大小。

第二,将sizeof m用作初始化程序会产生不同的效果,这是因为有关使用字符串文字初始化数组的规则。具体来说,该规则在C 2018 6.7.9 14中表示:

  

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

第三,在这些定义中未分配字符串文字。它用于初始化对象。分配和初始化不同,并且具有不同的规则。分配是表达式,其行为与其他表达式非常相似。初始化是声明的一部分,并且具有一些赋值所没有的特殊语法和语义。这就是为什么某些源代码的初始化行为与赋值行为不同的原因。

关于这个问题:

  

"hello"char m[] = {'h','e','l','l','0'};的语法糖吗

反之亦然;我们可以说char m[] = "hello";是较甜的版本,而char m[] = "hello";是原始版本。但是,是的,它们具有相同的效果。 (请注意,我纠正了两个错误:列表中应该有一个char m[] = {'h','e','l','l','o',0};,最后一个元素应该是'o',而不是0'0'是数字的字符,则'0'为零,这是空字符。)

答案 1 :(得分:0)

  

为什么char m [] =“ hello”;内容的副本。

这是数组初始化语法。编译器将为字符数组分配足够的新内存,然后将字符串 literal 的内容(与字符串 constant 不同)复制到其中。

  

m本身也是数组的第一个地址,为什么常量字符串>“ hello”会将它们分配给不同的效果?

仅使用数组名称来获得&m [0]的等效项只是编译器的方便。我们还说,仅按名称使用时,数组会“衰减”到指向第一个元素的指针中。

使用char * pm =“ Hello”时;那不是初始化,而是分配。您将字符串常量“ Hello”的地址分配给指针pm。字符串常量存储在其他存储段中,通常为只读

  

是char m [] = {'h','e','l','l','0'}; char m [] =“ hello”的语法糖;

不。第一个版本将不包含终止的空字符。