C++(一):基本数据类型

妖狐艹你老母 2024-03-18 00:22 151阅读 0赞

基本数据类型

    • 基本内置类型
    • 定义变量
      • `type field = value;`
      • `type field(value);`
      • `type field{value};`
      • `type field = {value};`
    • 数学常量及函数
    • 静态类型转换 `static_cast`
    • 格式化字符串
      • `std::stringstream`
      • `std::string`
      • 引入三方库 `fmt/core.h`
    • 字符运算
    • `auto` 关键字
    • 枚举类型
    • 数据类型定义别名
    • 判断是否为NaN
    • 三向比较运算符(太空飞船运算符)
    • 多维数组
    • 避免幻数
    • 运行期间为数组分配内存空间
    • 数组的替代品
      • `std::array`
      • `std::vector`

基本内置类型

在这里插入图片描述

  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. cout << "数据类型" << "\t\t" << "所占字节" << "\t" << "最小值" << "\t\t\t" << "最大值" << endl;
  5. cout << "bool(布尔型)" << "\t\t" << sizeof(bool) << "\t\t" << numeric_limits<bool>::min() << "\t\t\t" << numeric_limits<bool>::max() << endl;
  6. cout << "char(字符型)" << "\t\t" << sizeof(char) << "\t\t" << numeric_limits<char>::min() << "\t\t\t" << numeric_limits<char>::max() << endl;
  7. cout << "unsigned char" << "\t\t" << sizeof(unsigned char) << "\t" << numeric_limits<unsigned char>::min() << "\t" << numeric_limits<unsigned char>::max() << endl;
  8. cout << "signed char" << "\t\t" << sizeof(signed char) << "\t\t" << numeric_limits<signed char>::min() << "\t\t\t" << numeric_limits<signed char>::max() << endl;
  9. cout << "int(整型)" << "\t\t" << sizeof(int) << "\t\t" << numeric_limits<int>::min() << "\t\t" << numeric_limits<int>::max() << endl;
  10. cout << "unsigned int" << "\t\t" << sizeof(unsigned int) << "\t\t" << numeric_limits<unsigned int>::min() << "\t\t\t" << numeric_limits<unsigned int>::min() << endl;
  11. cout << "signed int" << "\t\t" << sizeof(signed int) << "\t\t" << numeric_limits<signed int>::min() << "\t\t" << numeric_limits<signed int>::max() << endl;
  12. cout << "short int" << "\t\t" << sizeof(short int) << "\t\t" << numeric_limits<short int>::min() << "\t\t\t" << numeric_limits<short int>::max() << endl;
  13. cout << "unsigned short int" << "\t" << sizeof(unsigned short int) << "\t\t" << numeric_limits<unsigned short int>::min() << "\t\t\t" << numeric_limits<unsigned short int>::max() << endl;
  14. cout << "signed short int" << "\t" << sizeof(signed short int) << "\t\t" << numeric_limits<signed short int>::min() << "\t\t\t" << numeric_limits<signed short int>::max() << endl;
  15. cout << "long int" << "\t\t" << sizeof(long int) << "\t\t" << numeric_limits<long int>::min() << "\t" << numeric_limits<long int>::max() << endl;
  16. cout << "unsigned long int" << "\t" << sizeof(unsigned long int) << "\t\t" << numeric_limits<unsigned long int>::min() << "\t\t\t" << numeric_limits<unsigned long int>::max() << endl;
  17. cout << "signed long int" << "\t\t" << sizeof(signed long int) << "\t\t" << numeric_limits<signed long int>::min() << "\t" << numeric_limits<signed long int>::max() << endl;
  18. cout << "float(浮点型)" << "\t\t" << sizeof(float) << "\t\t" << numeric_limits<float>::min() << "\t\t" << numeric_limits<float>::max() << endl;
  19. cout << "double(双浮点型)" << "\t" << sizeof(double) << "\t\t" << numeric_limits<double>::min() << "\t\t" << numeric_limits<double>::max() << endl;
  20. cout << "long double" << "\t\t" << sizeof(long double) << "\t\t" << numeric_limits<long double>::min() << "\t\t" << numeric_limits<long double>::max() << endl;
  21. cout << "wchar_t(宽字符型)" << "\t" << sizeof(wchar_t) << "\t\t" << numeric_limits<wchar_t>::min() << "\t\t" << numeric_limits<wchar_t>::max() << endl;
  22. return 0;
  23. }

