【C++学习笔记】变量和基本类型

news2024/11/23 19:52:42

2.1 基本内置类型

C++中包括 算数类型(arithmetic type) 和 空类型(void) 的数据类型,其中,算数类型包括字符、整型数、布尔值和浮点数;空类型不对应具体的值,当函数不返回值时用void作为返回类型

2.1.1算数类型

在这里插入图片描述

对于数组或者字符串,a[i++] / a[i—]先执行 a[i] 在执行i++/ i —; 而a[++i] / a[—i] 先执行 i++/ i— 然后执行 a[i]

Unsigned 和 signed:

无符号:只有正数
有符号: 分为 正数和负数 范围为 -128~127
unsigned和signed转换:unsigned表示为 1111 1111,为255,转换为signed后,符号位1代表是负数(最高位为符号位),数值位转换成十进制后是127,按照补码的定义结果为-1;当signed转为unsigned时,最高位不表示符号位。
补码
1、对于正数,补码与原码相同;
2、对于负数,数值位的绝对值取反后在最低位加1。PS:负数转整数也是取反后最低位加1(不是减1)

字面值常量

整型、浮点型:
以0 开头的为 八进制 : 024
以0x或者0X开头的为十六进制: 0x14
其他情况为十进制
字符型:
单引号括起来的为 char型字面值、双引号括起来的为 字符串型字面值

作用:用于显示单个字符
语法:char 字符名 = '字符值'
注意:
1. 要用单引号括起来
2. 单引号内只能由一个字符,不可以是字符串
3. C和C++中字符型变量只占用1个字节
4. 字符型变量不是把字符本身存放到内存中,而是将对应的ASCII编码放入到存储单元中

#include<iostream>

using namespace std;

int main()
{
	// 1.字符型变量的创建方式
	char ch = 'a';
	cout << ch << endl;

	// 2.字符型变量所占内存大小
	cout << "char字符型所占内存大小:" << sizeof(ch) << endl;

	// 3.字符型变量常见错误
	//char ch2 = "b"; // 创建字符型变量要用 单引号
	//char ch2 = 'abcdef'; //  创建字符型变量单引号内只能有一个字符

	// 4.字符型变量对应的ASCII编码 转为 int 型
	cout << "char字符型对应ASCII编码:" << (int)ch << endl;

	return 0;
}

输出结果:
在这里插入图片描述

常见字符型ASCII码:a - 97 A - 65
ASCII码:
1. 0-31 非打印的控制字符
2. 32-126 键盘上可以找到的字符
修改类型:
通过添加前后缀来改变字符类型
在这里插入图片描述

2.2 变量

2.2.1 变量定义

int:内置int 全局int默认初始化为0,函数体内的不被初始化 如果初始化会为 未定义的奇异值
string: 内置的string 无论是全局还是函数体内 默认初始化均为 空字符串

2.2.2 变量声明与定义

声明:将一个变量的名字让电脑知道 没有初始化 变量前+ 关键字 extern
定义:声明并初始化变量,需要申请存储空间
如果在函数体内初始化一个由extern 标记的变量会报错 变量可以多次声明但只能定义一次

2.3 复合类型

指针

