C++primer 第二章 变量和基本类型

news2024/11/20 17:38:43

昨天思考了一下,感觉明白了。于是报名了软考,还有挑战z杯,想着四级还要不要报,毕竟我也不是有天赋的人,就只能努力去做个努力的人。加油!!! 不知道未来怎么样,那就走好现在吧!!!

C++中的类型

C++语言中有多种类型,包括基本数据类型、复合数据类型和用户自定义类型。以下是C++的一些常见类型: 

1. 基本数据类型(Primitive Data Types):
   - 整数类型:int、short、long、long long、unsigned等。
   - 浮点数类型:float、double。
   - 字符类型:char、wchar_t、char16_t、char32_t。
   - 布尔类型:bool。

2. 复合数据类型(Compound Data Types)
   - 数组(Array):存储相同类型的多个元素的集合。
   - 结构体(Struct):将不同类型的数据聚集到一个对象中。
   - 联合体(Union):使用相同的内存位置存储不同类型的数据。
   - 枚举(Enum):定义具有离散取值集合的新类型。

3. 指针类型(Pointer Types):
   - 指针(Pointer):存储内存地址的变量,用于间接访问和修改数据。
   - 空指针(nullptr):表示指针不指向任何有效的内存位置。
   - 空类型指针(void*):指向未知类型的指针。

4. 引用类型(Reference Types):
   - 引用(Reference):为变量起别名,在声明时使用&操作符。

5. 常量类型(Constant Types):
   - const:用于声明常量,值不能被修改。
   - constexpr:用于在编译时计算表达式的常量。

6. 自定义类型(User-defined Types):
   - 类(Class):封装数据和函数的用户定义类型。
   - 枚举类(Enum class):具有强类型和作用域的枚举类型。
   - 联合体(Union):使用相同的内存位置存储不同类型的数据。
   - 结构体(Struct):将不同类型的数据聚集到一个对象中。
   - 类型别名(Typedef):为现有类型创建新的类型名称。
   - using 声明(using declaration):引入命名空间中的特定成员。

其中bool类型是一个字节,char类型一个字节,wchar_t为宽字符为16个字节。。。

int整形通常是四个字节,不过在计算中我们通常作为16个字节数。

类型转换:

通常是精度较高的类型向较低类型转换可以,反之则不行。

变量名的作用域

在C++中,变量的作用域决定了变量在程序中的可见性和生命周期。以下是几种常见的变量作用域及其代码案例:

1. 全局作用域(Global Scope):
   - 在函数体外部声明的变量具有全局作用域,可以在整个程序中访问。
   - 示例代码:
     ```cpp
     #include <iostream>
     
     int globalVariable = 10; // 全局变量
     
     void printGlobalVariable() {
         std::cout << "Global variable: " << globalVariable << std::endl;
     }
     
     int main() {
         printGlobalVariable(); // 输出:Global variable: 10
         return 0;
     }
     ```

2. 块作用域(Block Scope):
   - 在函数、语句块或循环中声明的变量具有块作用域,只能在其所在的块或内层块中访问。
   - 示例代码:
 

     ```cpp
     #include <iostream>
     
     void printNumber() {
         int number = 5; // 块作用域变量
         std::cout << "Number: " << number << std::endl;
     }
     
     int main() {
         printNumber(); // 输出:Number: 5
         // std::cout << number; // 错误:无法访问printNumber函数中的number变量
         return 0;
     }
     ```

3. 函数参数作用域(Function Parameter Scope):
   - 函数参数具有函数参数作用域,只能在函数体内部访问。
   - 示例代码:
 

     ```cpp
     #include <iostream>
     
     void printName(std::string name) {
         std::cout << "Name: " << name << std::endl;
     }
     
     int main() {
         std::string myName = "Alice"; // 局部变量
         printName(myName); // 输出:Name: Alice
         // std::cout << name; // 错误:无法访问printName函数中的name参数
         return 0;
     }
     ```