定义变量

type field = value;

这是最常见的初始化语法,使用等号来将value赋值给field。这种方式允许发生隐式类型转换,并且不会进行列表初始化检查。

  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. int a = 1;
  5. int b = 1.5;
  6. cout << a << endl; // 1
  7. cout << b << endl; // 1
  8. return 0;
  9. }

type field(value);

这种初始化方式使用括号进行初始化。它类似于使用等号进行初始化,允许发生隐式类型转换,不进行列表初始化检查。

  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. int a(1);
  5. int b(1.56);
  6. cout << a << endl; // 1
  7. cout << b << endl; // 1
  8. return 0;
  9. }

type field{value};

这种初始化方式使用花括号,被称为列表初始化。它提供了更严格的类型检查,并且不允许发生窄化转换(narrowing conversion)。如果存在可能发生精度损失或信息丢失的情况,编译器会产生错误。

  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. int a{
  5. 1}; // int a{1.5}; error
  6. cout << a << endl; // 1
  7. return 0;
  8. }

type field = {value};

这种初始化方式也使用等号和花括号,被称为统一初始化。它类似于列表初始化,提供了更严格的类型检查,并且不允许窄化转换。与type field{value}; 的区别在于,等号和花括号之间可以有空格。

  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. int a = {
  5. 1}; // int a = {1.5}; error
  6. cout << a << endl; // 1
  7. return 0;
  8. }

数学常量及函数

在这里插入图片描述

  1. #include <iostream>
  2. #include <numbers>
  3. using namespace std;
  4. int main() {
  5. cout << "自然对数的底\t\t\t" << numbers::e << endl;
  6. cout << "圆周率\t\t\t\t" << numbers::pi << endl;
  7. cout << "2的平方根\t\t\t" << numbers::sqrt2 << endl;
  8. cout << "黄金比例常量\t\t\t" << numbers::phi << endl;
  9. cout << "绝对值\t\t\t\t" << abs(-1.23) << endl;
  10. cout << "大于或等于参数的最小整数\t" << ceil(-1.23) << endl;
  11. cout << "小于或等于参数的最大整数\t" << floor(-1.23) << endl;
  12. cout << "计算e^参数\t\t\t" << exp(1) << endl;
  13. cout << "计算底为e的参数的自然对数\t" << log(exp(1)) << endl;
  14. cout << "计算底为10的参数的自然对数\t" << log10(100) << endl;
  15. cout << "幂\t\t\t\t" << pow(2, 10) << endl;
  16. cout << "平方根\t\t\t\t" << sqrt(9) << endl;
  17. cout << "四舍五入\t\t\t" << round(-12.54) << endl;
  18. return 0;
  19. }

静态类型转换 static_cast

强制转换为另一种数据类型的值,转换过程中不进行任何运行时类型检查,因此可能导致运行时错误,通常用于比较类型相似的对象之间的转换,如int转float

  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. float a = 1.23;
  5. int b = static_cast<int>(a);
  6. cout << a << " 类型:" << typeid(a).name() << endl; // 1.23 类型:f
  7. cout << b << " 类型:" << typeid(b).name() << endl; // 1 类型:i
  8. return 0;
  9. }

格式化字符串

std::stringstream

  1. #include <iostream>
  2. #include <sstream>
  3. using namespace std;
  4. int main() {
  5. int age = 18;
  6. char name[] = "Lee";
  7. stringstream msg;
  8. msg << "Hello, " << name << "!!! " << age << "!!!";
  9. cout << msg.str() << endl; // Hello, Lee!!! 18!!!
  10. return 0;
  11. }

std::string

  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. int age = 18;
  5. string name = "Lee";
  6. string msg = "Hello, " + name + "!!! " + to_string(age) + "!!!";
  7. cout << msg << endl; // Hello, Lee!!! 18!!!
  8. return 0;
  9. }

引入三方库 fmt/core.h

下载

https://github.com/fmtlib/fmt.git

在这里插入图片描述

