12 常量常量是通过显式表现所需值来代表特定值的表达式。C 答应数字、字符和字符串使用常量。我们已经在示例中看到了数字和字符串常量。12.1 整数常量整数常量由指定值的数字组成,后跟用于指定命据类型的后缀字母(
12 常量常量是通过显式表现所需值来代表特定值的表达式。C 答应数字、字符和字符串使用常量。我们已经在示例中看到了数字和字符串常量。 12.1 整数常量整数常量由指定值的数字组成,后跟用于指定命据类型的后缀字母(可选)组成。 最简单的整数常量是10十进制数,如5、77和403。十进制常量不能以字符“0”(零)开头,因为那是八进制常量。 通过在开头加上减号可以得到负整数常数的结果。从语法上讲,这是一个算术表达式,而不是常量,但它的举动就像一个真正的常量。 整数常量也可以写成八进制(基数 8)、十六进制(基数 16)或二进制(基数 2)。八进制常量以字符“”(零)开头,后跟任意数量的八进制数字(“”到“”):007 整数常量也可以是八进制(以8为基数)、十六进制(以16为基数)或二进制(以2为基数)。八进制常量以字符“0”(零)开头,后跟任意数量的八进制数字(“0”到“7”): 0 // zero 077 // 63 0403 // 259 学究式地说,常数0是一个八进制常数,但我们可以将其视为十进制;无论哪种方式,它都具有雷同的值。 十六进制常量以“0x”(大写或小写)开头,后跟十六进制数字(“0”至“9”,以及大写或小写的“A”至“f”): 0xff // 255 0XA0 // 160 0xffFF // 65535 二进制常量以“0b”(大写或小写)开头,后跟位(每个位由字符“0”或“1”表现): 0b101 // 5 二进制常量是GNU C扩展,不是C标准的一部门。 有时,整数常量后面需要一个空格,以避免与以下标记的词法肴杂。 12.2 整数常量数据类型整型常量的类型通常为int,假如值得当该类型,但以下是完整的规则。整数常数的类型是该序列中可以或许正确表现值的第一个, int unsigned int long int unsigned long int long long int unsigned long long int 以下规则不排除这一点。 假如常量以“l”或“l”作为后缀,则不包括前两种类型(non-long)。 假如常量以“ll”或“ll”作为后缀,则不包括前四种类型((non-long long)。 假如常量以“u”或“u”作为后缀,则不包括有符号类型。 否则,假如常量为十进制,则排除无符号类型。 以下是后缀的一些示例。 3000000000u // three billion as unsigned int. 0LL // zero as a long long int. 0403l // 259 as a long int. 很少使用整数常量中的后缀。当精确类型很紧张时,显式转换会更清晰。 12.3 浮点常量浮点常量必须具有小数点、十的指数或两者;它们将其与整数常数区分开来。 要表现指数,请写“e”或“e”。指数值如下。它总是写为十进制数;它可以选择以符号开始。指数n表现将常数的值乘以10的n次方。 因此,“1500.0”、“15e2”、“15e+2”、“15.0e2”、“1.5e+3”等。“15e4”和“15000e-1”是1500的六种浮点数写法。它们都是等价的。 以下是更多小数点的示例: 1.0 1000. 3.14159 .05 .0005 对于它们中的每一个,下面是一些用指数编写的等效常量: 1e0, 1.0000e0 100e1, 100e+1, 100E+1, 1e3, 10000e-1 3.14159e0 5e-2, .0005e+2, 5E-2, .0005E2 .05e-2 浮点常量通常具有double类型。您可以通过在末端添加“f”或“f”来强制它键入float。比方 3.14159f 3.14159e0f 1000.f 100E1F .0005f .05e-2f 同样,末端的“l”或“l”强制常量为类型long double。 您可以在十六进制浮点常量中使用指数,但由于“e”将被表明为十六进制数字,因此字符“p”或“p”(表现“幂”)表现指数。 十六进制浮点常量中的指数是一个大概有符号的十进制整数,指定2的幂(不是10或16)乘以数字。 以下是一些示例: 0xAp2 // 40 in decimal 0xAp-1 // 5 in decimal 0x2.0Bp4 // 16.75 decimal 0xE.2p3 // 121 decimal 0x123.ABCp0 // 291.6708984375 in decimal 0x123.ABCp4 // 4666.734375 in decimal 0x100p-8 // 1 0x10p-4 // 1 0x1p+4 // 16 0x1p+8 // 256 12.4 虚数常量复数由实部和虚部组成(其中一部门或两部门大概为零)。本节说明如何使用虚值写数字常量。通过将这些添加到普通的数值常量中,我们可以得到复数常量。 编写虚数常量的简单方法是将后缀“i”或“i”,或“j”或“j”,附加到整数或浮点常量。比方,2.5fi具有_Complex float类型,3i具有_ Complex int类型。四个可选后缀字母都是等效的。 写虚常数的另一种方法是将实常数乘以_Complex_I,它表现虚数I。标准C不支持以“I”或“j”作为后缀,因此需要这种笨拙的方法。 要编写一个包罗非零实部和非零虚部的复常量,请分别编写这两个常量并添加它们,如下所示: 4.0 + 3.0i 这给出了值4+3i,类型为_Complex double。 这样的和可以包括多个实常量,也可以不包罗。同样,它可以包括多个虚常量,也可以不包罗。比方: _Complex double foo, bar, quux; foo = 2.0i + 4.0 + 3.0i; /* Imaginary part is 5.0. */ bar = 4.0 + 12.0; / Imaginary part is 0.0. */ quux = 3.0i + 15.0i; / Real part is 0.0. */ 12.5 无效号码一些在预处置惩罚指令中被视为数字的构造实际上不是有效的数字常量。假如这些构造出如今预处置惩罚之外,则它们是错误的。 有时我们需要插入空格来分隔标记,这样它们就不会被组合成单个雷同数字的结构。比方,0xE+12是一个预处置惩罚数,它不是有效的数值常量,因此是一个语法错误。假如我们想要的是三个标记0xE + 12,我们必须使用这些空格作为分隔符。 12.6 字符常量字符常量是用单引号编写的,如 中所示。在最简单的情况下, 是常量应表现的单个 ASCII 字符。常量的类型为 ,其值是该字符的字符代码。比方, 表现字母“”的字符代码:97,即。'c'cint'a'a 字符常量用单引号书写,如'c'。在最简单的情况下,c应该表现的单个ASCII字符。常量的类型为int,其值为该字符的字符代码。比方,'a'表现字母“a”的字符代码,即,97。 若要将“'”字符(单引号)作为字符常量,请使用反斜杠(“\”)将其引用。此字符常量看起来像'''。这种以“\”开头的序列称为转义序列。这里的反斜杠字符用作一种转义字符。 要将“”字符(反斜杠)放在字符常量中,请用“”(另一个反斜杠)同样引用它。此字符常量看起来像 。\'\' 要将“\”字符(反斜杠)作为字符常量,请用“\”(另一个反斜杠)。此字符常量看起来像'\'。 以下是表现字符常量中特定字符的全部转义序列。表现的数值是相应的ASCII字符码,以十进制数字表现。
“\e”是GNU C扩展;要遵照标准C,使用“\33”。 您还可以将八进制和十六进制字符代码写为“”或“”。十进制在这里不是一个选项,因此八进制代码不需要以''开头。\octalcode\xhexcode0 您还可以将八进制和十六进制字符代码编写为“\octalcode”或“\xhexcode”。十进制在这里不是一个选项,因此八进制代码不需要以“0”开头。 字符常量的值具有int类型。但是,字符代码最初被视为char值,然后转换为int。假如字符代码大于127(八进制中的0177),则在char类型为8位长且有符号的平台上,结果int大概为负数。 12.7 字符串常量字符串常量表现一系列字符。它以“”开头,以“”末端;介于两者之间的是字符串的内容。在内容中引用特殊字符(如“”,“”和换行符)在字符串常量中与字符常量一样有效。在字符串常量中,“”不需要用引号引起来。"""' 字符串常量表现一系列字符。它以“开头,以”末端;中间是字符串的内容。在字符串中引用特殊字符,如 '、“\”和换行符与在字符常量中一样。在字符串常数中,不需要引用“'”。 字符串常量界说一个字符数组,其中包罗指定的字符,后跟空字符(代码0)。使用字符串常量相当于使用包罗这些内容的数组的名称。在简单情况下,字符串常量的长度(以字节为单位)比写入其中的字符数大 1。 与C中的任何数组一样,在表达式中使用字符串常量会将数组转换为指向数组第一个元素的指针。该指针将具有char *类型,因为它指向char类型的元素。char *是指针类型的类型指示符示例。该类型通常用于字符串,而不仅仅是步伐中表现为常量的字符串。 因此,字符串常量“Foo!”几乎相当于这样声明一个数组 char string_array_1[] = {'F', 'o', 'o', '!', '\0' }; 然后在步伐中使用string_ array_。然而,有两个区别:
字符串常量的文本中不答应使用换行符。此克制的动机是捕捉省略”的错误。要在常量字符串中放置换行符,请在字符串常量中将其写为“\n”。 字符串常量内的源代码中的实际空字符会导致警告。若要在字符串常量的中间放置空字符,使用“\0”或“\000”。 连续的字符串常量被有效地串联。因此 "Fo" "o!" is equivalent to "Foo!" 这对于编写包罗多行的字符串很有用,如下所示: "This message is so long that it needs more than\n" "a single line of text. C does not allow a newline\n" "to represent itself in a string constant, so we have to\n" "write \n to put it in the string. For readability of\n" "the source code, it is advisable to put line breaks in\n" "the source where they occur in the contents of the\n" "constant.\n" 反斜杠和换行的序列在C步伐中的任何位置都被忽略,并且包括在字符串常量中。因此,您可以这样编写多行字符串常量: "This is another way to put newlines in a string constant\n 但是,串联是实行此操纵的推荐方法。 你也可以像这样写反常的字符串常量, "Fo 但不要这样做 - 改为这样: "Foo!" 请留意避免将字符串常量传递给修改其接收的字符串的函数。存储字符串常量的存储器大概是只读的,这将导致通常制止函数的致命信号(请参阅信号。更糟糕的是,内存大概不是只读的。然后,该函数大概会修改字符串常量,从而破坏其他字符串常量的内容,这些字符串常量应该包罗雷同的值并由编译器统一。SIGSEGV 小心避免将字符串常量传递给那些会修改其接收到的字符串的函数。存储字符串常量的内存大概是只读的,这将导致致命的SIGSEGV信号,该信号通常会制止函数(请参阅信号)。更糟糕的是,内存大概不是只读的。然后函数大概会修改字符串常量,从而破坏其他字符串常量的内容,这些字符串常量本应包罗雷同的值,并由编译器统一成一体。 12.8 UTF-8 字符串常量紧挨着字符串常量之前写入“u8”,中间没有空格,意味着以UTF-8编码将该字符串表现为字节序列。UTF-8使用单个字节来描述ASCII字符,并将非ASCII Unicode字符(代码128及以上)表现为多字节序列。以下是UTF-8常量的示例: u8"A cónstàt" 该常量占用13字节加上制止的null,因为每个重音字母都是一个双字节序列。 从概念上讲,将普通字符串与UTF-8字符串毗连会生成另一个UTF-8字符串。但是,假如普通字符串包罗字符代码128及更高,则不能依靠结果。 12.9 Unicode字符码可以使用转义序列为单个字符常量指定 Unicode 字符或作为字符串常量的一部门(请参阅字符串常量)。将“”转义序列与 16 位十六进制 Unicode 字符代码一起使用。假如代码值对于 16 位来说太大,请使用带有 32 位十六进制 Unicode 字符代码的“”转义序列。(这些代码称为通用字符名称。比方\u\U 可以使用转义序列为单个字符常量或作为字符串常量的一部门指定Unicode字符。将“\u”转义序列与16位十六进制Unicode字符代码一起使用。假如代码值对于16位来说太大,请使用32位十六进制Unicode字符代码的“\U”转义序列。比方, \u6C34 /* 16-bit code (UTF-16) */ \U0010ABCD / 32-bit code (UTF-32) */ 使用这些的一种方法是使用UTF-8字符串常量。比方 u8"fóó \u6C34 \U0010ABCD" 您还可以在宽字符常量中使用它们,如下所示: u'\u6C34' /* 16-bit code */ U'\U0010ABCD' / 32-bit code */ 和宽字符串常量,如下所示: u"\u6C34\u6C33" /* 16-bit code */ U"\U0010ABCD" / 32-bit code */ D800到DFFF范围内的代码在Unicode中无效。小于00A0的代码也是被克制的,除了0024 、0040和0060外, 这些字符实际上是ASCII控制字符,您可以使用其他转义序列指定它们。 12.10 宽字符常量宽字符常量表现字符代码超过8位的字符。这是一个我们需要记录的含糊功能,但您大概永久不会使用它。假如你只是在学习C语言,你不妨跳过这一节。 原始的C宽字符常量看起来像“L”(大写!)紧接着一个普通字符常量(没有中间空格)。其数据类型为wchar_t,是界说在stddef.h中的,其中一个标准整数类型的别名。根据平台的不同,它可以是16位或32位。假如是16位,这些字符常量使用UTF-16形式的Unicode;假如是32位,则为UTF-32。 还有一些Unicode宽字符常量,它们显式指定宽度。这些常量以“u”或“U”而不是“L”开头。“u”指定16位Unicode宽字符常量,“U”指定32位Unicode宽度字符常量。它们的类型分别为char16_t和char32_t;它们在头文件uchar.h中声明。这些字符常量也是有效的,即使没有#include uchar.h,但假如不包括它来声明这些类型名称,它们的某些使用大概会很不方便。 宽字符常量中表现的字符可以是普通ASCII字符。L'a',u'a'和u'a'都是有效的,它们都即是'a'。 在全部三种宽字符常量中,可以在常量自己中写入非ASCII Unicode字符;常量的值是字符的Unicode字符代码。或者可以使用转义序列指定Unicode字符。 12.11 宽字符串常量宽字符串常量表现16位或32位字符的数组。它们很少使用;假如你只是在学习C语言,你不妨跳过这一节。 有三种宽字符串常量,它们在用于字符串中每个字符的数据类型上有所不同。每个宽字符串常量相当于一个整数数组,但这些整数的数据类型取决于宽字符串的类型。在表达式中使用常量会将数组转换为指向其第一个元素的指针,就像C中的数组一样。对于每种宽字符串常量,我们在下面说明该指针的类型。 char16_t 这是一个16位Unicode宽字符串常量:每个元素都是一个类型为char16_t的16位Unicode字符代码,因此该字符串的指针类型为char16_t*。(这是一个类型指示符;参见指针类型指示符。)常量被写为“u”(必须小写),后跟(没有中间空格)一个字符串常量,使用通常的语法。 char32_t 这是一个32位Unicode宽字符串常量:每个元素都是32位的Unicode字符代码,字符串的类型为char32_t*。它写为“U”(必须是大写),后面(没有中间空格)是一个字符串常量,使用通常的语法。 wchar_t 这是宽字符串常量的原始类型。它被写为“L”(必须是大写),后面(没有中间空格)是一个具有通常语法的字符串常量,字符串的类型为wchar_t*。 char16_t和char32_t在头文件uchar.h中声明。wchar_t声明在stddef.h中。 雷同类型的连续宽字符串常量毗连在一起,就像普通字符串常量一样。宽字符串常量与普通字符串常量毗连会产生宽字符串常量。不能毗连两个不同类型的宽字符串常量。也不能将宽字符串常量(任何类型)与UTF-8字符串常量毗连起来。 |
2022-08-07
2022-08-02
2022-08-02
2022-08-01
2022-08-06
评论