正如前面几个关键字volatile\static\extern 在平时项目开发中,自己曾经用过。

但是const这个关键字自己从来没用过, 对const的概念,就知道他是修饰常量的。

对于他的使用场景,怎么使用,说不上来。今天在此学习下。

 

一、const是什么

       const是C语言中的一个关键字,是定义只读变量的关键字。但是一个变量经过const的修饰后,不仅拥有常量的属性,又有变量的属性,所以又说const是定义常变量的关键字。

二、const的用法

const修饰时比较灵活,可能因为位置的不同起到不同的效果。

1、用来修饰变量(指针变量除外)

        在修饰变量(指针变量除外)的时候,const type name 和 type const name 这两种形式是完全一样的表示 name 是常变量。 此时无法直接修改 num,但是可以通过指针变量的形式来修改。

         无法直接通过修改 num来改变。
#include<stdio.h>
int main()
{
    const int num = 10; //const修饰之后,num是常变量
 
    //num 具有常量的性质
    num = 20;    //报错,因为num具有常量的性质,因此无法重新进行赋值。
    printf("num=%d", num);  
 
    return 0;
}

此时编译器会显示错误,提示表达式必须是可修改的值。错误如下:

 通过指针变量来进行修改num的值。

#include<stdio.h>
int main()
{
    const int num = 10; //const修饰之后,num是常变量
 
    //num具有变量的性质-通过指针的形式修改 num 的值
    int* p = &num;
    *p = 20;
    printf("num=%d\n", num);
    return 0;
}

此时输出结果如下:

 

2、用来修饰指针变量

         const用来修饰指针变量时分为两种情况:一种是const位于' * '的左边,另一种是const位于' * '的右边。

(1)当const位于' * '的左边,即 const type* name 和 type const *name 这两者是完全一样,无任何区别。这种情况下 const 修饰的是 name 指向的对象无法修改,但可以修改指针变量。

#include<stdio.h>
int main()
{
    int num = 10;//创建一个 num 的临时变量
    int n = 20;
    const int* p = &num;//将 num 这个临时变量的地址传给 p
 
    //无法修改指针变量所指向的对象
    //*p = 20;
    //printf("%d\n", *p);//报错
 
    //可以修改指针变量
    p = &n;//修改了指针变量,即 p 存放的是 n 的地址
    printf("num=%d  n=%d  *p=%d\n",num,n, *p);
 
    return 0;
}

指针变量指向的对象无法修改

 可以修改指针变量       

 

综上所述我们可以得到结论当const关键字放在*号的左边时修饰的*p,也就是说限制的是p所指向的对象,即p所指向的对象不能被修改。也就是*p不能在进行赋值, 但是p=&是可以进行修改的。

 

(2)当const位于' * '的右边,即 type* const name 。这种情况下无法修改指针变量, 但可以修改指针变量指向的对象。

#include<stdio.h>
int main()
{
    int num = 10;//创建一个 num 的临时变量
    int n = 20;
    int* const p = &num;//将 num 这个临时变量的地址传给 p;
 
    //无法修改指针变量
    //p = &n;
    //printf("%d\n", *p);//报错
 
    //可以修改指针变量所指向的对象
    *p = 200;//通过修改指针变量所指向的对象,改变了 num 的值
    printf("num=%d  n=%d  *p=%d\n", num,n,*p);
 
    return 0;
}

无法修改指针变量

 可以修改指针变量指向的对象

 const放在*号的右边时(int * const p)此时限制的就是p,此时p所指向的地址里的内容是可以进行修改的,也就是说*p是可以修改的,但是p所存放的地址不能被修改,也就是p = &(其它变量)不能改

 

(3)综上两种情况,若想无法修改指针变量也无法修改指针变量指向的对象,那么应该写成:const type* const name 。

看到这个地方,是不是对const有点感觉了。const修饰的是变量,它对应的值不能变。(但是可以通过其他方式来修改,并不是说他完全就是常量,不能修改)

 

3. const关键字的使用注意事项

在使用const关键字时,需要注意以下几点:

    (1)const关键字必须与类型说明符放在一起,这意味着它必须位于变量名之前。 并且因为修饰变量的只可读属性,所以必须进行初始化。
   (2) const关键字只是意味着变量的值不可改变,但并不是说该变量所在的内存区域也不可修改。因此,在使用const指针时,需要注意指针本身的值可以修改,但指向的变量不能修改。
    (3)在函数参数中使用const关键字时,需要注意函数内部不能修改该参数的值,否则会导致编译错误。

   (4) 从上面介绍来看,const可以骑其他几个关键字同时联合使用。他只是用来修饰变量的可读属性。

  (5)const修饰局部变量,并不会改变局部变量的存储区域,还是在栈区。

    (6)const 推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点。

(7)用 const 修饰后和未修饰前有什么区别呢? 用 const 定义的变量的值是不允许改变的,即不允许给它重新赋值,即使是赋相同的值也不可以。所以说它定义的是只读变量。这也就意味着必须在定义的时候就给它赋初值。

无论是全局常变量还是局部常变量都必须初始化赋值。

 

.const 与 define 的区别

从功能上说它们确实很像,但它们又有明显的不同:
1.#define 是预编译指令,而 const 是普通变量的定义,#define 定义的宏是在预处理阶段展开的,而 const 定义的只读变量是在编译运行阶段使用的。


2.const定义的是变量,而 define定义的是常量。define定义的宏在编译后就不存在了,它不占用内存(因为他是直接替换),因为它不是变量,系统只会给变量分配内存。

  但 const 定义的常变量本质上仍然是一个变量,具有变量的基本属性,有类型、占用存储单元。可以说,常变量是有名字的不变量,而常量是没有名字的。有名字就便于在程序中被引用,所以从使用的角度看,除了不能作为数组的长度,用 const 定义的常变量具有宏的优点,而且使用更方便,所以编程时在使用 const和 define都可以的情况下尽量使用常变量来取代宏。


3.const定义的是变量,而宏定义的是常量,所以const 定义的对象有数据类型,而宏定义的对象没有数据类型。所以编译器可以对前者进行类型安全检查,而对后者只是机械地进行字符替换,没有类型安全检查。这样就很容易出问题,即"边际问题”或者说是“括号问题"

                        

帖子:

https://blog.csdn.net/qq_53286439/article/details/129825603

https://blog.csdn.net/m0_73223961/article/details/132650588

https://blog.csdn.net/TiSg0/article/details/130398127

https://blog.csdn.net/u012730525/article/details/136182670

https://blog.csdn.net/hmh520i/article/details/131033002

 

posted on 2024-04-02 16:43  shiyuan310  阅读(11)  评论(0编辑  收藏  举报