引入 c-app/CMakeLists.txt

  1. cmake_minimum_required(VERSION 3.25)
  2. project(c_app)
  3. set(CMAKE_CXX_STANDARD 20)
  4. add_executable(c_app ../main.cpp)
  5. # 添加fmt库目录
  6. add_subdirectory(../libs/fmt-10.0.0)
  7. # 链接fmt库
  8. target_link_libraries(c_app fmt::fmt)

运行

  1. #include <iostream>
  2. #include "libs/fmt-10.0.0/include/fmt/core.h"
  3. using namespace std;
  4. int main() {
  5. char name[] = "Lee";
  6. double height = 1.8123456;
  7. int age = 18;
  8. string msg = fmt::format("Hello, {}! Height: {:.2f}! Age: {}!", name, height, age);
  9. cout << msg << endl; // Hello, Lee! Height: 1.81! Age: 18!
  10. return 0;
  11. }

字符运算

  1. #include <iostream>
  2. #include "libs/fmt-10.0.0/include/fmt/core.h"
  3. using namespace std;
  4. int main() {
  5. char word = 'A';
  6. string msg = fmt::format("字符: {} \n表示字符的整数代码: {} \n整数转字符: {}", word, word + 1, static_cast<char>(word + 2));
  7. /**
  8. * 字符: A
  9. * 表示字符的整数代码: 66
  10. * 整数转字符: C
  11. */
  12. cout << msg << endl;
  13. return 0;
  14. }

auto 关键字

用于自动推断变量类型

  1. #include <iostream>
  2. #include "libs/fmt-10.0.0/include/fmt/core.h"
  3. using namespace std;
  4. int main() {
  5. auto a = 1;
  6. auto b = {
  7. 2};
  8. auto c{
  9. 3};
  10. /**
  11. * a: i
  12. * b: St16initializer_listIiE
  13. * c: i
  14. */
  15. cout << fmt::format("a: {}\nb: {}\nc: {}", typeid(a).name(), typeid(b).name(), typeid(c).name()) << endl;
  16. return 0;
  17. }

枚举类型

  1. #include <iostream>
  2. #include "libs/fmt-10.0.0/include/fmt/core.h"
  3. using namespace std;
  4. /**
  5. * 枚举类型Color
  6. */
  7. enum class Color {
  8. red, green = 3, blue
  9. } color;
  10. /**
  11. * 枚举类型Mode
  12. */
  13. enum class Mode : char {
  14. create = 'C',
  15. del = 'D',
  16. edit = 'U',
  17. search = 'Q'
  18. };
  19. int main() {
  20. cout << static_cast<int>(color) << endl; // 0
  21. color = Color::red;
  22. cout << static_cast<int>(color) << endl; // 0
  23. color = Color::green;
  24. cout << static_cast<int>(color) << endl; // 3
  25. color = Color::blue;
  26. cout << static_cast<int>(color) << endl; // 4
  27. Color c1 = Color::red;
  28. Color c2 = Color::green;
  29. Color c3 = Color::blue;
  30. cout << fmt::format("c1: {}, c2: {}, c3: {}", static_cast<int>(c1), static_cast<int>(c2), static_cast<int>(c3)) << endl; // c1: 0, c2: 3, c3: 4
  31. Mode mode{
  32. Mode::edit};
  33. cout << fmt::format("mode: {}, {}", static_cast<char>(mode), static_cast<int>(mode)) << endl; // mode: U, 85
  34. return 0;
  35. }

数据类型定义别名

  1. #include <iostream>
  2. #include "libs/fmt-10.0.0/include/fmt/core.h"
  3. // 别名方式1
  4. using str1 = std::string;
  5. // 别名方式2
  6. typedef char str2;
  7. int main() {
  8. str1 say = "Hello";
  9. str2 name[] = "Lee";
  10. std::cout << fmt::format("{}, {}!!!", say, name) << std::endl; // Hello, Lee!!!
  11. return 0;
  12. }

判断是否为NaN

  1. #include <iostream>
  2. #include "libs/fmt-10.0.0/include/fmt/core.h"
  3. #include <numbers>
  4. using namespace std;
  5. int main() {
  6. double pi = numbers::pi;
  7. double num = sqrt(-1);
  8. cout << fmt::format("pi: {}, num: {}", pi, num) << endl; // pi: 3.141592653589793, num: nan
  9. cout << fmt::format("pi: {}, num: {}", isnan(pi), isnan(num)) << endl; // pi: false, num: true
  10. return 0;
  11. }

