「C++系列」C++ 变量类型

文章目录

  • 一、C++ 变量类型
    • 1. 基本数据类型
    • 2. 复合数据类型
    • 3. 类型修饰符
  • 二、C++ 变量定义
    • 案例 1: 基本类型变量的定义和初始化
    • 案例 2: 数组的定义和使用
    • 案例 3: 结构体(Struct)的定义和使用
    • 案例 4: 指针的定义和使用
    • 案例 5: 类的定义和使用(面向对象)
  • 三、C++ 变量声明
    • 变量声明与初始化
    • 案例 1: 局部变量和全局变量的声明与定义
    • 案例 2: 使用`extern`关键字声明变量
    • 案例 3: 使用`auto`和`const`
  • 四、C++ 左值和右值
    • 左值(Lvalue)
    • 右值(Rvalue)
    • C++11及之后的变化
    • 案例 1: 基本的左值和右值
    • 案例 2: 使用移动构造函数和移动赋值操作符
  • 五、相关链接

在这里插入图片描述

一、C++ 变量类型

C++ 是一种静态类型、编译式、通用、面向对象的编程语言。在 C++ 中,变量是存储信息的容器,并且每个变量都有特定的类型,这个类型决定了变量可以存储什么类型的数据、需要多少存储空间以及可以进行的操作。C++ 提供了多种基本数据类型和复合数据类型来支持不同的编程需求。

1. 基本数据类型

  1. 整型(Integer Types)
  • int:标准的整数类型,用于存储整数值。
  • short:短整型,用于存储较小的整数值。
  • long:长整型,用于存储较大的整数值。
  • long long:更长的整型,用于存储非常大的整数值。
  • unsigned:与上述类型结合使用,表示无符号类型,即只能存储非负值。
  1. 浮点型(Floating-Point Types)
  • float:单精度浮点型,用于存储有小数部分的数值。
  • double:双精度浮点型,用于存储更大范围或更高精度的浮点数。
  • long double:扩展精度浮点型,提供比 double 更高的精度。
  1. 字符型(Character Types)
  • char:用于存储单个字符(如字母或标点符号)。
  1. 布尔型(Boolean Type)
  • bool:表示真(true)或假(false)的布尔值。
  1. 枚举类型(Enumeration Types)
  • enum:用户定义的类型,包含一组命名的整型常量。
  1. 宽字符类型(Wide Character Types)
  • wchar_t:用于存储宽字符(如 Unicode 字符)。

2. 复合数据类型

  1. 数组(Arrays)
  • 允许存储相同类型数据的固定大小的集合。
  1. 结构体(Structures)
  • 允许将不同类型的数据项组合成一个单一的类型。
  1. 联合体(Unions)
  • 允许在相同的内存位置存储不同的数据类型,但一次只能使用其中一个。
  1. 类(Classes)
  • C++ 的核心特性之一,支持面向对象编程,包括封装、继承和多态。
  1. 指针(Pointers)
  • 存储变量的内存地址,而不是变量的值。
  1. 引用(References)
  • 类似于指针,但提供了更高级别的抽象,并且是安全的(不能为空)。
  1. 字符串(Strings)
  • 在 C++ 中,字符串可以通过字符数组、std::string 类(C++ 标准库中的一部分)等方式表示。

3. 类型修饰符

  • signedunsigned:用于指明整型变量是否有符号。
  • const:表示变量是常量,其值在初始化后不能被修改。
  • volatile:告诉编译器该变量的值可能会在程序的控制之外被改变。

二、C++ 变量定义

在C++中,变量定义涉及到指定变量的类型以及变量的名称,并可能包括初始化(即给变量赋一个初始值)。下面将展示几个详细的C++变量定义及使用的案例代码。

案例 1: 基本类型变量的定义和初始化