4. 类作用域(Class Scope):
   - 在类定义中声明的成员变量具有类作用域,可以在整个类中访问。
   - 示例代码:
 

     ```cpp
     #include <iostream>
     
     class MyClass {
     public:
         int memberVariable = 20; // 类成员变量
     
         void printMemberVariable() {
             std::cout << "Member variable: " << memberVariable << std::endl;
         }
     };
     
     int main() {
         MyClass obj;
         obj.printMemberVariable(); // 输出:Member variable: 20
         return 0;
     }
     ```

这些是变量作用域的几个常见示例,每个作用域都有其特定的可见范围和生命周期。正确使用变量的作用域可以提高代码的可读性、避免命名冲突以及有效地管理变量的生命周期。

引用和指针

#include<iostream>
using namespace std;
int main()
{
	int b = 10;   
	int *a=&b;
	int** c = &a;
	cout << **c<< endl;
	return 0;
}

在代码中*a=&b  a的值等于b的地址,与就是 a的值为&b,*a就是指向a的值的地址的值,就是指向&b位置的值。

指针和引用的区别

指针和引用是C++语言中两种不同的机制,它们都可以用于间接操作内存中的值,但是它们之间有以下几个最大的区别:

1. 指针和引用的定义方式不同:
   - 指针是一个变量,其存储的值为另一个变量的地址,需要使用*(解引用运算符)来获取所指向的值。指针可以为空或NULL,可以被重新赋值指向不同的内存地址。
   - 引用是一个已经存在的变量的别名,一旦被定义,就不能被改变指向其他变量,也不能为空或NULL。

2. 指针和引用的用途不同:
   - 指针通常用于动态内存分配、数组及链表等数据结构的实现,以及函数参数传递。
   - 引用通常用于函数的返回值、函数参数传递和类的成员变量。

3. 指针和引用的空间占用不同:
   - 指针在32位系统中通常占用4个字节,在64位系统中通常占用8个字节,而且每次访问指针变量时都需要额外的开销。
   - 引用本身不占用额外的内存空间,它只是原变量的另一个名称,所以访问引用的速度通常比访问指针快。

4. 指针和引用的空值处理不同:
   - 指针可以为空或NULL,需要在使用时进行判断,否则可能会导致程序崩溃。
   - 引用不能为NULL或空,一旦被定义,就必须指向一个已经存在的变量。

 const限定符

顶层const:表示指针是一个常量

底层const:表示指针所指的是一个常量

  1. **顶层 const**:

    • 顶层 const 出现在对象的最顶层,表示对象本身是一个常量。这意味着你不能通过这个指针或引用来修改对象的值,但可以改变指针或引用指向其他对象。
    const int x = 5; // x 是一个顶层 const,不可修改
    int const y = 10; // 与上面相同,x 和 y 是等价的
    
    const int* ptr = &x; // ptr 是一个指向常量整数的指针,不允许通过 ptr 修改 x 的值
    

    复制

  2. **底层 const**:

    • 底层 const 出现在对象的底层,表示对象本身可修改,但不能通过这个指针或引用来修改对象的值。
    int a = 5;
    int const* ptr = &a; // ptr 是一个指向整数常量的指针,a 是可修改的,但不能通过 ptr 修改 a 的值
    
    const int* constPtr = &a; // 同上,ptr 和 constPtr 是等价的
    
    • 底层 const 在函数参数中常用于指明参数是只读的,从而防止函数内部修改参数的值。
    void foo(const int x) {
        // 在函数内部,x 是只读的,不能修改它的值
    }
    

总结一下:

  • 顶层 const 表示对象本身是常量,不能被修改。
  • 底层 const 表示指向的对象是常量,但指针或引用本身可以修改

constexpr常量表达式

`constexpr` 是 C++11 引入的关键字,用于声明常量表达式。常量表达式是在编译时就可以计算出结果的表达式,它具有以下特点:

1. 在编译时求值:常量表达式的值必须在编译时能够确定,不能依赖于运行时的输入或其他动态操作。
2. 编译时优化:编译器可以对常量表达式进行求值,并在编译期间进行优化,减少运行时的开销。
3. 用于常量定义:常量表达式可以用于定义常量变量,并在程序中使用。

