下面是本节博客的大纲梳理:
引言
本节博客是围绕const为主题进行详细说明的,不知道大家是否知道,在公司招聘中,C语言知识关键字部分经常被问到的关键字就是const,也就是说const常用且细节比较多,下面且听我一一道来。
1.const概念
注:这里只是告诉大家const大概的这个属性是这样的,具体会在2.const常见用法中进行详谈。
简介:const首先是一个C中的常用关键字,用来在编译器层面(语法层面)约束修饰对象防止被修改,是一种假常量式防修改,约束性较弱。(这里所说的假常量和弱约束性大家可能不理解,继续往下看会有解释。)
下面对我所说的约束性强弱问题进行解释:在我们计算机当中,其实约束性这个概念并不陌生,比如我们对一个常量字符串进行修改的话,计算机是不允许的,就算编译器没有报错允许编译,那么我们操作系统也不会允许被修改,因为常量字符串存储在我们内存中的常量数据区,这块内存是不可被修改的,这也相对来说属于一种强的约束性。而上面我所说的const关键字具有弱约束性的意思就是,虽然const+变量表示不可以修改,但是也只是处在编译器角度来说的,只是告诉编译器帮我检查一下我往后的代码哈,不能修改该变量哈,如果我修改了告诉我一下哈。大概是这个样子。虽然编译器帮你检查是否修改并且可以为你提供一些警告甚至报错,但是我们仍然可以通过其他方式对该变量的值进行修改,比如指针的方式。
同理,我上面所说的假常量也跟弱约束性一样的意思,不允许就该的数据我们称为常量,但是const+变量表面看起来不可以被修改,实际上,完全可以通过其他方式进行修改。
书写位置:在理论上而言,const书写在类型前后均可,因为const是对变量起作用,也是语法规定。
2.const的常见用法
2.1 const修饰变量
常见用法:const+变量,修改变量内容,报错。
但前面也说了,const关键字对修饰对象是一种弱修饰,那么const+变量,该变量按照我上面的意思也是可以进行修改的:const+变量,该变量不可被直接修改,但是可以被间接修改。
这样的话,const修饰的变量可以被间接修改,那有同学可能会疑惑,如果这样做,const的意义何在呢?
1.让编译器进行直接修改式检查:让编译器意识到要提示你一下。
2.提示程序员该变量不可被修改:属于一种程序员自己看的标识符。
const修饰的变量并不是真正的常量值。
我们知道,数组的【】内需要一个固定的数字,但是const修饰的变量放进去仍会报错(vs)。
2.2 const修饰数组
const修饰数组的话基本跟修饰变量是一样的,会把数组变成只读数组。
这里其实是可以修改的,算是一种提示吧。
2.3 const修饰指针
const放在指针变量的✳号前,表示该指针变量不可以解引用,如果放在✳号后,表示该指针变量的内容不可以改变。
也就是说,const对于指针而言,✳号是分界线
如果const修饰指针都在*号前进行修饰,编译器会提示:
const修饰指针有四种形式(注:我这里以下面代码为例)
int main() { int a = 10; int b = 20; //const int const * p = &a; //int const * p = &a; //int * const p = &a; //const int * const p = &a; //*p = 30; //p = &b; return 0; }
分别如下:
1.const int* p = &a;这里表示p不可以解引用
2.int const * p = &a;这里与1同理,不再细说。
3.int * const p = &a;这里表示p指针变量的内容不可以改变。
4.const int* const p = &a;这里表示指针变量p既不可以解引用,p也不可以更改指向的空间。
相关概念拓展:
拓展1:指针与指针变量的概念区分:
指针:指针就是地址,地址就是内存编号。
指针变量:指针变量属于一种指针类型的变量,跟整型变量浮点型变量同一个级别。
指针(地址)的意义:指针的意义在于提升搜寻效率。
有同学可能比较好奇地址有啥意义啊,这里简单解释一下,在C语言中,C制造者为了学术化一点,把内存地址说为指针,这样更加学术化一点吧。指针(地址)的意义呢,大概就是你网购填你家地址的那个情况差不多,如果说世界上没有什么国、什么省…这些地名的话,你在哪里都会说不清楚,而且如果有人要找你,比如快递员要给你送快递,你怎么告诉他你在哪里?当然,这里有个比较笨的方法,就是快递员走遍全世界肯定能够找到你,但是成本代价太大了,计算机的内存地址意义就是如此。指针的意义在于提升搜寻效率。
然后指针变量跟指针他就不是一个概念,很多人或者书上都将两者混为一谈,让你在开始学习指针的时候就开始懵比。所谓指针变量,是专门用来存储内存地址的变量。
每一个字节都有属于自己的指针,那么多指针(地址)需要进行存储吗?不需要哈。计算机硬件约定俗成。
拓展2:左值与右值的概念
我估计这俩词很多敲代码的人并不陌生,反正是经常见(比如下图),但是具体啥意思并不清楚,这里来给大家解释一下。
左值:指的是变量空间的意思
右值:指的是数据的意思
比如拿下面这个代码举例:
那你可能大概理解了,不过这里再深入说一下,左值并不是指一个变量,右值并不等同于一个数值。左值更侧重于内存空间的概念,上面代码中int a是开辟空间的意思,而右值更侧重数值的概念,上面代码中10就是一个数值。
同一个标识符在不同的场景下不一定为左值/右值,比如下面的a在上面属于左值,在下面又属于右值了:
情况1:把const修饰的指针变量的内容赋给没有const修饰的指针变量,会有警告。
情况2:把没有const修饰的指针变量的值赋给有const修饰的指针变量的值没有警告。
上面的原因有点离谱,一般来说只要等号的左右两边的类型不同,编译器就会警告我们,但是这个const修饰的指针情况…怎么有一个没有警告呢?
const限制赋给不限制时,会有警告;const不限制赋给限制,没有警告。
这里解释一下,首先我们需要明白,编译器警告是出于安全考量,也就是说,如果你的代码变得更加“安全”的话,就不会警告了。const限制相对于const不限制一个变量而言,你把不限制变成限制更安全,因而情况1没有警告,而你把限制变成不限制,也就是有些权限被放开了,也就变得不太“安全”了起来,自然编译器会进行警告。
2.4修饰函数的参数
首先大家得了解形参跟实参的关系,形参是实参的一份临时拷贝。
然后,既然是临时拷贝,对于指针情况来说,如果指针被修改了就不好了,所以说const的意义就是防止在调用其他函数时候把原本的值给搞坏了。
比如下面的代码示例:
void test(const int* a) { printf("%d\n", *a); } int main() { int a = 100; test(&a); return 0; }
2.5 const修饰函数的返回类型
也是用来提示程序员,不可以修改该返回值哦,为了代码规范性,应该这样写:
不过对于内置类型而言(int,float…),返回类型是否加const并没有什么意义。
3.const意义
==const的意义在于帮助程序员检查错误。==上面概念部分关于const意义说的更详细一些,可以好好看看上面const概念部分。
说了这么多,其实大概大家就可以了解C中的const了,不过吧…c++里面好像还有补充,那又是另一个话题了。
完。