#include <iostream>
using namespace std;int main() {// 定义并初始化整型变量int age = 30;// 定义并初始化浮点型变量float height = 5.9;// 定义并初始化字符型变量char gender = 'M';// 定义布尔型变量并初始化bool isStudent = true;// 输出变量值cout << "Age: " << age << endl;cout << "Height: " << height << endl;cout << "Gender: " << gender << endl;cout << "Is Student: " << (isStudent ? "Yes" : "No") << endl;return 0;
}

案例 2: 数组的定义和使用

#include <iostream>
using namespace std;int main() {// 定义并初始化整型数组int numbers[] = {1, 2, 3, 4, 5};// 遍历数组并打印每个元素for(int i = 0; i < 5; i++) {cout << "numbers[" << i << "]: " << numbers[i] << endl;}return 0;
}

案例 3: 结构体(Struct)的定义和使用

#include <iostream>
using namespace std;// 定义结构体
struct Person {string name;int age;float height;
};int main() {// 定义并初始化结构体变量Person person1 = {"John Doe", 30, 6.0};// 访问结构体成员并打印cout << "Name: " << person1.name << endl;cout << "Age: " << person1.age << endl;cout << "Height: " << person1.height << endl;return 0;
}

案例 4: 指针的定义和使用

#include <iostream>
using namespace std;int main() {// 定义整型变量int value = 10;// 定义指向整型的指针变量,并初始化为指向valueint* ptr = &value;// 通过指针访问变量的值cout << "Value through pointer: " << *ptr << endl;// 修改指针指向的值*ptr = 20;// 再次通过指针访问变量的值,查看是否已修改cout << "Modified Value through pointer: " << *ptr << endl;return 0;
}

案例 5: 类的定义和使用(面向对象)

#include <iostream>
using namespace std;// 定义类
class Rectangle {
public:int width, height;// 构造函数Rectangle(int w, int h) : width(w), height(h) {}// 计算面积的方法int area() {return width * height;}
};int main() {// 创建Rectangle类的对象Rectangle rect(5, 7);// 调用对象的方法并打印结果cout << "Area of rectangle: " << rect.area() << endl;return 0;
}

三、C++ 变量声明

在C++中,变量声明(Declaration)和定义(Definition)有时可以互换使用,但在严格意义上它们是有区别的。声明是告诉编译器变量的类型和名称,而定义(也称为初始化)则是为变量分配内存空间并可能赋予一个初始值。然而,在大多数情况下,当你声明一个变量时也会同时定义它(即给出初始值),或者在之后的某个点进行定义。

变量声明与初始化

// 声明一个整型变量,但不在此初始化(即仅声明)
extern int a; // 这通常用于在多个文件中共享变量,但这里只是作为声明的示例// 声明并初始化一个整型变量
int b = 10; // 这既是声明也是定义// 声明一个整型变量,稍后在函数内部初始化
int c;
// ...
c = 20; // 现在c被定义了(如果之前没有在其他地方定义)// 使用auto关键字自动推导类型(C++11及以后)
auto d = 3.14; // d的类型是double,因为3.14是double字面量// 声明并初始化一个常量(使用const)
const int e = 5; // e是一个常量,其值在编译时确定,且之后不能更改// 静态局部变量声明(在函数内部)
void func() {static int f = 0; // f在函数第一次调用时初始化,之后调用时保持其值f++;cout << "f: " << f << endl;
}

案例 1: 局部变量和全局变量的声明与定义

#include <iostream>
using namespace std;// 全局变量声明(通常也是定义)
int globalVar = 100;void func() {// 局部变量声明并初始化int localVar = 20;cout << "Local variable: " << localVar << endl;// 访问全局变量cout << "Global variable: " << globalVar << endl;
}int main() {func(); // 调用函数,展示局部变量和全局变量的使用// 尝试在main中访问localVar会导致编译错误,因为它是func的局部变量return 0;
}

案例 2: 使用extern关键字声明变量

当你想在多个源文件中共享变量时,可以使用extern关键字在一个或多个源文件中声明变量,但在一个源文件中定义它。