使用 `constexpr` 关键字声明常量表达式时,需要满足一定的条件:

1. 表达式必须是编译时可求值的,不能含有任何可能运行时才能确定的值或操作。
2. 表达式中只能使用内置类型、字面值、函数调用(如果函数本身也是 `constexpr` 的),以及支持的运算符。
3. 声明常量表达式的函数本身也要被声明为 `constexpr`。

下面是一个示例代码,演示了如何使用 `constexpr` 声明和使用常量表达式:

```cpp
#include <iostream>

constexpr int square(int x) {
    return x * x;
}

int main() {
    constexpr int radius = 5;
    constexpr int area = square(radius) * 3.14;

    std::cout << "半径为 " << radius << " 的圆的面积是 " << area << std::endl;

    return 0;
}
```

在上面的代码中,`square` 函数被声明为 `constexpr`,它接受一个整数参数并返回该整数的平方。在 `main` 函数中,使用 `constexpr` 声明了常量 `radius` 和 `area`,并通过调用 `square` 函数计算圆的面积。由于所有的操作都是在编译时确定的,因此 `area` 的计算也可以在编译期间完成。

typedef

类型别名

typedef 是 C++ 中的一个关键字,用于为类型定义一个新的别名或类型名。通过使用 typedef,可以为已有的类型赋予一个更具描述性的名称,提高代码的可读性和可维护性。

typedef 的语法形式如下:

typedef 原类型 新类型名;

其中,原类型 表示要定义别名的已有类型,新类型名 是所定义的新类型。

下面是一些 typedef 的常见用法示例:

typedef int myInt;  // 将 int 类型定义为 myInt
typedef double Distance;  // 将 double 类型定义为 Distance
typedef int* IntPtr;  // 将 int* 类型定义为 IntPtr

typedef struct {
    int x;
    int y;
} Point;  // 将匿名结构体定义为 Point

typedef void (*FunctionPtr)(int);  // 将函数指针定义为 FunctionPtr,指向接受 int 参数且返回值为 void 的函数

在上述示例中,我们使用 typedef 分别为 intdoubleint*、匿名结构体以及函数指针定义了新的类型名。使用这些新类型名时,就相当于使用原类型。

typedef 在 C++ 中广泛用于提高代码的可读性和可维护性。它特别适用于复杂的类型和函数指针的声明,可以避免编写冗长的类型名,并使代码更加清晰易懂。然而,自 C++11 起,还引入了更加灵活和强大的类型别名机制 using,建议在新的代码中使用 using 来替代 typedef。例如,上述示例可以改写为以下形式:

using myInt = int;
using Distance = double;
using IntPtr = int*;

struct Point {
    int x;
    int y;
};

using FunctionPtr = void (*)(int);

decltype类型指示符

`decltype` 是 C++11 中引入的一个类型指示符(type specifier)。它用于从表达式中推导出其类型,并在编译时确定该表达式的类型。

`decltype` 的语法形式如下:
decltype(expression)

其中,`expression` 是一个有效的 C++ 表达式,可以是任意合法的表达式,包括变量、函数调用、运算符操作等。

`decltype` 主要有两种使用方式:

1. 推导变量的类型:通过 `decltype` 可以根据变量的初始化表达式来推导出变量的类型。例如:

  

 ```cpp
   int x = 5;
   decltype(x) y;  // 推导出 y 的类型为 int
   ```

   这里 `decltype(x)` 推导出的类型为 `int`,因为变量 `x` 的初始化表达式是整数值 5。

2. 推导表达式的类型:通过 `decltype` 可以根据表达式来推导出该表达式的类型。例如:

   ```cpp
   int a = 10;
   double b = 5.5;
   auto result = a + b;
   decltype(a + b) sum;  // 推导出 sum 的类型为 double
   ```

   这里 `decltype(a + b)` 推导出的类型为 `double`,因为表达式 `a + b` 的结果是一个浮点数。

