【C++基础知识】基本内置类型

基本内置类型

算术类型

C++是一种静态数据类型语言,它的类型检查发生在编译时。因此,编译器必须知道每个变量对应的数据类型

那么,C++中哪些数据类型呢?

C++定义了一套包括算术类型空类型(void)在内的基本数据类型。

基本算术类型可以分为整型、浮点型、字符型、布尔值。

详见下表:

在这里插入图片描述

注意: 使用 sizeof关键字——可以统计数据类型/对象所占的内存大小。

需要关注的点:

  • 有符号和无符号

有符号数(signed)是可以用来区分数值的正负。而无符号数(unsigned)仅有正值,没有负值。

当一个数是有符号数时,此时的最高位称为符号位符号位为 1 时表示负数,为 0 时则表示正数。

有符号数和无符号数两者表示的范围不同,即同样长度的字节,有符号数比无符号数的最大值出现缩水。

  • 单、双精度浮点数类型

    float可以表示大约 7 位有效数字;double可以表示大约 15 位有效数字。

    如果计算需要高精度,或者需要处理极大或极小的数值范围,那么 double 可能更合适。

    然而,如果内存占用是一个重要因素,或者精度要求不是很高,那么 float 可能是一个更经济的选择。

  • 字符型和字符串型

在 c 和 c++ 中,字符型变量占 1 字节。

char str[] = "hello world";
cout << sizeof(str) << endl;  // 输出 12,因为编译器会在字符串结尾处添加一个空字符('\0')
#include<string>
string str = "hello world";
cout << sizeof(str) << endl;  // 输出 40(32位下是28个字节、64位下是40个字节)

上面例子中,sizeof(str)输出 40,这与string的内存分布相关。

  • 宽字符

在 ASCII 字符编码中,每个字符由一个单字节(8位)表示。然而,这种编码无法表示许多非英语语言的字符,比如各种非拉丁文字(如中文、日文、阿拉伯文)或带有重音的字母。

宽字符wchar_t 通过使用多个字节来表示单个字符,来处理这种情况。

#include <iostream>
#include <locale> // 包含头文件以设置本地化

int main() {
  // 设置本地化以支持宽字符输出
  std::locale::global(std::locale(""));

  wchar_t wideChar[] = L"こんにちは"; // 一个日语问候
  std::wcout << wideChar << std::endl;

  return 0;
}

注意:wchar_t 的确切大小取决于编译器和系统,但通常大于一个字节,常见的大小为 2 或 4 字节。

为了解决这个问题,C++11引入了 <uchar.h> 头文件,并定义了 char16_tchar32_t 类型,分别用于表示 16位 和 32位 的 Unicode 字符。这些类型的大小是固定的,分别为 2 字节和 4 字节,从而提供了更可靠的方法来处理 Unicode 字符,而不会受到不同实现之间的差异影响。

重识“类型转换”

类型转换我们已经足够熟悉了,所以在这里讲些可能不被人们熟悉的知识,以及强调几个问题。

static_cast 显式转换

static_cast 用于基本类型之间的转换,可以执行多种类型转换,但在安全性上比C风格转换更好。

double doubleValue = 3.14;
int intValue1 = (int)doubleValue; // C风格强制转换
int intValue2 = static_cast<int>(doubleValue); // 使用static_cast进行转换

问题 1:精度损失

当我们把一个整数值赋给浮点类型时,小数部分记为 0。

但是如果该整数所占的空间超过了浮点类型的容量,精度可能有损失。

#include <iostream>

int main() {
  int intValue = 1234567890; // 一个大整数
  double doubleValue = intValue;

  std::cout << "Integer value: " << intValue << std::endl;
  std::cout << "Double value: " << doubleValue << std::endl;

  return 0;
}
Integer value: 1234567890
Double value: 1.23457e+09     //精度损失

