代码之家  ›  专栏  ›  技术社区  ›  STW

在c中,术语“原始”和“字面”是否可以互换?

  •  12
  • STW  · 技术社区  · 15 年前

    今天早些时候的一次讨论让我怀疑我对原语和文字的理解是否正确。


    我的理解是,文本类型是一种特定的类型,它可以使用一种表示法分配值,而不需要特定的类型声明,人和编译器都可以理解这种表示法:

    var firstName = "John"; // "John" is literal
    
    var firstName = (string)"John"; // *if* the compiler didn't understand that "John"
                                    // was a literal representation of a string then I
                                    // would have to direct it as such
    

    我对原语的理解是,它们本质上是编译器可以理解的基本数据类型,例如int:

    int age = 25;
    

    …文本可以是非基元的,例如VB9对XML文本的支持。一个非现实世界的例子是,如果System.Drawing.Point可以被指定为文本:

    Point somePoint = 2,2; // both X and Y are primitive values, however Point is a
                           // composite value comprised of two primitive values
    

    最后(这个问题反过来又让我问了上述问题): 我的理解是,类型是原始类型还是文本类型,与它是值类型还是引用类型没有直接关系。

    例如,System.String是支持文本的引用类型。自定义定义的结构是不支持文本的复合值类型。

    我的理解(如果不是我的解释)在很大程度上是正确的吗?


    更新: 感谢您提供的精彩信息和对话!对于任何发现这一点的人,一定要阅读评论和答案,这里有一些很好的澄清和一些有趣的旁注。

    顺便说一句:这是一个折中的问题,在哪一个答案真的值得得到绿色支票。我把它交给了不幸的被否决的答案,它不仅包含一个体面的答案,而且在评论中包含了大量的澄清和信息。公平地说,这里没有一个最好的答案,至少有三个:)

    8 回复  |  直到 10 年前
        1
  •  0
  •   JonH    15 年前

    我想有一件事你没有提到是空间和分配。基元是值类型,并在堆栈上分配(只要它们不与对象关联),除了您提到的字符串类型(字符串类在堆上分配其空间)。

    尽管对象本身包含基元,但实际对象的分配位置(位于堆中)存储在那里。

    另外,你的陈述写得很好。您是否有我遗漏的特定问题:)?

        2
  •  14
  •   Eric Lippert    15 年前

    我只是想在这里写个便条。

    C语言规范清楚地定义了“literal”——literal是 值的源代码表示法 . 文字是诸如“真”、“10”、“5.7”、“C”、“Hello”和“空”之类的东西——它们是 文本 代表一个 特定值 .

    C语言规范使用了两次“原始”这个词;它从来没有被定义过,并且对它可能的含义完全模糊。

    C语言规范不需要使用或定义单词“primitive”,因此不应该使用这个模糊的术语。我已经和MADS谈过了,我们已经同意对规范的未来版本进行修改,以完全消除这种用法。

    当然,其他类型系统规范——反射库、cli、ves等等——是如何定义单词“primitive”的。

    谢谢你提出这个问题。

        3
  •  3
  •   Matthias    15 年前

    我的理解(如果不是我的解释)在很大程度上是正确的吗?

    我不同意一点: 文字是某种编译时常量(如 "Hello World" , 5 'A' )但是,没有“文本类型”;文本始终是实际值。

    基本类型是imo“基本”类型,如string、int、double、float、short、…

    因此,原始文字的类型与它们相关。

        4
  •  3
  •   Jon Skeet    15 年前

    是的,文本是一个用源代码表示的值,所以虽然vb支持日期/时间和XML文本,但c不支持。

    根据C规范第2.4.4节:

    字面意义的 是源代码 值的表示。

    如您所说,这与值类型无关,而引用类型-字符串实际上是引用类型。

    一个还没有人提到的字面意思 null 顺便说一句。。。

    它也与原始类型无关-来自 Type.IsPrimitive :

    基元类型是布尔型、字节型、字节型和 sbyte,int16,uint16,int32,uint32, int64,uint64,intptr,uintptr,char,字符 双人房和单人房。

    …C规范实际上并没有定义“原始”类型的概念,但请注意 String 不在上面的列表中。

    字面意思是编译时间常数…在C中,每个文本都有一个可以直接烘焙到程序集中的表示;在VB中,额外的文本意味着它们不是clr理解的常量-不能 const DateTime 例如-但它们仍然是文字。

        5
  •  1
  •   mbeckish    15 年前

    Here 是一个关于cls的msdn页面,其中包括 一串 作为基元类型:

    .NET框架类库 包括与 编译器的基本数据类型 使用。在这些类型中,以下是 符合CLS:byte,int16,int32, int64、single、double、boolean、char、 decimal、intptr和string。为了更多 有关这些类型的信息,请参见 .NET框架类中的类型表 图书馆概况。

        6
  •  0
  •   JB King    15 年前

    别忘了这里也存在着 ASP.Net Literal class .

    编辑:因此,标题中的问题的答案是否,因为没有提供相同功能的“基本”类。不过,这可以被视为一种明智的ALEC回应。

        7
  •  0
  •   kvb    15 年前

    我认为你的理解基本上是正确的。正如Winsharp93所说,文本本身就是有类型的值,但没有“文本类型”这样的东西。也就是说,虽然可以使用字符串文本,但字符串不是“文本类型”。正如您所猜测的,定义一个文本的是直接在源代码中写下该值,尽管您不需要指定任何类型的要求似乎过于严格(例如f具有数组文本,并且可以推断数组文本的类型) [| 1; 2; 3 |] ,但不能必然推断空数组文本的类型 [| |] )

    不幸的是,我不认为对原始人的定义有一个一致的定义。当然,正如乔恩·斯基特所指出的,clr有自己的原始性定义。( Type.IsPrimitive ,排除了字符串。然而, other reputable sources 考虑 string 甚至 object 是C中的原始类型。我更喜欢这个定义,因为C中有内置的字符串支持,例如 + 用于连接和使用的运算符 == 作为值相等而不是引用相等,以及可以使用短格式引用字符串类型的事实 一串 而不是使用全名 System.String .

        8
  •  0
  •   Pragmateek    10 年前

    只需补充一点,还有另一种类型模糊了限制: System.Decimal 其值可以表示为 字面量 C.* 语言,但它不是 .NET基元类型 .

    IMHO 本原类型 可以简单地定义为在每个基础中直接“存在”的类型 平台/主机 :如果您已经使用汇编语言,您知道您有字节、字、双字…但你没有字符串或小数。

    的确 净小数 仿真 “由.NET运行时处理,而不是由只了解 IEEE 754 浮点数(浮点数和双精度数,然后是基元类型)。

    通过对文字值概念的扩展 “文字类型” 可以被视为其值可以直接用给定语言(C,VB.NET,CIL…)表示的任何类型。 有了这个定义,文字类型将是: 所有基元类型+字符串+小数 .