C++ 入门(七)— 基本数据类型

Void

Void 是最容易解释的数据类型。void = 没有类型

不返回值的函数

最常见的是,void 用于指示函数不返回值:

void writeValue(int x) 
{
    std::cout << "The value of x is: " << x << '\n';
}

如果使用 return 语句尝试在此类函数中返回值,则会导致编译错误:

void noReturn(int x) // void here means no return value
{
    std::cout << "The value of x is: " << x << '\n';
    return 5; // error
}

已弃用:不采用参数的函数

在 C 语言中,void 用于指示函数不采用任何参数:

int getValue(void) // void here means no parameters
{
    int x{};
    std::cin >> x;

    return x;
}

但这种关键字 void 的使用在 C++ 中被视为已弃用。以下代码是等效的,在 C++ 中是首选的:

int getValue() // empty function parameters is an implicit void
{
    int x{};
    std::cin >> x;

    return x;
}

整数

有符号整数

整数是一种整数类型,可以表示正整数和负整数,包括 0(例如 -2、-1、0、1、2)。C++ 有 4 种主要基本整数类型可供使用:

类型最小范围注意
short int16 bits(位)
int16 bits(位)在现代架构上通常为 32 位
long int32 bits(位)
long long int64 bits(位)

定义有符号整数

short s;      // 用short代替short int
int i;
long l;       // 选择“long”而不是“long int”
long long ll; // 选择“long long”而不是“long long int”

整数类型还可以采用可选的 signed 关键字,但是,不应使用此关键字,因为它是多余的,因为默认情况下整数是有符号的。

有符号整数范围

类型范围
8 位有符号-128 ~ 127
16 位有符号-32,768 ~ 32,767
32 位有符号-2,147,483,648 ~ 2,147,483,647
64 位有符号-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807

无符号整数

要定义无符号整数,我们使用 unsigned 关键字。按照惯例,它放在以下类型之前:

unsigned short us;
unsigned int ui;
unsigned long ul;
unsigned long long ull;

无符号整数范围

类型范围
8 位有符号0 ~ 255
16 位有符号0 ~ 65,535
32 位有符号0 ~ 4,294,967,295
64 位有符号0 ~18,446,744,073,709,551,615

n 位无符号变量的范围为 0 0 0 ( 2 n ) − 1 (2^n)-1 (2n)1

应该避免使用无符号整数:

  • 首先,对于带符号值,需要做一些工作才能意外溢出范围的顶部或底部,因为这些值远非 0。对于无符号数字,溢出范围的底部要容易得多,因为范围的底部是 0,它接近我们大多数值的位置。
  • 其次,更隐蔽的是,当您混合有符号和无符号整数时,可能会导致意外行为。在 C++ 中,如果数学运算(例如算术或比较)有一个有符号整数和一个无符号整数,则有符号整数通常会转换为无符号整数。因此,结果将是无符号的。

固定宽度的整数和size_t

C99 定义了一组固定宽度的整数(在 stdint.h 标头中),这些整数保证在任何架构上都是相同的大小。

名称类型范围
std::int8_t1 byte signed-128 ~ 127
std::uint8_t1 byte unsigned0 ~ 255
std::int16_t2 byte signed-32,768 ~ 32,767
std::uint16_t2 byte unsigned0 ~ 65,535
std::int32_t4 byte signed-2,147,483,648 ~ 2,147,483,647
std::uint32_t4 byte unsigned0 ~ 4,294,967,295
std::int64_t8 byte signed-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
std::uint64_t8 byte unsigned0 ~ 18,446,744,073,709,551,615

C++ 正式采用这些固定宽度的整数作为 C++11 的一部分。可以通过包含标头来访问它们,标头在 std 命名空间中定义它们。下面是一个示例:

#include <cstdint> // for fixed-width integers
#include <iostream>

int main()
{
    std::int16_t i{5};
    std::cout << i << '\n';
    return 0;
}

_t 后缀
较新版本的 C++ 中定义的许多类型(例如 std::nullptr_t)都使用 _t 后缀。此后缀的意思是“类型”,它是应用于现代类型的常见命名法。
如果您看到带有 _t 后缀的内容,则它可能是一种类型。但许多类型没有_t后缀,因此这并不能始终如一地应用。

固定宽度的整数有两个缺点:

  • 首先,不能保证在所有体系结构上都定义固定宽度的整数。
  • 其次,如果使用固定宽度的整数,则在某些体系结构上,它可能比更宽的类型慢。

浮点数

有三种不同的浮点数据类型:float、double 和 long double。与整数一样,C++ 不定义这些类型的实际大小(但它保证最小大小)。

在现代架构上,浮点表示几乎总是遵循 IEEE 754 二进制格式(由 William Kahan 创建)。在这种格式中,浮点数为 4 个字节,double 为 8 个字节,长 double 可以等效于 double(8 字节)、80 位(通常填充为 12 个字节)或 16 个字节。

浮点数据类型始终是有符号的(可以保存正值和负值)。

类型最小尺寸常用尺寸
float4 bytes4 bytes
double8 bytes8 bytes
long double8 bytes8, 12, or 16 bytes

