为什么字符串在C语言中被认为是标记,而数组却不是?

fzwojiic  于 2023-03-07  发布在  其他
关注(0)|答案(4)|浏览(109)

这是一个非常基本的理论问题。我开始学习C语言。我遇到了C语言中的令牌这个主题。
引用geeksforgeeks.org
标记是程序中对编译器有意义的最小元素。标记可分为以下几类:
1.关键词
1.标识符
1.常数
1.字符串
1.特殊符号
1.操作员
为什么字符串被认为是一个令牌,而数组不是?

dwthyt8l

dwthyt8l1#

Geeksforgeks几乎和ChatGPT一样是一个糟糕的学习来源。
的确,C语言中的字符串由以null结尾的字符数组组成,但它的意思是 * string literal *,"these things",也就是说,一个用于初始化字符数组或用作只读字符串的常量。
类似地,"constants"并不指const int x=1;这样的东西,而只是指数字部分1--这就是形式C在指 * 整型常量 * 时的含义(有时也称为"整型文字",尽管严格地说这个术语是不正确的)。
注意,标记是编写宏时最重要的一个概念,它不是初学者通常需要担心的概念。形式语法(C17 6.4),"词法元素",将C语言中的所有内容分为以下几组/子章节:

  • 关键词
  • 标识符
  • 通用字符名称
  • 常数
  • 字符串文字
  • 标点符号
  • 标题名称
  • 预处理编号
  • 评论
3bygqnnd

3bygqnnd2#

标记是不可分割的解析单元。

  • ;是一个令牌。
  • +是一个令牌。
  • ==是一个令牌。
  • 十进制数字文字4是一个标记。
  • 十进制数字文字12是一个标记。
  • 字符串文字"abc"是一个标记。
  • 标识符foo是一个令牌。
  • 标识符int是一个令牌。

但是,

  • 字符串不是令牌,因为字符串不是代码片段(但请参阅上面的string * literals *)。
  • 数组不是标记,因为数组不是代码片段。
  • 数组声明(例如int a[4];)不是标记,因为它们由多个其他标记组成。
  • 数组初始化器(例如{ 4, 5, i+2 })不是标记,因为它们是由多个其他标记组成的。

通常可以在标记之间放置空格,但不能在标记内部放置空格。

  • 121 2不同
  • "abc""a b c"不同。
  • foof o o不同。
  • i+2i + 2相同。
  • {4,5,i+2}{ 4, 5, i + 2 }相同。
sf6xfgos

sf6xfgos3#

当编译器处理源代码时,它首先将它们拆分为标记。

printf("%d", 4 << 2);

这将转换为以下令牌:

  • printf
  • (
  • "%d"-字符串文字
  • ,
  • 4
  • <<
  • 2
  • )
  • ;

int a[] = {1, 2, 3};这样的数组声明由多个标记组成,因此它本身不是一个标记,这里的a虽然是一个标记,但它不是一个特定的数组标记,更一般地说是一个标识符(“变量名”)。
关于printf()的附注:这个函数本身也会对它作为第一个参数接收到的字符串进行标记化,唯一的区别是一个字符是否是%占位符,所以它要简单得多,但原理是一样的。

syqv5f0l

syqv5f0l4#

直接查到源代码通常更好。C语言语法在C标准(C17)附录A中有半正式的描述。第一段(A.1.1)指出:

token:
      keyword
      identifier
      constant
      string-literal
      punctuator

注意,“字符串文字”是作为一个标记特别提到的。
至于原因:C语言是由与自然语言相同的层构建的:字母、单词和句子。当编译器读取一个程序文件时,它读取文件中的字符并将它们组合成记号,就像我们在阅读一本书时将字母组合成单词一样。然后,它将程序解释为记号序列,就像我们将文本解释为单词序列一样。
字符串文字作为标记只是C语言设计者的一个决定,因为它在描述语言的语法和语义时是有意义的。

相关问题