C++中const,指针和引用

这篇具有很好参考价值的文章主要介绍了C++中const,指针和引用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C++中的const,指针和引用

在线C/C++编译器,可以试着运行代码。

C++中的const

在C语言中,const修饰的量称为常变量(在编译过程中,const就是当成变量的编译生成指令的),不可以直接修改它的值,但是可以通过地址进行修改其对应的值。并且const修饰的变量可以不进行初始化,编译器最后默认赋值为0。

#include <stdio.h>
void main()
{
    const int a = 10;
    // a=30; a不能直接作为左值修改其值
    int *p = (int *)&a; // p指向a的地址,所以后面通过指针可以修改地址的值 //理论上来说是错误的,int* <- const int* 这种转化不支持,但是编译器确实通过了
    *p = 30;
    printf("%d,%d,%d", a, *p, *(&a)); // 30,30,30
    const int i;
	printf("%d",i); // 0
}

然而在C++中,这个一样的代码就会出现不一样的结果:

#include<iostream>
using namespace std;

int main()
{
    const int a = 10;
    // a=30; 不能直接作为左值进行修改其值
    int *p = (int *)&a; //理论上来说是错误的,int* <- const int* 这种转化不支持,但是编译器确实通过了
    *p = 30;
    cout << a << "," << *p << "," << *(&a) << endl; // 10,30,30 在编译过程中会直接替换a为10
    // const int i; C++中const必须初始化,也成为常量
    int array[a]; // a是常量,座椅所以可以初始化数据长度
    int b = 20;
    // int test_array[b]; b是变量,所以不能直接初始化数组长度
    return 0;
}

这是因为在C++中const修饰的变量在编译过程中会将const修饰的值直接替换为对应的值。

C++中const修饰的量称为常量必须进行初始化,不可以直接修改它的值,但是可以通过地址进行修改其对应的值

C++引用

C++引用又可以分为左值引用和右值引用

  • 左值,它有内存,有名字,值可以修改
  • 右值,没内存,没名字
  • 一个右值引用变量,其本身是一个左值

以下举例进行说明:

int i = 10; // i是一个左值,有内存,有名字,值可以修改
int &j = i; // j左值引用变量

// int m = &20; 20是一个右值,没内存,没名字
int &&m = 20;// 可以使用右值引用
m = 30;
// int &&n = m; n是一个右值引用变量,但是它本身是一个左值
int &n = m;

const int &k = 20; // int temp=20;const int &k=temp;这个代码的编译过程和int &&m=20;一样,不过m可以被修改而k不能被修改
// k = 30; k是常量,不能被修改

C++中指针和引用的区别

  1. 引用是一种更安全的指针。
  2. 引用必须初始化,指针可以不初始化。
  3. 引用只有一级引用,没有多级引用;指针可以有一级指针,也可以有多级指针。
  4. 定义一个引用变量和定义一个指针变量,其汇编指令是一模一样的;通过引用变量修改所引用的内存的值,和通过指针解引用去修改指针所指向的内存值,其底层指令是一模一样的。
int a = 0;
int b = 10;
int &c = a;
// int &d; 引用必须要初始化
int *d = &b;
int *e;                                    // 指针可以不初始化
c = 20;                                    // c就相当于a的别名,
cout << a << "," << b << "," << c << endl; // 20,10, 20
*d = 30;
cout << a << "," << b << "," << *d << endl; // 20,30, 30

函数传值和传引用的区别

#include<iostream>
using namespace std;

void swap_comm(int x,int y)
{
    int temp = x;
    x = y;
    y = temp;
}
void swap(int *x,int *y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}
void swap(int &x,int &y)
{
    int temp = x;
    x = y;
    y = temp;
}

int main()
{
	int array[10] = {};
    int *a_p1 = array;// 指针指向数组的首地址
    int (&a_inf)[10] = array;//定义一个引用变量来存储array,也就是别名
    cout << sizeof(array) << "," << sizeof(a_p1) << "," << sizeof(a_inf) << endl; // 40,8,40

    int a = 0;
    int b = 10;

    cout << a << "," << b << endl; //0,10
    swap_comm(a, b);//传值,没啥用,会新建临时变量,更改的只是临时变量的值,不会更改a,b的值
    cout << a << "," << b << endl; // 0,10
    swap(a, b);//传引用
    cout << a << "," << b << endl; // 10,0
    swap(&a, &b);//传指针
    cout << a << "," << b << endl; // 0,10

    return 0;
}

