【C深度解剖】const关键字

简介: 【C深度解剖】const关键字

下面是本节博客的大纲梳理:

引言

本节博客是围绕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++里面好像还有补充,那又是另一个话题了。


完。

相关文章
|
4月前
|
存储 编译器 C++
【C++】深度解剖多态(下)
【C++】深度解剖多态(下)
54 1
【C++】深度解剖多态(下)
|
4月前
|
Java 编译器 C++
【C++】深度解剖多态(上)
【C++】深度解剖多态(上)
55 2
|
4月前
|
存储 Java 程序员
【c++】继承深度解剖
【c++】继承深度解剖
36 1
|
4月前
|
存储 算法 编译器
【C++11】C++11深度解剖(下)
【C++11】C++11深度解剖(下)
38 0
|
4月前
|
存储 安全 程序员
【C++11】C++11深度解剖(上)
【C++11】C++11深度解剖(上)
38 0
|
6月前
|
算法 Serverless 数据安全/隐私保护
【C++ 函数 基本教程 第三篇 】深度解析C++函数类型:探寻全局函数、成员函数与静态函数的奥秘
【C++ 函数 基本教程 第三篇 】深度解析C++函数类型:探寻全局函数、成员函数与静态函数的奥秘
424 1
|
6月前
|
安全 算法 Java
【C++ 友元的运用】C++深度解析:友元关系的奥秘与挑战
【C++ 友元的运用】C++深度解析:友元关系的奥秘与挑战
138 0
|
存储 C语言
C语言深度解剖-关键字(4)
C语言深度解剖-关键字(4)
76 0
C语言指针深度解剖
对C语言的指针进行深入学习
C语言指针深度解剖
|
C语言 C++
C语言深度解剖-关键字(5)
C语言深度解剖-关键字(5)
72 0