跳到主要内容

C 语言 - 常量

在 C 语言中,常量(Constants)是指程序在执行过程中不能改变的固定值。这些固定值也称为字面量(Literals)。常量可以是任何基本数据类型,例如整数常量、浮点常量、字符常量或字符串文字,以及枚举常量。

在使用时,常量可以直接在代码中使用,也可以通过定义常量来使用。通过定义创建的常量,其处理方式与变量基本一样,只是它们的值在定义后不能修改,换句话说,常量是只读的。

定义常量的方式

C 语言定义常量的方式有两种,一是使用 #define 宏定义,二是使用 const 关键字。

使用 #define 宏定义

使用 #define 可以在 C 程序中定义一个常量,#define 是一个预处理指令,也称为“宏定义”,因此它会在编译时被替换为其对应的值。

使用 #define 预处理器定义常量的语法如下:

#define identifier value

例如,下面代码定义了一个名为 PI(圆周率)的常量:

#define PI 3.1415926

注意:#define 宏定义末尾不需要添加分号 ;

使用 const 关键字

在定义变量时,使用 const 关键字可将其声明为只读变量,即常量,此后该变量的值在其生命周期将不能修改。

使用 const 关键字定义常量的语法如下:

const type variable = value;

例如,下面代码定义了一个名为 MAX_VALUE 的常量:

const int MAX_VALUE = 100;

值得一提的是,使用 const 定义常量时,必须在定义的时候初始化,因为常量不允许重新赋值。例如,下面的写法是错误的。

const int MAX_VALUE;
MAX_VALUE = 200;

整数常量

整数常量(Integer Literals)可以是十进制、十六进制、八进制或二进制的常量,默认为十进制整数,可通过前缀指定基数。例如,0x0X 表示十六进制,0 表示八进制,0b0B 表示二进制。不过,需要注意的是,并不是所有的 C 编译器都支持二进制数字,只有一部分编译器支持,并且和编译器的版本有关系。

下面列举几个不同进制的整数常量的例子:

256        /* decimal */
0567 /* octal */
0x4F /* hexadecimal */
0b1010 /* binary */

注意:不同进制的数字不能超过其进制限制,比如十六进制的数字范围是 0-9 以及 A-F,二进制数字只能是 0 和 1,否则会报错。例如 0b10020855 都是不允许的。

另外,整数常量也可以带一个后缀,后缀是 UL 的组合(可单独使用)。其中,U 表示无符号整数(unsigned),L 表示长整数(long)。后缀可以是大写,也可以是小写,其顺序任意。例如:

30         /* int */
30U /* unsigned int */
30L /* long */
30UL /* unsigned long */

通常,在使用 #define 定义整数常量时,如果这个整数很大,或者可能会参与很大的运算,那么建议加上后缀 L 防止数据溢出。例如:

#define SECONDS_PER_YEAR 31556926UL

浮点常量

浮点常量(Floating-point Literals)由整数部分、小数点、小数部分和指数部分组成。你可以使用小数形式或者指数形式来表示浮点常量。

  • 当使用小数形式表示时,必须包含整数部分、小数部分,或同时包含两者。
  • 当使用指数形式表示时,必须包含小数点、指数(使用 e 或 E 引入),或同时包含两者。

浮点常量可以带一个后缀,后缀是 FL,也可以是小写 fl。如果不带后缀,浮点常量的类型默认为 double,如果后缀是字母 fF,则常量的类型为 float。 如果后缀是字母 lL,则常量的类型为 long double

下面列举几个浮点常量的例子:

100.0         /* 合法的 */
-100.0f /* 合法的 */
3.1415926L /* 合法的 */
314159E-5 /* 合法的 */
314159E-5L /* 合法的 */
510E /* 非法的:不完整的指数 */
210f /* 非法的:没有小数或指数 */
.e55 /* 非法的:缺少整数或分数 */

字符常量

字符常量(Character Constants)就是一个个的字符,在 C 语言中由单引号包裹。例如,'x' 可以存储在 char 类型的简单变量中。

在 C 语言中,字符常量可以是一个普通的字符(例如 'x')、一个转义字符(例如 '\t'),或一个通用的字符(例如 '\u02C0')。转义字符是一些特定的字符,它们具有特殊的含义,使用反斜杠开头,例如换行符(\n)或制表符(\t)等,下表列出了一些常见的转义字符。

转义字符含义ASCII 码
\a响铃(BEL)007
\b退格(BS)008
\f换页(FF)012
\n换行(LF)010
\r回车(CR)013
\t水平制表(HT)009
\v垂直制表(VT)011
\\反斜杠092
\?问号字符063
\'单引号字符039
\"双引号字符034
\0空字符(NULL)000
\dddddd 表示三位八进制的任意字符
\xhhhh 表示二位十六进制的任意字符

下面通过一个简单的例子演示转义字符的用处。在该示例中,我们在字符串 Hello 后面添加一个制表符,在 World 后面添加了两个换行符。

#include <stdio.h>

int main(void)
{
printf("Hello\tWorld\n\n");
return 0;
}

编译并运行上述代码,输出结果如下:

$ ./a.out
Hello World

字符串常量

字符串常量(String Literals)使用双引号 " " 包裹。一个字符串包含字符常量的字符,包括普通的字符、转义序列和通用的字符。在字符串常量中,你可以使用空格做分隔符,把一个很长的字符串常量进行分行。

下面列举一些字符串常量的例子,这几种形式所显示的字符串是相同的。

// 第1种形式
"hello, dear"

// 第2种形式
"hello, \

dear"

// 第3种形式
"hello, " "d" "ear"

值得一提的是,字符串常量在内存中是以空字符 \0 结尾,因此其长度比你看到的字符长度要多1个字节。