C++中const和一二级指针的结合使用

C++中const修饰的量叫做常量,和普通变量的区别在于:1、编译的方式不同,直接替换程序中出现的名字。2、不能作为左值,也就是不能重新直接修改它对应的值,但是可以通过指针修改它的值。

const修饰的量(常量)常出现的错误是:

  • 常量不能在作为左值,直接修改常量的值。
  • 不能把常量的地址泄露给一个普通的指针或者普通的引用变量。

const和指针联用的情况,const修饰的是离它类型最近的类型:

const int *p; //可以指向其他内存的地址,但是不能用指针间接修改其对应的值,p=&a;√ *p=a;×
int const* p;
//上面两个是一样的,不过常用第一种

int *const p; //指针p是常量,不能指向其他内存,但是可以通过指针间接修改内存所指向的值 *p=a;√ p=&a;×

const int *const p;//既不可以修改p指针,也不可以通过指针修改指向的内存

const和指针类型转化

int* q1 = nullptr;
int* const q2 = nullptr; // const右边没有*,则不参与类型
// int*,int *
cout << typeid(q1).name() << "," << typeid(q2).name() << endl;

int a = 10;
int* p1 = &a;
const int* p2 = &a; // const int* <- int*
int* const p3 = &a; // int*       <- int*
int* p4 = p3;       // int*       <- int*

// const int** m = &p; // const int ** <= int **

总结const和指针的类型转化公式:

int* <= const int* 不可以的
const int* <= int* 可以的
const int** <= int** 不可以的
int** <= const int** 不可以的
int** <= int* const* 等价于 int*<=const int*  不可以的
int* const* <= int** 等价于 const int* <=int* 可以的

C++ 底层const二级指针为何能被非const指针初始化? - 张三的回答 - 知乎解释了二级指针和二级常量指针的转化问题。

int* p = nullptr;
const int** cpp = &p; //假如这行代码是正确的...,那么后面 *cpp=&ci;就会出现问题

const int ci = 0;
*cpp = &ci; // const int* *cpp=const int* ci;看上去没有问题,但是 *cpp本质上就是p,而p指向了ci的地址,就出现了int* <- const int*

const,指针,引用判断正误

以下简要说明const和二级指针的用法问题

/*
int a = 10;
const int* p = &a; // const int* <- int*
int* const* q = &p; // int* const* <- const int **;等价于int* <- const int*。错误
*/

/*
int a = 10;
int*const p = &a; // int* <- int*;
int** q = &p;//int** <- int* const*;错误,因为p取了地址,所以需要考虑const
*/

/*
int a = 10;
int* p = &a; // int* <- int*;
int** const q = &p;//int** <- int**;
*/

/*
int a = 10;
int* p = &a; // int* <- int*;
int* const* q = &p;//int* const* <- int**;
*/

/*
int a = 10;
int* p = &a; // int* <- int*;
const int** q = &p; // const int ** <- int**; 错误,不支持转化
*/

/*
int a = 10;
int* const p = &a; // int* <- int*;
const int* q = p; // const int* <- int*
*/

/*
int a = 10;
int* const p = &a; //int* <- int*; const后面没有*所以不参与类型转化
int* const q = p; //int* <- int*
*/

/*
int a = 10;
int* const p = &a; //int* <- int*; const后面没有*所以不参与类型转化
int* q = p; //int* <- int*
*/

/*
int a = 10;
const int* p = &a; //const int* <- int *;
int* q = p; //int* <- const int*;错误
*/

const和一级指针和引用结合的代码分析:文章来源地址https://www.toymoban.com/news/detail-646301.html

int a = 10;
int* p = &a;
const int*& q = p; //const int** q=&p=int** p;错误

int a = 10;
const int*  p = &a;
int*& q = p;//int** q=const int** p;错误

int a = 10;
int* const p = &a;
int*& q = p; //int** q=int* const* p; 错误
//或者 int**q=&p;p是const修饰的量,不能将其地址赋值给普通变量

int a = 10;
int* p = &a;
int*& q = p; //int** p=&q;
//写一句代码,在内存的0x0018ff4处写一个为4字节的整数10;
int* p = (int*)0x0018ff4;
*p = 10;

int a = 10;
int* p = &a;
int** q = &p;
int*& m = p; // int** m=&p;还原回来就是这样的

