asp网上书店网站开发,做网站的内容样本,网站黑色代码,如何做好品牌宣传工作今天我们来探讨C/C中const、指针和引用的相关问题。这些概念是编程中的重要组成部分#xff0c;它们的正确使用对于代码的可读性和可维护性至关重要。通过深入了解const的不可变性、指针的灵活性以及引用的简洁性#xff0c;我们能够更好地掌握编程的精髓#xff0c;并写出更…今天我们来探讨C/C中const、指针和引用的相关问题。这些概念是编程中的重要组成部分它们的正确使用对于代码的可读性和可维护性至关重要。通过深入了解const的不可变性、指针的灵活性以及引用的简洁性我们能够更好地掌握编程的精髓并写出更加健壮和高效的代码 浅谈C/C 1const 一级指针2const 二级多级指针3引用操作符 先来看看对const的描述C/C中的const关键字用于声明一个常变量即一个“不可修改的值”通过使用关键字const我们可以明确地指定一个变量、函数参数、函数返回值或类成员函数为只读从而禁止对其进行修改增强程序的健壮性。可见我们对于 const 的描述常见为一个不可修改但在C和C中编译器对于 const 的反应也是 有差异的 1、我们先来看看.c文件 -》 C语言中的const猜猜有何问题 #includestdio.h
int main()
{const int a;int array[a] { 0 };const int b 0;b 5;int* p (int*)a; *p 30;printf(%d %d %d\n, a, *p, *(a));
}我们不难想到 array[a] 会报错因为a没有被初始化定义数组需要有一个常量值作为数组的长度而a不可推测b 5变量b为常变量不可被修改然而对于涉及到变量p的语句朋友是否有些疑惑p是指向变量a地址的普通指针而*p 30就是将它指向的地址上对应的值改为30即分配给变量a的地址空间中的值 被改了我们去掉错误语句加上a 20后看看执行的结果 由此可见我们可以归纳出 C语言编译器 下有关const的特性 在C语言编译器中
a) const修饰可以不进行初始化被看作常变量
b) 被const修饰的变量只是不能作为左值被修改通过指针或引用的方式能够修改2、我们再来看看.cpp文件 -》C语言中的const猜猜有何问题 int main()
{const int b;int c 5;const int a c;//const int a 20;int array[a] { 0 };int before a;int* p (int*)a; *p 30; int after *(int*) a;cout before endl after endl; cout a *p *(a) endl;return 0;
}不难想到 const int b;会报错因为在C中const修饰的变量被看作常量不能够不对它进行初始化在array[a]报错变量a为变量c赋值而来而c是一个变量赋给变量a后变量a也作为变量而array[]里需要一个常量所以出现错误如下图 除去错误语句把const int a 20后的执行结果 由此我们可以了解到 在C语言编译器中
a) const修饰的变量必须初始化不能作为左值
b) 被const修饰的变量只是不能作为左值被修改通过指针或引用的方式能够修改
c) 被const修饰的变量被叫做常量若直接赋值一个变量不能直接作为数组的长度
c) 在C编译器中执行程序遇到const变量的时候会直接被看作是常量直接用初值替换即*(a) - 20本来我们使用const修饰变量的目的就是保证变量不被修改然上面我们能够看到如果我们把一个常量的地址泄露给了一个普通指针或者引用那么就会有被修改的风险因此我们需要对此问题做相应的处理也就是下面我们将要介绍的 const 指针的结合
注意在C语言规范中const修饰的类型是离它最近的类型
1const 一级指针
我们先来看看一级指针 const的情况如下
//根据上面的注意项有
const int *p; - const修饰int即值*p不可修改指针可以任意指向p a
int const *p; - const修饰int同上
int* const p; - const修饰int*即指针指向p不可修改值*p可以任意
int* const *p; - const同时修饰int*和int都不能修改看到这我们就能够自己解决当泄露了常量的指针或引用时常量可能被修改的问题。但是对于const和指针的各种组合类型中也并非都能够相互进行强制转化的。
这里又需要注意一点const右边如果没有指针*的话const是不会参与进推测的类型
int* q1 nullptr;
int* const q2 nullptr;
const int* q3 nullptr;
int const* q4 nullptr;
int* const* q5 nullptr;
cout typeid(q1).name() endl; // - int*
cout typeid(q2).name() endl; // - int*
cout typeid(q3).name() endl; // - const int* / int const*
cout typeid(q4).name() endl; // - const int* / int const*
cout typeid(q5).name() endl; // - int* const*
//以上代码朋友可以自己去验证一下是否正确这里我们再给出一段代码来看看是否正确 #includeiostream
using namespace std;int main()
{int a 5;const int* pp a;//const int* pp nullptr;int* qq p;//cout typeid(pp).name() endl;char s a;const char* ss s;char* sss ss;return 0;
}整形常量指针p指向的是普通变量a的地址整形变量指针qq指向p也是普通变量a的地址既然是普通变量那么普通变量a的值应该是能被修改是吧然当我们放在visual studio 2022上时发现它报错了其实这更变量a无关若我们将pp指向nullptr仍然是一样的结果。因为在类型上编译器是禁止将 const int* 类型的数据转换成 int* 类型的使用char等其他类型也是如此 2const 二级多级指针
我们再来看看const 二级多级指针的情况如下
const int**q; - **q 不能被赋值
int* const *q; - *q 不能被赋值
int** const q; - q不能被赋值注意对于const 多级指针 的结合涉及到类型转化时
错误const int* - int* ;int** - const int** ;int* const* - int** //const修饰一级指针《》 const* - *《》 const int* - int* 是错误的const int** - int** ;正确int* - const int* ;int** - int* const* 《》 * - const*《》 int* - const int* 是正确的 这里我们给出一段代码来看看是否正确 #includeiostream
using namespace std;
int main()
{int a 10;int* p a;const int **q p; // const int** - int**return 0;
}这里我们可以把换换const int* *q即*q是整形常量的指针 《》p所以当我们把一个整形常量的地址赋值给*q时const int b 20; *q b相当于直接就修改了p使其指向了常量的地址把变量b的指针间接地泄露给了普通指针*p系统报错 — 解决方法const int* const*q p; 我们让其不能够给*q赋值即禁用*q b 3引用操作符
引用是C种的一种特殊数据类型它提供了对现有别名的访问通过引用可以使用相同的变量名来访问同一个内存地址的内容一旦被初始化后它将一致引用同一个对象并且不能再引用其他对象因此引用也被叫做更安全的指针对比一下指针和引用的区别
引用是必须初始化的指针可以不被初始化引用只有一级而指针有多级在汇编层面上定义或修改引用变量和指针变量是一样的 从以下代码即图例可以看出 #includeiostream
using namespace std;
void swap(int a, int b) { int t a; a b; b t; } //引用底层还是转化为指针实现
void swap(int* a, int* b) { int t *a; *a *b; *b t; }int main()
{int a 10, b 20;swap(a, b);swap(a, b);int *p a;int q a;int array[5] {};int (vv)[5] array;return 0;引用又可分为两种左值引用 和 右值引用
左值引用 对象的一个命名引用它绑定到左值如一个具名变量即有名字、有内存通过左值引用可以修改被引用对象的值。右值引用 对临时对象或将要销毁的对象的引用它绑定到右值如一个临时对象一个匿名对象或一个将要销毁的对象通过右值引用可以实现资源的高效转移和移动语义
#includeiostream
using namespace std;
{int a 10;//int b a; //错误右值引用变量无法绑定到左值int c 20; //c11提供了右值引用汇编指令上产生临时量const int d a; //左值引用可以指向左值int e a;int f c; //右值引用本身是一个左值return 0;注意左值引用变量能够拥有右值和左值但右值引用变量只能引用右值
上面就是关于const 、 指针 、 引用的问题学而不思则罔思而不学则殆下面给出几道题目来检验一下我们的学习成果
A) int a 10const int *p aint *q p xxx
B) int a 10int* const p aint *q p gggC) int a 10int* const p aconst int *q p gggD) int a 10int *p aconst int **q p xxxE) int a 10int *p aint* const* q p gggF) int a 10int *p aint ** const q p gggG) int a 10int* const p aint **q p int** - int* const*xxxH) int a 10const int*p aint* const* q p int* const* - const int**《》 int* - const int*xxx引用是不参与推测类型的I) int a 10int *p aint *q p 《》 int **q pgggJ) int a 10int* const p aint *q p 《》 int **q pxxxK) int a 10int *p aconst int* q p; 《》 const int**q pggg 以上就是浅谈C/C的常量const、指针和引用的有关问题如果聪明的你浏览到这篇文章并觉得文章内容对你有帮助请不吝动动手指给博主一个小小的赞和收藏