需要注意的是,`decltype` 不会执行表达式,只负责推导表达式的类型。此外,如果表达式是一个变量名而不是一个初始化表达式,`decltype` 推导的类型将是该变量声明时的类型。例如:

```cpp
int x = 5;
decltype(x) y = x;  // 推导出 y 的类型为 int
```

`decltype` 是一个非常有用的类型指示符,可以在编译时获取表达式的类型,并且能够根据变量初始化表达式来推导出变量的类型。它可以用于声明变量、定义函数返回类型等场景,提高代码的可读性和灵活性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1081285.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Tableau:商业智能(BI)工具

Tableau入门 1、Tableau概述2、Tableau DesktopTableau保存文件类型和文件夹 1、Tableau概述 Tableau 成立于 2003 年&#xff0c;Tableau于2019年被 Salesforce 收购&#xff0c;是斯坦福大学一个计算机科学项目的成果&#xff0c;该项目旨在改善分析流程并让人们能够通过可视…

重新定义公共厕所,智慧公厕最新解决方案与推广路径

随着科技的进步&#xff0c;现代城市管理的智慧化解决方案在不断挑战传统的管理方式&#xff0c;而在智慧城市领域有一个热点的物联网应用解决方案——智慧公厕。智慧公厕不仅仅是公共厕所的升级版&#xff0c;它也是城市文明&#xff0c;高效&#xff0c;环保和科技的体现。本…

echarts实现圆柱体 渐变柱体