//判断是否正确
//const int*& k = p; // const int** k=&p; const int** <- int**;所以是错误的  

到了这里,关于C++中const,指针和引用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C语言】const修饰普通变量和指针

    大家好,我是苏貝,本篇博客带大家了解const修饰普通变量和指针,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 用const修饰普通变量时,是在语法层面限制了变量的修改,但是本质上,变量还是变量,是一种不能被修改的变量。以下两种定义方式都可以:

    2024年02月12日
    浏览(46)
  • C++教程——const修饰指针、结构体、文件操作

    读取数据的方式 写文件 读文件

    2024年02月13日
    浏览(33)
  • C++学习笔记---- 引用

    给变量起别名 基本语法:数据类型 别名 = 原名 示例: 引用必须初始化 引用在初始化后,不可以改变 int c; //错误,引用必须初始化 示例:   作用:  函数传参时,可以利用引用的技术让形参修饰实参 优点:   可以简化指针修改实参 示例: 作用:  引用是可以作为函数的

    2024年02月11日
    浏览(34)
  • 【C语言趣味教程】(5) 常量:字面常量 | 类型常量 | const 关键字 | const 的声明 | 程序中的只读概念 | const 保护机制 | 如何巧妙区分 “指针常量“ 和 “常量指针“

        🔗 《C语言趣味教程》👈 猛戳订阅!!! ✨ 专栏介绍 / 总目录: 【C语言趣味教程】(0) 导航篇 ​ —— 热门专栏《维生素C语言》的重制版 —— 💭 写在前面: 这是一套 C 语言趣味教学专栏,目前正在火热连载中,欢迎猛戳订阅!本专栏保证篇篇精品,继续保持本人

    2024年02月15日
    浏览(44)
  • 计算机语言 之【C++】入门级知识讲解(命名空间,C++输入输出,缺省参数,函数重载,引用,内敛函数,auto关键字,for循环,指针空值nullptr)

    三点睡六点起,阎王夸我好身体 不到三点我不睡,太平间里抢C位 目录: 前言: 本片博客是以学习过C语言之后进入C++学习为前提,讲解C++入门级知识,为C++之后的学习做铺垫 –❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀-正文开始-❀–❀–❀–❀–❀

    2024年04月11日
    浏览(127)
  • [开发语言][c++]:左值、右值、左值引用、右值引用和std::move()

    写在前面: 如果你也被 左值、右值、左值引用、右值引用和std::move 搞得焦头烂额,相关概念和理解不够深入,或者认识模棱两可,那么这篇文章将非常的适合你,耐心阅读,相信一定会有所收获~~ 左值: 可以取地址、位于等号左边 – 表达式结束后依然存在的持久对象

    2024年02月02日
    浏览(60)
  • 【C++】C++ 引用详解 ⑦ ( 指针的引用 )

    指针的引用 效果 等同于 二级指针 , 因此这里先介绍 二级指针 ; 使用 二级指针 作为参数 , 可以实现如下功能 : 动态内存管理 : 借助二级指针 , 可以在函数中分配或释放内存 ; 如 : 创建一个动态数组或调整现有数组的大小 , 在函数中需要一个指向指针的指针作为参数 , 以便修

    2024年02月11日
    浏览(36)
  • C++ 指针学习笔记

    指针是一个变量,其值为另一个变量的地址。 指针声明的一般形式为: type 是指针的基类型, ptr_name 是指针的名称, * 用来指定一个变量是指针 对于一个指针,需要明确四个方面的内容: 指针的类型 、 指针所指向的类型 、 指针的值 ( 指针所指向的内存区 )、 指针本身

    2024年02月05日
    浏览(48)
  • C++学习笔记——指针

    指针的作用: 可以通过指针间接访问内存 内存的编号是从0开始记录的,一般用十六进制数字表示 可以利用指针变量保存地址 上图中的p就是a变量的指针,也可以记作*a 指针变量定义语法: 数据类型*变量名; *p——解引用的含义,可以通过指针来保存一个地址:  指针与数

    2024年01月23日
    浏览(38)
  • C++学习笔记——对象的指针

    目录 一、对象的指针 二、减少对象的复制开销 三、应用案例 游戏引擎 图像处理库 数据库管理系统 航空航天软件 金融交易系统 四、代码的案例应用 是一种常用的技术,用于处理对象的动态分配和管理。使用对象的指针可以实现以下几个方面的功能: 动态分配对象:通过

    2024年02月03日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包