即使我们使用了双精度浮点数(double),它具有更多的位数,可以提供更高的精度。但只要超过一定范围的整数也可能在浮点数中存在精度损失的问题。

问题 2:数值越界

**情况一:**赋给无符号类型一个超出它表示范围的值时,结果是初始值对无符号类型表示数值总数取模后的余数。

例如,8 比特大小的 unsigned char 可以表示 0 至 255 区间内的值,如果我们给它赋值 -1,则实际的结果是该值对 256 取模后所得的余数。因此,把 -1 赋给 8 比特大小的 unsigned char 所得的结果是255。

**情况二:**赋给带符号类型一个超出它表示范围的值时,结果是未定义的。此时,程序可能继续工作、可能崩溃,也可能生成垃圾数据。

问题 3:带无符号类型的表达式

尽管我们不会故意给无符号对象赋一个负值,却可能(特别容易)写出这么做的代码。

unsigned u = 10;
int i = -42;
std::cout << i + i << std::endl;    // 输出-84
std::cout << i + u << std::endl;    // 输出4294967264

unsigned u1 = 20, u2 = 10;
std::cout << u1 - u2 << std::endl;  // 输出10
std::cout << u2 - u1 << std::endl;  // 输出4294967286

我们可以看到,当表达式里面既有带符号类型又有无符号类型时,带符号类型会自动转换为无符号类型。

因此,切勿混用带符号类型和无符号类型

字面值常量

一个形如 42 的值被称作字面值常量(iteral),这样的值一望而知。每个字面值常量都对应一种数据类型,字面值常量的形式和值决定了它的数据类型。

整型和浮点型字面值

我们可以将将整型字面值写作十进制、八进制或十六进制。

20  /* 十进制 */                024  /* 八进制 */                0x14  /* 十六进制 */

浮点型字面值表现为一个小数以科学计数法表示的指数,其中指数部分用 E 或 e 标识。

3.1415926         0.         .001         1.6e+05         0e0

默认的,浮点型字面值是一个double

字符和字符串字面值

由单引号括起来的一个字符称为char型字面值,双引号括起来的零个或多个字符则构成字符串型字面值。

'a'    //字符字面值
"Hello World!"  //宇符串宇面值

字符串字面值的类型实际上是由常量字符构成的数组(array)。编译器会在字符串结尾处添加一个空字符('\0'),因此,字符串字面值的实际长度要比它的内容多 1。

如果两个字符串字面值位置紧邻且仅由空格、缩进 和 换行符 分隔,则它们实际上是一个整体。当书写的字符串字面值比较长,写在一行里不太合适时,就可以采取分开书写的方式:

std::cout « "a really, really long string literal "
          "that spans two lines" << std::endl;

布尔字面值和指针字面值

true 和 false 是布尔类型的字面值;

nullptr 是指针的字面值。

转义序列

作用: 用于表示一些不能显示出来的 ASCII 字符。

在这里插入图片描述

制表符\t : 与前面的字符一共占8个空格,使输出格式整齐。

指定字面值类型

可以通过添加前缀或后缀的形式,改变整型、浮点型和字符型字面值的默认类型。

L'a'        // 宽字符型字面值,类型是 wchar_t
u8"hi!"     // utf-8 字符串字面值(utf-8用8位编码一个Unicode字符)
42ULL       // 无符号整型字面值,类型是 unsigned long long
1E-3F       // 单精度浮点型字面值,类型是 float
3.14159L    // 扩展精度浮点型字面值,类型是 long double
  • 字符和字符串字面值
前缀含义类型
uUnicode 16 字符char16_t
UUnicode 32 字符char32_t
L宽字符wchar_t
u8UTF-8(仅用于字符串字面值)char
  • 整型字面值
后缀最小匹配类型
u or Uunsigned
l or Llong
ll or LLlong long
  • 浮点型字面值
后缀类型
f 或 Ffloat
l 或 Llong double
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Skylar Lin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值