const weatherIcons [ { lable: ‘寿险’, id: 2, img: require(/assets/images/customerModule/title-action.png) }, { lable: ‘重疾’, id: 3, img: require(/assets/images/customerModule/title-action.png) }, { lable: ‘医疗’, id: 4, img: require(/assets/images/…

区块链跨链技术

区块链跨链技术 背景 近年来&#xff0c;随着区块链技术的不断发展&#xff0c;区块链的应用场景逐渐从最初的加密货币领域扩展到金融、物流、医疗、公共服务等各个领域。随着区块链的应用场景不断增多&#xff0c;区块链的“数据孤岛”问题日益突出&#xff0c;不同场景下的…

yolov8剪枝实践

本文使用的剪枝库是torch-pruning &#xff0c;实验了该库的三个剪枝算法GroupNormPruner、BNScalePruner和GrowingRegPruner。 安装使用 安装依赖库 pip install torch-pruning 把 https://github.com/VainF/Torch-Pruning/blob/master/examples/yolov8/yolov8_pruning.py&…

Mac系统清理工具BuhoCleaner

BuhoCleaner是一款在Mac电脑上运行的清洁软件。它的界面简洁&#xff0c;易于使用&#xff0c;能够快速扫描Mac电脑上的垃圾文件、重复文件、大型文件等&#xff0c;帮助用户清理不需要的文件&#xff0c;释放磁盘空间。 该软件的主要功能包括&#xff1a; 垃圾文件清理&…

哈希桶封装unordered set和map

目录 进一步实现哈希桶 引入 keyofValue 迭代器 insert返回值 operator[ ] key不能修改 模拟实现 keyofValue 代码 迭代器 谁在前 普通迭代器转换为const迭代器 const *this 问题 代码 insert和erase const迭代器转换为普通迭代器 key不能修改 完整版代码 …

前端axios发送请求,在请求头添加参数

1.在封装接口传参时&#xff0c;定义形参&#xff0c;params是正常传参&#xff0c;name则是我想要在请求头传参 export function getCurlList (params, name) {return request({url: ********,method: get,params,name}) } 2.接口调用 const res await getCurlList(params,…

电力智能运维管理平台:提升电力行业运营效率与安全

随着电力行业的不断发展&#xff0c;电力系统的运维管理逐渐成为关注的焦点。如何在保证供电稳定的同时&#xff0c;提高运营效率&#xff0c;降低运营成本&#xff0c;是电力行业面临的挑战。电力智能运维管理平台&#xff0c;正是在这一背景下应运而生的一种解决方案。 力…

insightface的预训练权重buffalo_sc.zip下载

想要下载 https://github.com/deepinsight/insightface里的权重找了半天&#xff0c;网络时而卡掉&#xff0c;所以分享 一下终于下载好了&#xff0c;存在百度网盘里&#xff0c;分享给大家。 链接&#xff1a;https://pan.baidu.com/s/1PKp3pPzFg8hrbqACUfHO2A?pwdamtf 提…

数据转换为excel模板下载

一、引入依赖 <dependency><groupId>org.jxls</groupId><artifactId>jxls-poi</artifactId><version>2.12.0</version></dependency> 二、准备解析的数据封装 package com.dst.modules.business.after.sale.parts.sparepa…

Java学习复杂的对象数组操作

Java学习复杂的对象数组操作 定义一个长度为3的数组&#xff0c;数组存储1~3名学生对象作为初始数据&#xff0c;学生对象的学号&#xff0c;姓名各不相同。 学生的属性&#xff1a;学号&#xff0c;姓名&#xff0c;年龄。 要求1&#xff1a;再次添加一个学生对象&#xff0…

什么是React的虚拟DOM(Virtual DOM)?它的作用是什么?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

nginx服务---2

如何统计连接数&#xff0c;以及根据域名配置虚拟主机 cd /usr/local/nginx/conf vim nginx.conf server {listen 80;server_name www.abc.com;charset utf-8;access_log logs/www.abc.com;error_log logs/www.abc.error.log;location / {root /var/www/html/zzr;in…

Pytorvh之Vision Transformer图像分类

文章目录 前言一、Transformer1.Transformer概览2.Self-Attention3.Multi-head Attention4.Position-wise Feed-Forward Networks(位置前馈网络)5.残差连接和层归一化6.Positional Encodings(位置编码) 二、Vision Transformer1.Vision Transformer概览2.Embedding层结构&#…

DetailView/货币详情页 的实现

1. 创建货币详情数据模型类 CoinDetailModel.swift import Foundation// JSON Data /*URL:https://api.coingecko.com/api/v3/coins/bitcoin?localizationfalse&tickersfalse&market_datafalse&community_datafalse&developer_datafalse&sparklinefalseR…

滚珠螺母在工业机器人中的应用优势

工业机器人是广泛用于工业领域的多关节机械手或多自由度的机器装置&#xff0c;具有一定的自动性&#xff0c;可依靠自身的动力能源和控制能力实现各种工业加工制造功能。滚珠螺母作为工业机器人中的重要传动配件&#xff0c;在工业机器人的应用中有哪些优势呢&#xff1f; 1、…

华为云云耀云服务器L实例评测 | 实例评测使用之硬件参数评测:华为云云耀云服务器下的监控 glances

华为云云耀云服务器L实例评测 &#xff5c; 实例评测使用之硬件参数评测&#xff1a;华为云云耀云服务器下的监控 glances 介绍华为云云耀云服务器 华为云云耀云服务器 &#xff08;目前已经全新升级为 华为云云耀云服务器L实例&#xff09; 华为云云耀云服务器是什么华为云云耀…

【操作系统】信号量机制及PV操作问题总结

【操作系统】信号量机制及PV操作问题总结 文章目录 【操作系统】信号量机制及PV操作问题总结题型分类解题的基本思路1、前置知识 &#xff08;信号量机制&#xff09;&#xff08;1&#xff09;整型信号量&#xff08;2&#xff09;记录型信号量&#xff08;3&#xff09;信号量…

PCB板子上一坨黢黑的可不简单,你知道吗?

有些电路板上我们会看到这么一坨黑色的东西&#xff0c;其实这是一种封装工艺&#xff0c;我们称之为软封装&#xff0c;也叫邦定封装。 它是芯片生产工艺中一种打线的方式&#xff0c;一般用于封装前将芯片内部的电路用金线与封装管脚连接&#xff0c;是裸芯片贴装技术之一&am…