32位 指针占用内存 4个字节
64位 8个字节
作用:获取对象的地址 (指针本身是对象
指针值:对象的地址 类型要匹配
四种状态:
1.指向一个对象
2.指向邻近对象所占空间的下一个位置
3.空指针,即指针没有指向任何对象
4.无效指针,除以上3种外的情况
void* 指针,可以指向任何类型的对象的地址;一般用于指针比较、作为函数的输入或输出、赋值给另一个void*指针

判断指针是否合法:

将指针用if 进行判断
在这里插入图片描述
在这里插入图片描述

空指针:

1.用于给指针变量初始化

int *p = NULL;

2.空指针不能进行访问

const 与指针

int main()
{
	int a = 10, b = 10;
    //1. const 修饰指针  常量指针
    const int *p = &a; // 常量指针,指针指向的值不可以改, 指针的指向可以改
    // *p = 20; //指针指向的值不可以改
    p = &b; // 指针的指向可以改  

    //2. const 修饰常量 指针常量
    int * const p2 = &a;
    *p2 = 100; // 指针指向的值可以改
    // p2 = &b; // 指针的指向不可以改
    
    //3. const 修饰常量和指针
    const int * const p3 = &a;
    // *p3 = 100; // 指针指向的值不可以修改
    // p3 = &b; // 指针的指向不可以修改
}

指针与数组、指针与函数

指针与数组

	//指针与数组
	int arr[10] = {1,2,3,4,5,6,7,8,9,10};
	int *p = arr; // p指向数组的首地址
	// cout << *p << endl;
	// 指针访问 数组任意位置 p++ 相对于指针p向后移动了4个字节
	// cout << *(p+1) << endl;
	for(int i = 0; i < sizeof(arr) / sizeof(int); ++i)
	{
		cout << *(p++) << " ";
	}

指针与函数
利用地址传递实现函数
// 数组以参数的形式传出时会成为一个指针类型,失去了数组的属性, 因此必须传入一个数组的长度 且 数组默认的传递方式均为 地址传递,不能进行值传递
传递引用时,同时将数组长度也传递进去了,所以传入时必须为相应长度的数组。并且,在传递引用时,需要注意用()将&aa括起来,否则编译器报错。

	//值传递数组
	void printdz(int a[])
	{
		cout<<"子函数里a0的地址为"<<&a[0]<<endl;
		cout<<"子函数里a的地址为"<<a<<endl; 
		//a本身即为指针 无需取地址符
		cout<<"子函数里a1的首地址为"<<&a[1]<<endl;
		a[1]=2;
	}
	int main()
	{
		int a[10]={1};
		cout<<"主函数里a的首地址为"<<&a[0]<<endl;
		cout<<"开始的a1为 "<<a[1]<<endl;
		printdz(a);
		cout<<"函数里改过的a1 为"<<a[1]<<endl;
		return 0;
	}
	//引用传递数组
	void printdzyy(int (&aa)[10]) 
	//引用就可以传递数组长度 因此需要写出数组大小
	{
		cout<<"函数里aa的地址为"<<aa<<endl;
	}
	int main()
	{
		int a[10]={1};
		int b[5]={1};
		cout<<"主函数里a[0]的首地址为"<<&a[0]<<endl;
		printdzyy(a);
	  //printdzyy(b);  incorrect  //如果传入b则编译不通过
		return 0;
	}
#include<iostream>
using namespace std;

void bubbleSort(int *arr, int len)
{
    for(int i = 0; i < len; ++i)
    {
        for(int j = 0; j < len; ++j)
        {
            if(arr[i] < arr[j])
            {
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
    }
}

void printArr(int *arr, int len)
{
     for(int i = 0; i < len; ++i)
    {
        cout << arr[i] << " ";
    }
    cout << endl;
}

int main()

{ 
    int arr2[10] = {4,3,6,9,1,2,10,8,7,5};
    int len = sizeof(arr2) / sizeof(int);
    cout << "排序前:" << endl;
    printArr(arr2, len); 
    bubbleSort(arr2, len);
    cout << "排序后:" << endl;
    printArr(arr2, len);
} 

引用

引用:引用类型的初始值必须是一个==对象类型需要相同==
int 可以引用 double 类型(窄化操作
引用一旦初始化后,就不可以更改

#include<iostream>
using namespace std;
int main()
{
    int a = 10;
    int &b = a; // 引用必须初始化
    int c = 20;
    b = c; // 为赋值操作 不是更改引用,引用在初始化后不可以更改
  
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    cout << "c = " << c << endl;
}

引用做函数参数

1.值传递

// 1. 值传递 // 值没有发生改变, 值传递不改变实参数据 形参不会修饰实参
void mySwap01(int a, int b)
{
    int temp = a;
    a = b;
    b = temp;
    cout << "函数内 a = " << a << endl;
    cout << "函数内 b = " << b << endl;
}

2.地址传递

// 2. 地址传递 用形参修饰实参 用指针接受地址
void mySwap02(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

3.引用传递

// 3. 引用传递
void mySwap03(int &a, int &b)
{
    int temp = a;
    a = b;
    b = temp;
}
int main()
{
    // 引用做函数参数
    int a = 5, b = 10;
    // 1. 值传递
    // mySwap01(a, b); // 值没有发生改变, 值传递不改变实参数据 形参不会修饰实参
    // cout << "值传递 交换后 a = " << a << endl;
    // cout << "值传递 交换后 b = " << b << endl;

    // 2. 地址传递 形参会修饰实参
    // mySwap02(&a, &b);
    // cout << "地址传递 交换后 a = " << a << endl;
    // cout << "地址传递 交换后 b = " << b << endl;

    // 3.引用传递 形参会修饰实参
    mySwap03(a, b);
    cout << "引用传递 交换后 a = " << a << endl;
    cout << "引用传递 交换后 b = " << b << endl;
    return 0;  
}

引用做函数的返回值

1.不能返回局部变量的引用

#include<iostream>
using namespace std;

// 引用做函数的返回值
// 1.不能返回局部变量的引用
int &test1()
{
    int a = 10; // 局部变量存放在 栈区
    return a;
}
// 2.函数的调用可以作为左值
int main()
{
    int &ref = test1();
    cout << "ref = " << ref << endl; // 第一次结果正确
    cout << "ref = " << ref << endl; // 第二次结果错误  

    return 0; 
}

在这里插入图片描述

2.函数的调用可以作为左值

#include<iostream>
using namespace std;

// 引用做函数的返回值
// 2.函数的调用可以作为左值
int& test2()
{
	static int a = 10;// 静态变量 存放在全局区 由系统释放
	return a;
}

int main()
{
    int &ref2 = test2();
	cout << "ref2 = " << ref2 << endl; // 第一次结果正确
	cout << "ref2 = " << ref2 << endl; // 第二次结果错误
	test2() = 100; // 函数的调用做左值 ,如果函数的返回值是引用,则该函数调用可以作为左值
	cout << "ref2 = " << ref2 << endl; // 第一次结果正确
	cout << "ref2 = " << ref2 << endl; // 第二次结果错误

    return 0; 
}

在这里插入图片描述

引用的本质

本质:引用的本质在C++内部中本质为 指针常量

常量引用

使用场景:用来修饰形参,防止误操作

#include<iostream>

using namespace std;

void showValue(const int &val)
{
	val = 10000;
	cout << "val = " << val << endl;
}

int main()
{
	// 常量引用
	// 使用场景:修饰形参, 防止误操作

	int a = 10; // 变量a存放在栈区
	// int &ref= 10; 
	// 引用必须引用一块合法的内存空间,若引用数值10时,
	// 10在堆区中,是一个字面量不能直接引用。此时需要添加const关键字
	// 添加const 后编译器将代码修改为用一个临时变量存储 该值, int temp = 10; const int &ref = temp; 但是不能修改
	 // 常量引用
	const int &ref = 20;
	//ref = 30; // 加入const后变为只读,不可修改

	// 修饰形参, 防止误操作
	int b = 100;
	
	// 通过函数打印b
	showValue(b);
	// 因为 showValue(int &val) 是引用传递,因此在函数内可以通过形参来修改实参的值, 此时为了防止数据被修改,将其利用const 修饰形参 避免误操作
	cout << "b = " << b << endl; 
	//cout << ref << endl;
	system("pause");
	return 0;
}

引用与指针区别:

引用:绑定一个对象,必须在定义是赋值,本身不是对象;不能更换对象
指针:指向一个对象的地址,本身为对象,无须在定义时赋值;且允许进行赋值和拷贝;允许更换对象

判断值的真实含义:

右向左阅读定义,离得最近的为其类型
在这里插入图片描述

2.4 const限定符

const 对象必须要初始化
若想在多个文件之间共享 const 对象,需要添加 extern关键字
普通指针只能指向普通常量,const 指针只能指向const常量 且 常量指针不能赋值

顶层const

顶层const 表示指针本身是常量;在进行拷贝时顶层const不受影响
底层const 表示指针指向的对象是常量
简单而言就是可以修改值的const为底层const,不能修改的为顶层const

//顶层const
int i = 0;
int *const p1 = &i; // 不能改变p1的值,为顶层const
const int ci = 42; // 不能改变ci的值,顶层const
const int *p2 = &ci; // 可以修改p2的值,底层const
const int *const p3 = p2; // 左侧的const 为底层,右侧的为顶层
const int &r = di; // 用于声明应用的const均为底层const

consterxpr变量:由编译器验证是否是一个常量表达式,且声明为consterxpr的变量一定是一个常量,必须用常量表达式进行初始化 ^tasctu

2.5 处理类型

C++11 新特性:

别名声明
using SI = XXX; // SI 是XXX的同义词

auto 类型说明符:
编译器通过初始值来推断变量的类型,因此变量必须初始化
decltype类型指示符: 选择并返回操作数的数据类型
decltype((variable)): 结果为引用;
decltype(variable) : 结果为变量,只有当variable为引用(表达式是引用)时,其结果才是引用 ^q1zzxe

auto与decltypye 区别:

1.auto 根据变量的初始值来判断其类型;decltype 根据括号及括号内的内容判断
2.auto 有时候推断的结果和初始值类型不完全一样 会忽略掉顶层const 把底层const保留下来;而decltype则会保留顶层const

typeid().name() 相关缩写类型

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

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

相关文章

一篇搞定CDH 5.x 核心概念与集群部署

一、概述 1.1 Hadoop发行商 Apache:开源免费 CDH: Clouder公司研发。只支持64位操作系统。更加详细信息后面会介绍。 HDP: Hortonworks公司研发。 1.2 公司常用版本及介绍 apache -> cdh | hdp 常见问题&#xff1a; apache与cdh的比较&#xff1f;&#xf…

在国内怎么玩chatgpt,有可行的gpt游玩攻略么

首先你想玩chatgpt&#xff0c;你要明白一点这是一个国外的软件&#xff0c;所以你懂的&#xff0c;如果你不会魔法&#xff0c;那么就必须要改其他途径去探索游玩咯。今天我们就来探讨一下国内怎么玩chatgpt&#xff0c;可行的gpt游玩攻略。 一.Chatgpt的版本 我们先来认识一…

61 openEuler 22.03-LTS 搭建MySQL数据库服务器-管理数据库用户

文章目录 61 openEuler 22.03-LTS 搭建MySQL数据库服务器-管理数据库用户61.1 创建用户示例 61.2 查看用户示例 61.3 修改用户61.3.1 修改用户名61.3.2 修改用户示例61.3.3 修改用户密码61.3.4 修改用户密码示例 61.4 删除用户示例 61.5 用户授权示例 61.6 删除用户权限示例 61…

看完这篇文章你就彻底懂啦{保姆级讲解}-----(面试刷题链表相交) 2023.4.24

目录 前言面试题&#xff08;链表相交&#xff09;—&#xff08;保姆级别讲解&#xff09;分析题目&#xff1a;链表相交代码&#xff1a;算法思想 结束语 前言 本文章一部分内容参考于《代码随想录》----如有侵权请联系作者删除即可&#xff0c;撰写本文章主要目的在于记录自…

LVS负载均衡—DR模式

DR模式的特点 &#xff08;1&#xff09;Director Server&#xff08;调度器&#xff09; 和 Real Server&#xff08;节点服务器&#xff09; 必须在同一个物理网络中。 &#xff08;2&#xff09;Real Server可以使用私有地址&#xff0c;也可以使用公网地址。如果使用公网…

零代码平台如何帮助服装企业实现数字化转型?

随着互联网的不断发展&#xff0c;数字化转型已经成为各行各业必须跨越的一道坎&#xff0c;而服装行业也不例外。 但是&#xff0c;服装行业相对于其他行业来说&#xff0c;数字化转型面临着更多的挑战&#xff1a; 生产环节复杂&#xff1a;服装制造涉及到复杂的生产工序&a…

问题定位及解决方案

1.视频沉浸页快速滑动后&#xff0c;必现不能向下划动 复现步骤&#xff1a; 进入视频沉浸页&#xff0c;快速向下划动&#xff0c;滑动到第一页最后一个时&#xff0c;不能再向下划动。 解决步骤&#xff1a; 1.确定请求API&#xff1a; mtop.aliexpress.ugc.feed.video.lis…

Vivado关联第三方编辑器的方法

​Vivado是一个非常强大的工具&#xff0c;但是在一些方面可能不能完全满足我们的需求&#xff0c;比如代码编辑器的功能。幸运的是&#xff0c;Vivado允许我们关联第三方编辑器来扩展其代码编辑器的功能。在本文将介绍如何配置Vivado与第三方编辑器一起使用&#xff0c;并提供…

Pulsar幂等性开发的设计文档

PIP: https://github.com/apache/pulsar/issues/19744 具体设计 每个TC维护一个Map<ClientName,List> terminatedTxnMetaMap&#xff0c;维护每个客户端最新N个事务的状态&#xff0c;事务结束前&#xff0c;会把事务元数据写入这个List里&#xff0c;同时写入一个Compa…

高分辨率光学遥感图像水体分类综述2022.03

本文是Water body classification from high-resolution optical remote sensing imagery: Achievements and perspectives的学习笔记。 相关资源被作者整理到&#xff1a;这里 文章目录 Introduction基本知识 挑战和机遇挑战1. 有限的光谱信息和小场景覆盖2. 形状、大小和分布…

开放原子训练营(第三季)RT-Thread Nano学习营北京站

开放原子训练营&#xff08;第三季&#xff09;RT-Thread Nano学习营北京站学习心得 文章目录 开放原子训练营&#xff08;第三季&#xff09;RT-Thread Nano学习营北京站学习心得RT-Thread简介会议议程介绍RT-Thread Nano介绍RT-Thread Nano实操训练总结 RT-Thread简介 RT-Th…

【网络安全】XXE--XML外部实体注入

XXE XXE定义XML初识菜鸟xml概念初识DTD解答疑虑1&#xff1a;&#xff01;DOCTYPE是干什么用的疑虑2&#xff1a;&#xff01;ELEMENT是干什么用的疑虑3&#xff1a;#PCDATA是干什么用的疑虑4&#xff1a;为什么元素要再次声明类型 内部实体和外部实体的区别内部实体外部实体通…

【Spring篇】DI相关内容

&#x1f353;系列专栏:Spring系列专栏 &#x1f349;个人主页:个人主页 目录 一、setter注入 1.环境准备 2.注入引用数据类型 3.注入简单数据类型 二、构造器注入 1.环境准备 2.构造器注入引用数据类型 3.构造器注入多个引用数据类型 4.构造器注入多个简单数据类型 …

OAuth2学习(实操OAuth微信登录)

文章目录 前言1 OAuth2基本概念2 网站应用微信登录2.1 大概流程2.2 前期准备2.3 将微信登录二维码内嵌到自己页面2.3.1 后端接口编写(向前端提供参数)2.3.2 前端显示二维码页面 2.4 编写回调接口2.4.1 回调接口根据code获取access_token 这个令牌2.4.2 回调接口根据access_toke…

大数据分析工具Power BI(十三):制作占比分析图表

文章目录 制作占比分析图表 一、饼图 二、环形图 三、树状图

赛题解析 | kaggle百万奖金新赛--图书墨水检测大赛

整理自kaggle平台 比赛题目 Vesuvius Challenge - Ink Detection kaggle-图书墨水检测 比赛背景 赫库兰尼姆卷轴中使用的墨水在X射线扫描中不容易显示出来。但我们发现机器学习模型可以检测到它。幸运的是&#xff0c;我们有地面实况数据。自从近300年前发现赫库兰尼姆Papyr…

【K8S系列】深入解析Service

序言 Dont count the days. Make the days count 不要数着日子。让日子过得有意义 文章标记颜色说明&#xff1a; 黄色&#xff1a;重要标题红色&#xff1a;用来标记结论绿色&#xff1a;用来标记一级论点蓝色&#xff1a;用来标记二级论点 Kubernetes (k8s) 是一个容器编排平…

React 组件 API

常用 React 组件 API&#xff1a; 设置状态&#xff1a;setState替换状态&#xff1a;replaceState设置属性&#xff1a;setProps替换属性&#xff1a;replaceProps强制更新&#xff1a;forceUpdate获取DOM节点&#xff1a;findDOMNode判断组件挂载状态&#xff1a;isMounted …

基础自动化测试脚本开发——Loadrunner网页系统两种创建关联函数的方法详解

前言 许多的系统都采用SessionID或SeqID等方法来标识不同的任务和数据报&#xff0c;应用在每次运行时发送的数据并不完全相同。所以&#xff0c;为了让脚本能够支持测试的需求&#xff0c;就必然要用某种机制对脚本的数据进行关联了。总之一句话&#xff1a;通过关联可以在测试…

AOD实践,modis数据下载,modis数据处理

modis数据下载-数据读取-重投影-拼接-均值 一、数据下载 1、Cygwin安装 Cygwin安装教程&#xff1a;https://blog.csdn.net/u010356768/article/details/90756742 1.2 数据采集 现提供遥感数据下载服务&#xff0c;主要是NASA数据&#xff0c;数据下载网站包括&#xff1a…