C语言详细讲解const的用法

 更新时间:2022年05月10日 08:41:59   作者:lonely-hermit  
今天探讨const,首先来说是将变量常量化。为什么要将变量常量化,原因有诸多好处有诸多。比如可以使数据更加安全不会被修改

一、int const a / const int a

int 和const 都作为一个类型限定词,有相同的地位,所以谁在前谁在后无所谓了,标题中的这两种写法是一致的。

这是我们常规的用途,我们发现这样的话我们对a已经不能做任何修改了。

int main() {
    int const a = 10;
    printf("%d\n",a);
    return 0;
}

真的不能修改吗?未必的

int main() {
    int const a = 10;
    int *p = &a;
    *p = 20;
    printf("%d\n",a);
    return 0;
}

成功修改,这是为什么呢,其实也很简单,这与编译器有关,gcc编译器中const是通过编译器在编译的时候执行检查来确保实现的,也就是检查的时候我发现你没有修改a的值,那我就认为你是对的。更深入一层的原因,是因为gcc把const类型的常量也放在了data段,其实和普通的全局变量放在data段是一样实现的,只是通过编译器认定这个变量是const的,运行时并没有标记const标志,所以只要骗过编译器就可以修改了。

这个本质上是C语言的问题,因为C语言就没有强制要求说const就是不能修改的,所以在C语言中使用const,就好象是 一种道德约束而非法律约束,所以大家使用const时更多是传递一种信息,就是告诉编译器、也告诉读程序的人,这个变量是不应该也不必被修改的。而且我的理解中,这个东西其实设置为了强制不可变在某种程度上不也就限制了C语言的灵活性嘛,c的奇淫巧技不就依靠C语言的灵活性实现的嘛,所谓bug变特性,我的猜测哈,不知道丹尼斯·里奇是不是也是这么想的。

二、const int(*p)/int const(*p)

其实标题是很好理解的,我们修饰了*p,使得p的指向不能被改变了。

int main() {
    int a = 10;
    int const (*p) = &a;
    printf("%d\n",*p);
    return 0;
}

上面的程序很好理解,p指向了a,p被const修饰,指向的对象a已经不能被修改了,下面的程序输出20就说明出了问题,这个还是上面我们讲到的那个问题,这是一个君子约定。

int main() {
    int a = 10;
    int const (*p) = &a;
    a = 20;
    printf("%d\n",*p);
    return 0;
}

下面的四种写法等价

int const (*p)
const int (*p)
int const *p
const int *p

三、int*const p

那么如何声明一个自身是常量指针呢?方法是让const尽可能的靠近p,下面的这个就是

int main() {
    int a = 10;
    int b = 20;
    int* const p = &a;
    printf("%d\n",*p);
    return 0;
}

指针只能指向a,指向b就报错。地址只能赋值一次。

这里有一个简便的区分方法:沿着*号划一条线,如果const位于*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量.如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量。

四、const用于函数的地址传递参数

void func(const int *p);

这种形式通常用于在数组形式的参数中模拟传值调用。也就是相当于函数调用者声称:"我给你一个指向它的指针,但你不能去修它。"如果函数编写者遵循了这个约定,那么就相当于模拟了值传递。这也是const最有用之处了:用来限定函数的形参,这样该函数将不会修改实参指针所指的数据。这里注意了,是函数不应该去修改而不是不能修改,也就是说const不能阻止参数的修改(原因见上)。

到此这篇关于C语言详细讲解const的用法的文章就介绍到这了,更多相关C语言const内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++的输入与输出和格式化输出

    C++的输入与输出和格式化输出

    这篇文章主要介绍了详解C++中的输入与输出和格式化输出,是C++入门学习中的基础知识,需要的朋友可以参考,希望能够给你带来帮助
    2021-11-11
  • Matlab实现绘制玫瑰线的示例代码

    Matlab实现绘制玫瑰线的示例代码

    这篇文章主要为大家介绍了如何利用Matlab绘制3好看的玫瑰线,文中的示例代码讲解详细,对我们学习Matlab有一定帮助,感兴趣的小伙伴可以动手试一试
    2022-08-08
  • C++智能指针之shared_ptr的具体使用

    C++智能指针之shared_ptr的具体使用

    本文主要介绍了C++智能指针之shared_ptr的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧<BR>
    2022-05-05
  • C语言实现学生宿舍管理系统

    C语言实现学生宿舍管理系统

    这篇文章主要为大家详细介绍了C语言实现学生宿舍管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • C++ const和指针详情

    C++ const和指针详情

    这篇文章主要介绍了C++ const和指针,关于使用const来修饰指针,有两种不同的方式。第一种是让指针指向一个常量对象,这样可以防止使用该指针进行修改指向的值。第二种则是将指针本身声明为常量,可以防止改变指针指向的位置,下面来看看文章的详细内容
    2021-11-11
  • C语言实现获取内存信息并输出的实例

    C语言实现获取内存信息并输出的实例

    这篇文章主要介绍了C语言实现获取内存信息并输出的实例的相关资料,需要的朋友可以参考下
    2017-03-03
  • c语言左移和右移的示例详解

    c语言左移和右移的示例详解

    这篇文章主要介绍了c语言左移和右移的示例详解,移位操作符的两个操作数必须是整型的。整个移位表达式的值的类型也是整型的,而且,左移位操作符与右移位操作符的运算并不对称。
    2020-07-07
  • 详解c语言中的 strcpy和strncpy字符串函数使用

    详解c语言中的 strcpy和strncpy字符串函数使用

    strcpy 和strcnpy函数是字符串复制函数。接下来通过本文给大家介绍c语言中的strcpy和strncpy字符串函数使用,感兴趣的朋友跟随小编要求看看吧
    2018-10-10
  • C++泛型编程基本概念详解

    C++泛型编程基本概念详解

    这一篇介绍一下 C++ 编程中与面向对象并列的另一大分支——泛型编程,这一篇主要介绍函数模板、类模板和成员模板三大部分,需要的朋友可以参考下
    2021-08-08
  • C++回溯算法中子集问题分析探讨

    C++回溯算法中子集问题分析探讨

    回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为回溯点
    2023-03-03

最新评论