以下是浮点变量的一些定义:

float fValue;
double dValue;
long double ldValue;

使用浮点运算文本时,请始终至少包含一位小数(即使小数点为 0)。这有助于编译器了解该数字是浮点数而不是整数。

int x{5};      // 5 means integer
double y{5.0}; // 5.0 is a floating point literal (no suffix means double type by default)
float z{5.0f}; // 5.0 is a floating point literal, f suffix means float type

请注意,默认情况下,浮点文本默认为 double 类型。f 后缀用于表示 float 类型的文本。

浮点范围

IEEE 754 表示:
在这里插入图片描述
浮点精度

浮点类型的精度定义了它可以表示多少有效数字而不会丢失信息。

双精度值的精度在 15 到 18 位之间,大多数双精度值至少有 16 位有效数字。Long double 的最小精度为 15、18 或 33 位有效数字,具体取决于它占用的字节数。

浮点类型只能精确地表示一定数量的有效数字。使用有效位数多于最小值的值可能会导致值存储不准确。

NaN 和 Inf

浮点数有两个特殊类别:

  • 第一个是 Inf,它代表无穷大。Inf 可以是正数或负数。
  • 第二个是NaN,代表“不是数字”。

布尔值

布尔变量是只能有两个可能值的变量:true 和 false。

要声明布尔变量,我们使用关键字 bool。

bool b1 { true };
bool b2 { false };
b1 = false;
bool b3 {}; // default initialize to false

整数到布尔值的转换

使用整数初始化变量,初始化bool值:

#include <iostream>

int main()
{
	bool bFalse { 0 }; // okay: initialized to false
	bool bTrue  { 1 }; // okay: initialized to true
	bool bNo    { 2 }; // error: narrowing conversions disallowed

	std::cout << bFalse << bTrue << bNo << '\n';

	return 0;
}

在这里插入图片描述

上面在 bNo 初始化 2 时报错。

但是,整数可以转换为布尔值 :

#include <iostream>

int main()
{
	std::cout << std::boolalpha; // print bools as true or false

	bool b1 = 4 ; // copy initialization allows implicit conversion from int to bool
	std::cout << b1 << '\n';

	bool b2 = 0 ; // copy initialization allows implicit conversion from int to bool
	std::cout << b2 << '\n';


	return 0;
}

在这里插入图片描述

字符

char 数据类型设计为保存单个字符,可以是单个字母、数字、符号或空格。

char 数据类型是整数类型,这意味着基础值存储为整数。

初始化字符

可以使用字符文本初始化 char 变量:

char ch2{ 'a' }; // initialize with code point for 'a' (stored as integer 97) (preferred)

也可以使用整数初始化字符,但如果可能,应避免这样做

char ch1{ 97 }; // initialize with integer 97 ('a') (not preferred)

打印字符

#include <iostream>

int main()
{
    char ch1{ 'a' }; // (preferred)
    std::cout << ch1; // cout prints character 'a'

    char ch2{ 98 }; // code point for 'b' (not preferred)
    std::cout << ch2; // cout prints a character ('b')


    return 0;
}

在这里插入图片描述

字符大小、范围和默认符号

Char 由 C++ 定义为大小始终为 1 字节。

默认情况下,字符可以是有符号的,也可以是无符号的(尽管它通常是有符号的)。如果使用字符来保存 ASCII 字符,则无需指定符号(因为有符号和无符号字符都可以保存介于 0 和 127 之间的值)。

如果使用 char 来保存小整数(除非显式优化空间,否则不应这样做),则应始终指定它是有符号还是无符号。有符号的字符可以保存介于 -128 和 127 之间的数字。无符号字符可以保存 0 到 255 之间的数字。

将符号放在单引号和双引号中有什么区别

  • 单个字符总是放在单引号中:一个字符只能代表一个符号。
  • 双引号之间的文本:被视为多个字符的字符串。

类型转换

隐式类型转换

当编译器在没有我们明确询问的情况下代表我们进行类型转换时,我们称之为隐式类型转换。

#include <iostream>

void print(double x) // print takes a double parameter
{
	std::cout << x << '\n';
}

int main()
{
	print(5); // what happens when we pass an int value?

	return 0;
}

某些类型转换始终是安全的,而其他类型转换可能会导致在转换过程中更改值。不安全的隐式转换通常会生成编译器警告,或者(在大括号初始化的情况下)错误。

这是大括号初始化是首选初始化形式的主要原因之一。大括号初始化将确保我们不会尝试使用初始值设定项初始化变量,该变量在隐式类型转换时会丢失值:

int main()
{
    double d { 5 }; // okay: int to double is safe
    int x { 5.5 }; // error: double to int not safe

    return 0;
}

显式类型转换

通过 static_cast 运算符进行显式类型转换。

static_cast<new_type>(expression)

示例:

#include <iostream>

void print(int x)
{
	std::cout << x << '\n';
}

int main()
{
	print( static_cast<int>(5.5) ); // explicitly convert double value 5.5 to an int

	return 0;
}
  • 18
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值