三向比较运算符(太空飞船运算符)

  • a <=> b 返回枚举类型

    • equal(等于)
    • equivalent(等于)
    • greater(大于)
    • less(小于)
    • unordered(NaN相等)









































比较类型 less greater equal equivalent unordered 用于
strong_ordering YES YES YES YES NO 整数和指针
partial_ordering YES YES NO YES YES 浮点数
weak_ordering YES YES NO YES NO 仅用于用户自定义的运算符
  1. #include <iostream>
  2. #include "libs/fmt-10.0.0/include/fmt/core.h"
  3. using namespace std;
  4. int main() {
  5. double a = numeric_limits<double>::quiet_NaN(); // nan
  6. double b = numeric_limits<double>::quiet_NaN(); // nan
  7. partial_ordering c{
  8. a <=> b};
  9. if (c == strong_ordering::equal) {
  10. cout << "a = b" << endl;
  11. } else if (c == strong_ordering::equivalent) {
  12. cout << "两个值在强序比较中是等价的" << endl;
  13. } else if (c == strong_ordering::greater) {
  14. cout << "a > b" << endl;
  15. } else if (c == strong_ordering::less) {
  16. cout << "a < b" << endl;
  17. }
  18. if (c == partial_ordering::unordered) {
  19. cout << fmt::format("a: {}, b: {}", isnan(a), isnan(b)) << endl; // a: true, b: true
  20. }
  21. if (is_eq(c)) {
  22. cout << "a = b" << endl;
  23. }
  24. if (is_gt(c)) {
  25. cout << "a > b" << endl;
  26. }
  27. if (is_gteq(c)) {
  28. cout << "a >= b" << endl;
  29. }
  30. if (is_lt(c)) {
  31. cout << "a < b" << endl;
  32. }
  33. if (is_lteq(c)) {
  34. cout << "a <= b" << endl;
  35. }
  36. return 0;
  37. }

多维数组

  1. #include <iostream>
  2. #include "libs/fmt-10.0.0/include/fmt/core.h"
  3. using namespace std;
  4. int main() {
  5. int list[3][3] = {
  6. {
  7. 1, 2, 3},
  8. {
  9. 4, 5, 6},
  10. {
  11. 7, 8, 9}
  12. };
  13. for (int i = 0; i < size(list); ++i) {
  14. for (int j = 0; j < size(list[i]); ++j) {
  15. cout << fmt::format("{} ", list[i][j]); // 1 2 3 4 5 6 7 8 9
  16. }
  17. }
  18. for (auto &a: list) {
  19. for (int b: a) {
  20. cout << fmt::format("{} ", b); // 1 2 3 4 5 6 7 8 9
  21. }
  22. }
  23. return 0;
  24. }

避免幻数

幻数是指在代码中直接使用一些未经解释的常数值,这样的代码可读性较差,且不易于维护和理解,示例如下:

  1. #include <iostream>
  2. #include "libs/fmt-10.0.0/include/fmt/core.h"
  3. using namespace std;
  4. int main() {
  5. int list[3]{
  6. 1, 2, 3};
  7. for (int i = 0; i < size(list) + 5; ++i) {
  8. /**
  9. * 结果:
  10. * 1 2 3 1 -1445723955 -250088645 0 0
  11. * 1 2 3 1 1461452947 457358528 0 0
  12. * 1 2 3 1 805896392 1713566091 0 0
  13. */
  14. cout << fmt::format("{} ", list[i]);
  15. }
  16. return 0;
  17. }

运行期间为数组分配内存空间

可变的数组长度

  1. #include <iostream>
  2. #include "libs/fmt-10.0.0/include/fmt/core.h"
  3. using namespace std;
  4. int main() {
  5. int count;
  6. cin >> count; // 8
  7. int list[count];
  8. for (int i = 0; i < count; ++i) {
  9. list[i] = i + 1;
  10. }
  11. for (int num: list) {
  12. cout << fmt::format("{} ", num); // 1 2 3 4 5 6 7 8
  13. }
  14. return 0;
  15. }

