返回顶部
分享到

GNU C 手册 第十二章

科技 2023-1-2 13:44 375人浏览 0人回复
摘要

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字符码,以十进制数字表现。

'\a'  7       /* alarm, CTRL-g */'\b'  8       /* backspace, BS, CTRL-h */'\t'  9       /* tab, TAB, CTRL-i */'\n'  10      /* newline, CTRL-j */'\v'  11      /* vertical tab, CTRL-k */'\f'  12      /* formfeed, CTRL-l */'\r'  13      /* carriage return, RET, CTRL-m */'\e'  27      /* escape character, ESC, CTRL-[ */'\\'  92      /* backslash character, \ */'\''  39      /* singlequote character, ' */'\"'  34      /* doublequote character, " */'\?'  63      /* question mark, ? */

“\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
and break the line after them in the source code."

但是,串联是实行此操纵的推荐方法。

你也可以像这样写反常的字符串常量,

"Fo
o!"

但不要这样做 - 改为这样:

"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*。
数据类型wchar_t的宽度取决于目的平台,这使得这种宽字符串与较新类型相比没有多少用处。

char16_t和char32_t在头文件uchar.h中声明。wchar_t声明在stddef.h中。

雷同类型的连续宽字符串常量毗连在一起,就像普通字符串常量一样。宽字符串常量与普通字符串常量毗连会产生宽字符串常量。不能毗连两个不同类型的宽字符串常量。也不能将宽字符串常量(任何类型)与UTF-8字符串常量毗连起来。

本文暂无评论,快来抢沙发!

最新问答
天盟传媒网是一个由会员自行发布传媒的平台,一家集新闻稿发布平台,软文发稿平台,广告交易平台,媒体投放平台,为一体的全网媒体资源自助发布平台。尽一网在手,晓其所有!人人都是传媒者!。
  • 官方手机版

  • 微信公众号

  • 客户端下载