#include <iostream>
using namespace std;// 定义全局变量
int sharedVar = 5;void printSharedVar() {cout << "sharedVar in file1.cpp: " << sharedVar << endl;
}// ...
#include <iostream>
using namespace std;// 声明全局变量(不初始化)
extern int sharedVar;void modifySharedVar() {sharedVar = 10; // 修改在file1.cpp中定义的全局变量
}// ...

注意:在实际项目中,你还需要确保这些文件被正确地编译和链接,以便extern声明能够找到变量的定义。

案例 3: 使用autoconst

#include <iostream>
#include <vector>
using namespace std;int main() {// 使用auto自动推导类型auto x = 10; // x的类型是intauto y = 3.14; // y的类型是double// 使用const声明常量const int maxSize = 100; // maxSize是一个常量,其值在编译时确定// 使用auto和const一起const auto z = 20.5; // z的类型是const doublecout << "x: " << x << endl;cout << "y: " << y << endl;cout << "maxSize: " << maxSize << endl;cout << "z: " << z << endl; // 注意:不能直接修改z的值,因为它是constreturn 0;
}

四、C++ 左值和右值

在C++中,左值(lvalue)和右值(rvalue)是表达式的一个关键属性,它们与表达式的身份(location)和值(value)有关。左值通常指的是一个具有持久状态的对象,其地址可取,可以被赋值。而右值则是一个临时值,没有持久的存储位置,通常用于表达式的求值过程中,且不能作为左值被赋值。

左值(Lvalue)

  • 有持久的身份(即存储位置)。
  • 可以出现在赋值语句的左侧。
  • 可以取地址(& 操作符)。

右值(Rvalue)

  • 通常是临时的,没有持久的存储位置。
  • 不能出现在赋值语句的左侧(C++11之前)。
  • 不能直接取地址(尽管C++11引入了右值引用,允许通过std::move等方式“模拟”取地址)。

C++11及之后的变化

C++11引入了右值引用(通过&&表示)和移动语义,使得右值可以被更加高效地处理和利用。此外,还引入了std::move函数,用于将左值“转换为”右值引用,以便可以使用移动构造函数或移动赋值操作符。

案例 1: 基本的左值和右值

#include <iostream>
#include <string>int main() {int a = 5; // a是左值int b = a; // 合法,因为a是左值int c = 10 + 20; // c是左值,但10 + 20这个表达式的结果是右值// int d = 10 + 20; // 这条语句在语法上也是合法的,但10+20的结果(右值)不会“存储”在d中,而是被计算后赋值给d// 尝试对右值进行取地址操作(编译错误)// &(10 + 20); // 非法,因为右值没有地址std::string s1 = "Hello"; // s1是左值std::string s2 = std::move(s1); // s1在这里被“转换”为右值引用,以便s2可以“窃取”s1的资源// 注意:此时s1的状态是未定义的,因为s2可能已经“接管”了s1的资源return 0;
}

案例 2: 使用移动构造函数和移动赋值操作符

为了展示移动语义,我们可以定义一个简单的类,该类包含动态分配的内存,并实现移动构造函数和移动赋值操作符。

#include <iostream>
#include <cstring>
#include <algorithm>class MyString {
public:char* data;size_t len;// 构造函数MyString(const char* str) : len(std::strlen(str)) {data = new char[len + 1];std::strcpy(data, str);std::cout << "Constructor called" << std::endl;}// 移动构造函数MyString(MyString&& other) noexcept : data(other.data), len(other.len) {other.data = nullptr; // 防止析构时释放已移动的资源other.len = 0;std::cout << "Move constructor called" << std::endl;}// 移动赋值操作符MyString& operator=(MyString&& other) noexcept {if (this != &other) {delete[] data; // 释放当前对象的资源data = other.data;len = other.len;other.data = nullptr; // 防止析构时释放已移动的资源other.len = 0;}std::cout << "Move assignment operator called" << std::endl;return *this;}// 析构函数~MyString() {delete[] data;std::cout << "Destructor called" << std::endl;}// 为了简单起见,省略了拷贝构造函数和拷贝赋值操作符
};int main() {MyString s1("Hello");MyString s2 = std::move(s1); // 调用移动构造函数MyString s3("World");s3 = std::move(s2); // 调用移动赋值操作符// 此时s1和s2的资源已被s3接管,
}