数组的替代品

std::array

  1. #include <iostream>
  2. #include "libs/fmt-10.0.0/include/fmt/core.h"
  3. using namespace std;
  4. int main() {
  5. /* ========= list1 =========*/
  6. array<int, 5> list1 = {
  7. 1, 2, 3, 4, 5};
  8. for (int d: list1) {
  9. cout << d; // 1 2 3 4 5
  10. }
  11. /* ========= list2 =========*/
  12. auto list2 = array{
  13. 1, 2, 3, 4, 5}; // 根据值推断模版参数
  14. cout << list2.size(); // 5
  15. cout << list2.at(3); // 4
  16. cout << list2[2]; // 3
  17. list2.fill(3);
  18. for (double d: list2) {
  19. cout << d; // 3 3 3 3 3
  20. }
  21. return 0;
  22. }

比较

  • 相等比较每个元素均相等
  • 不等只要存在不等即不等
  • 大于第一个元素进行比较然后返回对应判断
  • 小于第一个元素进行比较然后返回对应判断

    include

    include “libs/fmt-10.0.0/include/fmt/core.h”

    using namespace std;

    int main() {

  1. array<int, 5> l = {
  2. 1, 2, 3, 4, 5};
  3. array<int, 5> a = {
  4. 1, 2, 3, 4, 5}; // l == a
  5. array<int, 5> b = {
  6. 5, 4, 3, 2, 1}; // l < b
  7. array<int, 5> c = {
  8. 3, 2, 1, 5, 4}; // l < c
  9. array<int, 5> d = {
  10. 6, 6, 6, 6, 6}; // l < d
  11. array<int, 5> e = {
  12. 0, 0, 1, 0, 0}; // l > e
  13. return 0;
  14. }

std::vector

  1. #include <iostream>
  2. #include "libs/fmt-10.0.0/include/fmt/core.h"
  3. using namespace std;
  4. int main() {
  5. /* ====== list1 ====== */
  6. vector<int> list1 = {
  7. 1, 2, 3, 4, 5};
  8. // push一个元素
  9. list1.push_back(6);
  10. // 数组长度
  11. cout << list1.size() << endl; // 6
  12. for (int num: list1) {
  13. cout << num; // 1 2 3 4 5 6
  14. }
  15. // 删除最后一个元素
  16. list1.pop_back();
  17. for (int num: list1) {
  18. cout << num; // 1 2 3 4 5
  19. }
  20. /* ====== list2 ====== */
  21. vector list2(1, 6); // 1 到 6
  22. for (int num: list2) {
  23. cout << num; // 1 2 3 4 5 6
  24. }
  25. list2.assign(3, 1); // 3 个 1
  26. for (int num: list2) {
  27. cout << num; // 1 1 1
  28. }
  29. list2.assign({
  30. 6, 2, 3, 4, 5});
  31. for (int num: list2) {
  32. cout << num; // 6 2 3 4 5
  33. }
  34. /* ====== list3 ====== */
  35. vector<int> list3{
  36. 7, 6, 2, 3, 3, 6, 3, 8};
  37. erase(list3, 3);
  38. for (int num: list3) {
  39. cout << num; // 7 6 2 6 8
  40. }
  41. list3.empty(); // 清空但保留长度
  42. cout << list3.size(); // 5
  43. list3.clear(); // 清空
  44. cout << list3.size(); // 0
  45. return 0;
  46. }

发表评论

表情:
评论列表 (有 0 条评论,151人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java 基本数据类型

    Java中的基本数据类型是构建Java程序的基础,熟练掌握这些类型的使用方法对于编写高质量的Java代码至关重要。本文将对Java中的基本数据类型进行详细介绍,并提供一些示例代

    相关 C51基本数据类型

    C51基本数据类型 C51中基本数据类型主要是指变量类型。变量是指其值可以改变的量。一个变量实质上是代表了内存中的某个存储单元。程序中的变量a,就是指用a命名的某个存储单

    相关 Linux C++基本数据类型

    计算机的内存是以字节byte为单位进行组织的。一个字节是我们能够在c++程序中操作的最小内存单位。 下面我们通过程序打印一下c++中常见的数据类型以及其所能够存储的数据范围