C语言const 关键字
发布日期:2021-06-30 18:42:53 浏览次数:3 分类:技术文章

本文共 3113 字,大约阅读时间需要 10 分钟。

面试的时候,应该有遇到const相关的,毕竟也是学习中的一个知识点,看完我们这篇文章,我觉得你应该可以在面试中完完全全的吃透const这个点。

const和变量

const uint32_t hello = 3;

编译的时候,编译器就知道了 hello 这个变量是不可以被修改了,const其实也就是read only,你只能读我的,不能修改我。

所以你要是试图修改这个变量的值,编译器会告诉你

clang-700.1.81:error: read-only variable is not assignable    hello++;    ~~~~~^error: read-only variable is not assignable    hello = 92;    ~~~~~ ^ gcc-5.3.0:error: increment of read-only variable 'hello'     hello++;          ^error: assignment of read-only variable 'hello'     hello = 92;           ^

C有一个特点,只要const 在变量名之前就可以,所以 const uint32_t i; 和uint32_t const i都是一样的。

const uint32_t hello = 3;uint32_t const hello = 3;

const 和函数参数

我们有时候不希望函数体内的代码修改呢我们传入的参数,我们就会这样做。我们看看下面这个代码

#include "stdio.h"#include "stdint.h" void printTwo(uint32_t a, uint64_t b); void printTwo(const uint32_t a, const uint64_t b) {
printf("%d %d\n", a, b);} int main(){
printTwo(12,23); return (1); }

我们声明的时候,没有加上const ,但是我们定义函数的时候,我们加上了const,编译没有报错,也成功执行了。声明只是一个虚张声势而已,就好比严令禁止一样,有些人还是继续作恶,就好比。

我解释得再深入一些,我们知道函数形参(非指针或者数组)传过来的是一个拷贝,函数体里面处理的是这个形参的拷贝而不是这个形参的实体,就像影分身一样,分身死了,本体还在着呢。所以对分身的属性和本体的属性是不一样的。

#include "stdio.h"#include "stdint.h" void printTwo(const uint32_t a, const uint64_t b); void printTwo(const uint32_t a, uint64_t b) {
b = 12; printf("%d %d\n", a, b);} int main(){
printTwo(12,23); return (1); }

const 和数组

#include "stdio.h"#include "stdint.h" const uint16_t things[] = {5, 6, 7, 8, 9}; int main(){
things[1] = 12; return (1); }

编译一下,就会报错

8    12    G:\c\1.cpp    [Error] assignment of read-only location 'things[1]'

const 和结构体

例子

#include "stdio.h"#include "stdint.h" struct aStruct {
int32_t a; uint64_t b;}; const struct aStruct someStructA = {.a = 3, .b = 4}; int main(){
someStructA.a = 12; return (1); }

编译的时候

13    16    G:\c\1.cpp    [Error] assignment of member 'aStruct::a' in read-only object

我们也可以在结构体里面指明const,这样就不会影响整个结构体,而只影响里面的某一个参数了。

const 和指针

const 修饰指针变量指向的内容

指针和const应该是最常见了,毕竟指针一边,就好比火车脱轨了,开往了错误的方向。

#include "stdio.h"#include "stdint.h" uint64_t bob = 42;uint64_t const *aFour = &bob; int main(){
*aFour = 4; return (1); }

一样的,编译的时候,还是会出错

9    9    G:\c\1.cpp    [Error] assignment of read-only location '* aFour'

const 修饰的是指针指向的内容,说明指针执行的内容是read only的,是不可改变。

所以,下面这个代码是没有问题的

#include "stdio.h"#include "stdint.h" uint64_t bob = 42;uint64_t const *aFour = &bob;uint64_t b = 32;int main(){
aFour = &b; return (1); }

const 修饰指针变量

同理如果const 修饰指针变量,那就说明这个地址是不可变的。

#include "stdio.h"#include "stdint.h" uint64_t bob = 42;uint64_t  *const aFour = &bob;uint64_t b = 32;int main(){
aFour = &b; return (1); }
9    8    G:\c\1.cpp    [Error] assignment of read-only variable 'aFour'

所以如果我们希望一个指针变量不能改变,指向的内容也不能改变,就应该这样写

uint32_t bob = 32;uint32_t const *const p = &bob;

const 和#define的区别

既然有了#define 还需要const 吗?他们的恩恩怨怨我觉得今天应该要结束了,即使没有结束,也应该分出一个胜负了。

•#define 是宏替换,在预编译的时候确定•const 前面有数据类型,会进行数据类型检查•#define 执行的宏名,可以通过#undef来取消宏定义,但是const修饰的变量,保存在静态区,会一直存在,所以如果你有多个头文件声明同一个const 变量,肯定会出现重复定义。但是你在两个头文件中,#define 两个名字一样的宏名,并不会有问题

如果看了上面还不过瘾,推荐一个const的文章,因为没有获得作转载许可,只给出链接

扫码或长按关注

回复「 加群 」进入技术群聊

转载地址:https://linus.blog.csdn.net/article/details/102656024 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Linux 内核通知链和例程代码
下一篇:南拳北腿

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2024年04月13日 10时15分18秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章