五、相关链接

  1. Visual Studio Code下载地址
  2. Sublime Text下载地址
  3. 「C++系列」C++简介、应用领域
  4. 「C++系列」C++ 基本语法
  5. 「C++系列」C++ 数据类型

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

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

相关文章

网络连接之队头阻塞!!!

一、什么是队头阻塞 队头阻塞&#xff0c;在网络模型中简单理解就是&#xff0c;对于队列型的请求模型&#xff0c;如HTTP的请求-响应模型、TCP的ACK确认机制&#xff0c;都依赖得到一个具体的响应包&#xff0c;如果收不到这个响应包&#xff0c;那下一个请求就不能发&#x…

4、音视频封装格式---FLV

FLV FLV是一种容器封装格式&#xff0c;是由Adobe公司发布和维护的&#xff0c;用于将视频编码流与音频编码流进行封装。对于任意一种封装格式&#xff0c;都有其头部区域与数据区域&#xff0c;在FLV中&#xff0c;称之为FLV Header与Body。 对于FLV Header&#xff0c;一个FL…

煤矿安全大模型:微调internlm2模型实现针对煤矿事故和煤矿安全知识的智能问答

煤矿安全大模型————矿途智护者 使用煤矿历史事故案例,事故处理报告、安全规程规章制度、技术文档、煤矿从业人员入职考试题库等数据,微调internlm2模型实现针对煤矿事故和煤矿安全知识的智能问答。 本项目简介: 近年来,国家对煤矿安全生产的重视程度不断提升。为了确…

SpringBoot+mail 轻松实现各类邮件自动推送

一、简介 在实际的项目开发过程中&#xff0c;经常需要用到邮件通知功能。例如&#xff0c;通过邮箱注册&#xff0c;邮箱找回密码&#xff0c;邮箱推送报表等等&#xff0c;实际的应用场景非常的多。 早期的时候&#xff0c;为了能实现邮件的自动发送功能&#xff0c;通常会…

【STM32入门教学】——串口、定时器与参考资料

机器人工程系列文章目录 这里罗列了系列文章链接 概念总述 STM入门教学 还没写完组里急用 文章目录 机器人工程系列文章目录概念总述STM入门教学 前言串口串口的概念cubemxkeil5实物实验关于cubemx生成逻辑printf升级usart.cmain.hretarget.c 定时器定时器的概念cubemxkeil5…

带电池监控功能的恒流直流负载组

EAK的交流和直流工业电池负载组测试仪对于测试和验证关键电力系统的能力至关重要&#xff0c;旨在实现最佳精度。作为一家客户至上的公司&#xff0c;我们继续尽我们所能应对供应链挑战&#xff0c;以提供出色的交货时间&#xff0c;大约是行业其他公司的一半。 交流负载组 我…

时钟切换的代码

目录 描述 输入描述&#xff1a; 输出描述&#xff1a; 参考代码 描述 题目描述&#xff1a; 存在两个同步的倍频时钟clk0 clk1,已知clk0是clk1的二倍频&#xff0c;现在要设计一个切换电路&#xff0c;sel选择时候进行切换&#xff0c;要求没有毛刺。 信号示意图&…

学习springMVC

第四章 Spring MVC 第一节 Spring MVC 简介 1. Spring MVC SpringMVC是一个Java 开源框架&#xff0c; 是Spring Framework生态中的一个独立模块&#xff0c;它基于 Spring 实现了Web MVC&#xff08;数据、业务与展现&#xff09;设计模式的请求驱动类型的轻量级Web框架&am…

vue3源码(六)渲染原理-runtime-dom

