Learning C++ 之 2.8 常量

本文介绍了C++中的文字常量,包括整型、布尔型、浮点型、字符型和字符串型常量的特点及使用方法。此外还讲解了如何使用后缀指定常量类型,以及如何使用不同进制(如八进制、十六进制)表示常量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++有两种常量:文字常量和符号常量。这篇我们讲文字常量。

文字常量:

文字常量(常被称为常量)是直接插入到代码中的值。他们是常量因此你不能更改他得值。

return 5; // 5 is an integer literal
bool myNameIsAlex = true; // true is a boolean literal
std::cout << 3.4; // 3.4 is a double literal

就像每个变量都有一个类型一样,常量也会有一个类型,通常是根据它的值来假定的。

Literal valueExamplesDefault type
integral value5, 0, -3int
boolean valuetrue, falsebool
floating point value3.4, -2.2double (not float)!
char value‘a’char
C-style string“Hello, world!”const char[14] (see chapter 6)

文字常量后缀

如果默认的类型不符合你的期望,你可以使用后缀:

Data TypeSuffixMeaning
intu or Uunsigned int
intl or Llong
intul, uL, Ul, UL, lu, lU, Lu, or LUunsigned long
intll or LLlong long
intull, uLL, Ull, ULL, llu, llU, LLu, or LLUunsigned long long
doublef or Ffloat
doublel or Llong double

一般来说对整型没有必要通过后缀来判断,但是也有一些例子:

unsigned int value1 = 5u; // 5 has type unsigned int
long value2 = 6L; // 6 has type long

一般来说浮点数常量默认类型是double,如果想要变成float类型,需要增加f后缀:

float f = 5.0f; // 5.0 has type float

新的程序员往往会困惑,为什么下面的程序并不按照期望的那样显示:

float f = 4.5;

这是因为4.5是没有后缀的,因此是double类型的,而不是float类型。当C++定义常量类型时,他不会关心你用常量做什么。因此你必须将4.5增加后缀,转换成float类型,这样会减小精度值。

C++也支持字符型常量:

std::cout << "Hello, world!" // "Hello, world!" is a C-style string literal
std::cout << "Hello," " world!" // C++ will concatenate sequential string literals

字符型常量在C++中处理起来非常奇怪。目前来说,将该常量作为输出std::out的参数是可以了。但是不能把它当作参数传递给函数。要么不会工作,要么不会想你期望的那样工作。后面我们会讨论C-style的字符串,以及怎么解决这些奇怪的问题。

只要意思明确,字符型常量是可以在C++中正常使用的,这往往会用在初始化一个值,进行数字运算,或者需要打印一个值的时候。

科学记数法的浮点类型

浮点常量的两种类型:

double pi = 3.14159; // 3.14159 is a double literal in standard notation
double avogadro = 6.02e23; // 6.02 x 10^23 is a double literal in scientific notation

当然第二种类型的指数可以是负数:

double electron = 1.6e-19; // charge on an electron is 1.6 x 10^-19

八进制和十六进制常量

在日常的生活中,我们的数字都是由:0,1,2,3,4,5,6,7,8,9组成的,我们叫做十进制数值。在这个系统中我们可以这样:0,1,2,3,4,5,6,7,8,9,10,11,12......通常来说,默认数值是10进制的。

int x = 12; // 12 is assumed to be a decimal number

在2进制中只有0和1,所有的数字都是0和1组成的:0,1,10,01,1010101等

在计算机中还有两种其他的进制类型:8进制和十六进制。

Decimal01234567891011
Octal0123456710111213

 如果要使用8进制,需要在前面增加一个0:

#include <iostream>
 
int main()
{
    int x = 012; // 0 before the number means this is octal
    std::cout << x;
    return 0;
}

输出为:10

8进制几乎不使用,建议忽略。下面是16进制的介绍;

Decimal01234567891011121314151617
Hexadecimal0123456789ABCDEF1011

 使用16进制需要在前缀增加0x

#include <iostream>
 
int main()
{
    int x = 0xF; // 0x before the number means this is hexadecimal
    std::cout << x;
    return 0;
}

输出是15

因为在16进制中我们有16个不同的值来表示,正好4bits。通常来说两个16进制的数就可以表示一个byte了。

考虑一个三十二位的整型数值:0011 1010 0111 1111 1001 1000 0010 0110。因为数字的重复和长度,非常难记和读。但是用16进制表示就是:3A7F 9826.这说明16进制在内存中是一种间接的计数方式。因此16进制往往会用来表示地址值和未处理的数据值。

在C++14之前,没有办法直接分配二级制的数据,因此16进制给我们提供了一种的方式:

#include <iostream>
 
int main()
{
    int bin(0);
    bin = 0x01; // assign binary 0000 0001 to the variable
    bin = 0x02; // assign binary 0000 0010 to the variable
    bin = 0x04; // assign binary 0000 0100 to the variable
    bin = 0x08; // assign binary 0000 1000 to the variable
    bin = 0x10; // assign binary 0001 0000 to the variable
    bin = 0x20; // assign binary 0010 0000 to the variable
    bin = 0x40; // assign binary 0100 0000 to the variable
    bin = 0x80; // assign binary 1000 0000 to the variable
    bin = 0xFF; // assign binary 1111 1111 to the variable
    bin = 0xB3; // assign binary 1011 0011 to the variable
    bin = 0xF770; // assign binary 1111 0111 0111 0000 to the variable
 
    return 0;
}

在C++14之后,可以用0b来表示:

#include <iostream>
 
int main()
{
    int bin(0);
    bin = 0b1;  // assign binary 0000 0001 to the variable
    bin = 0b11; // assign binary 0000 0011 to the variable
    bin = 0b1010; // assign binary 0000 1010 to the variable
    bin = 0b11110000; // assign binary 1111 0000 to the variable
 
    return 0;
}

 因为长整形非常难记,所以可以用'分开:

#include <iostream>
 
int main()
{
    int bin = 0b1011'0010;  // assign binary 1011 0010 to the variable
    long value = 2'132'673'462; // much easier to read than 2132673462
 
    return 0;
}

 幻数,为什么他们不好

考虑如下的小段:

int maxStudents = numClassrooms * 30;

像上面的30被称为幻数,幻数就是在一段代码中直接写死的数字,并且没有任何注释。30是什么意思?及时在这种情况下你可以猜到表示的是一个班级的最大数量,但是始终是不明确的。在更加复杂的情况下,你是没有办法猜到这个数字代表什么意思的,除非有注释。

使用幻数是一种非常差的体验,除了没有备注之外,值的修改也会非常麻烦。假设学校让购买课桌,而现在美分班级最大的认数变成了35,在程序里需要体现出来。考虑下面的情况:

int maxStudents = numClassrooms * 30;
setMax(30);

为了将程序中的size扩展到35,你需要更改。但是setMax中的30和这个30是否是同一个意思?这个setMax中的30需不需要更改?如果都是表示的班级人数,那么就应该一起修改;如果不是,那么需要保留。如果你是通过全部替换修改,那么setMax中的30也会被改变。如果一个个去查找验证的话,那么就需要花费大量的时间。这都是非常不好的习惯。

下一篇文章我们会学习怎么来很好地规避这个问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值