1、从入口文件看实现 项目入口文件 import { createApp } from vue import ./style.css import App from ./App.vuecreateApp(App).mount(#app)文件位置core\packages\runtime-dom\src\index.ts 保证了render的唯一性 // // rendererOptions 是patchProp 和nodeOps的合集&a…

可视化低代码平台之:RayData光启元的震撼作品。

RayData家的可视化作品&#xff0c;贝格前端工场是经常碰到&#xff0c;制作十分的精良&#xff0c;业内很有影响力。他们也有自己的低代码平台&#xff0c;分为了桌面版和网页版&#xff0c;本期分享一下他们的作品。

彻底掌握 Git:从零基础到高级实战的全方位教程

文章目录 一、Git 简介二、安装 Git1. Windows2. macOS3. Linux 三、Git 基本概念四、初次使用 Git1. 配置 Git2. 创建一个新的 Git 仓库3. 克隆一个远程仓库4. 跟踪文件5. 提交变更6. 查看历史记录 五、Git 分支管理1. 创建和切换分支2. 合并分支3. 分支冲突 六、远程仓库1. 添…

to_json 出现乱码的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

国产分布式数据库灾备高可用实现

最近在进行核心业务系统的切换演练测试&#xff0c;就在想一个最佳的分布式数据库高可用部署方案是如何保证数据不丢、系统可用的&#xff0c;做到故障时候可切换、可回切&#xff0c;并且业务数据的一致性。本文简要介绍了OceanBase数据库和GoldenDB数据库在灾备高可用的部署方…

kafka的架构

一、架构图 Broker&#xff1a;一台 kafka 服务器就是一个 broker。一个kakfa集群由多个 broker 组成。一个 broker 可以容纳多个 topic。 Producer&#xff1a;消息生产者&#xff0c;就是向 kafka broker 发消息的客户端 Consumer&#xff1a;消息消费者&#xff0c;向 kafk…

深海电波,智能驾驭:海上发电系统中的先进网关技术

随着技术的不断演进&#xff0c;海上风电场逐渐走向深海&#xff0c;随之而来的高速通信保障成为一大难题。同时&#xff0c;海上风电特殊的环境与部署技术&#xff0c;也给运维带来了作业难、成本高、响应慢等困难。通过在沿海岸边建立高站&#xff0c;结合超远覆盖、载波聚合…

springboot java.lang.ClassNotFoundException: dm.jdbc.driver.DmDriver 应该如何解决

遇到的问题&#xff1a;项目中引用了外部的达梦jar包 在idea中正常使用 也能找到dm.jdbc.driver.DmDriver 驱动 但是当通过jenkins 构建部署到服务器上 总是报 ClassNotFoundException: dm.jdbc.driver.DmDriver 找不到驱动 应用到的驱动代码如下格式 排查步骤 1.首先看你的项…

ROS2仿真工具-gazebo

gazebo独立于ROS2&#xff0c;就像插件一样&#xff0c;需要安装。 1.安装 sudo apt install gazebo sudo apt install ros-humble-gazebo-* 2.运行测试demo gazebo /opt/ros/humble/share/gazebo_plugins/worlds/gazebo_ros_diff_drive_demo.world 查看所有话题 ros2 top…

使用css做一个旋转的八卦图

使用css做一个旋转的八卦图 1, html部分 <div class"tai"><div class"bai"></div><div class"hei"></div> </div>2, css部分 .tai{width: 200px;height: 200px;border: 1px solid #000;background: linea…

STM32-I2C硬件外设

本博文建议与我上一篇I2C 通信协议​​​​​​共同理解 合成一套关于I2C软硬件体系 STM32内部集成了硬件I2C收发电路&#xff0c;可以由硬件自动执行时钟生成、起始终止条件生成、应答位收发、数据收发等功能&#xff0c;减轻CPU的负担 特点&#xff1a; 多主机功能&#x…

Shiro框架

入门概述 1 shiro是什么? Apache Shiro 是一个功能强大且易于使用的 Java 安全(权限)框架。Shiro 可以完成&#xff1a;认证、授权、加密、会话管理、与 Web 集成、缓存 等。借助 Shiro 您可以快速轻松地保护任何应用程序——从最小的移动应用程序到最大的 Web 和企业应用程…