c语言const作用域,C/C++:Const总结

本文对比了C和C++中const修饰变量的差异,讨论了如何通过指针间接修改const变量的值,以及const变量在文件作用域中的行为。在C++中,const变量实际上是常量,而在C语言中,const变量仍可通过指针修改。同时,const与static结合使用会影响变量的文件作用域。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

指针变量和它所指向的内存空间是两个不同的概念

由于Const在C和C++中存在差异,本篇将会对Const在两种语言的表现异同点上进行对比探讨。

实现方式不同

在C语言中,Const修饰的变量只是告诉编译器该变量是一个只读的变量,不能通过该变量改写器内存空间中的值,但是其本质上还是一个变量,既然是变量,就会有内存地址,因此可以通过指针间接修改该地址空间的值。

const int a = 10;

int* p = &a;

*p = 20;

printf("a = %d, *p = %d\n", a, *p);

-------------结果------------------

a = 20, *p = 20

在C++中Const修饰的变量被称为常量,其值存放在常量表中,在使用常量时,编译器回到常量表中查询对应的常量,并将其替换,这部分没有涉及内存分配,因此对其取地址是没有意义的。但是当我们非要对该常量去地址时,则编译器会为其临时分配一个内存,并将常量值存入该临时内存中,事实上,在C++中规定必须用const修饰的指针来指向const修饰的常量。虽然可以使用强制转换的方式,对Const修饰的常量进行去地址,并将其赋值给一个非Const修饰的指针(最好不要这样做),但打这个指针上的任何改动都只会影响到临时分配的内存空间,而不会影响到原常量上。

const int a = 10;

int* p = (int *)&a;

*p = 20;

printf("a = %d, *p = %d\n", a, *p);

-------------结果------------------

a = 10, *p = 20

变量的文件作用域

在C语言中,访问一个变量之前,该变量必须要被预先定义,当访问一个由外部文件定义的变量时,则必须要提前声明该变量。来看下面几个例子。

// main.c

extern int a;

int main() {

printf("a = %d\n", a);

return 0;

}

//ln_const.c

int a = 128;

--------结果-------

a = 128

上面的例子是一个标准C语言访问外部变量的例子。我们编写代码时也应该遵守这样的规则。但是,总有写人不是那么规范,例如可以在main.c文件中将extern关键字去掉。

// main.c

int a;

int main() {

printf("a = %d\n", a);

return 0;

}

//ln_const.c

int a = 128;

--------结果-------

a = 128

我们发现实际上结果并没有变化,因为编译器在编译时,如果在当前文件中该变量没有被定义,则会从其他文件中寻找定义并链接。因此结果是没有问题的。那么如果变量a的定义被设定成文件内私有时,将会发生什么呢?

// main.c

int a;

int main() {

printf("a = %d\n", a);

return 0;

}

// ln_const.c

static int a = 128;

--------结果-------

a = 0

发生这种现象的原因是,编译器没有找到该变量的外部定义,则直接将声明默认为定义,因此变量a是一个默认赋值。事实上extern关键字的作用就是,告诉编译器,该变量的值是由外部文件定义的。因此当我们声明一个外部变量时,如果编译器无法再外部找到该变量的定义,则会无法编译通过。

// main.c

extern int a;

int main() {

printf("a = %d\n", a);

return 0;

}

// ln_const.c

static int a = 128;

--------结果-------

编译失败,无法解析外部符号a

那么如果我们在外部定义了一个Const变量,情况是否会有不同呢?在标准情况下,声明和定义,应该是保持一致的。因此标准做法应该是这样的。

// main.c

extern const int a ;

int main() {

printf("a = %d\n", a);

return 0;

}

// ln_const.c

const int a = 128;

-----结果---------

a = 128

C语言的难点之一就是规范标准,总有人会在声明时忘记const关键字,但是结果也是正确的。

// main.c

extern int a ;

int main() {

printf("a = %d\n", a);

return 0;

}

// ln_const.c

const int a = 128;

-----结果---------

a = 128

既然a在声明时并没有Const修饰是不是意味着,可以直接修改a呢?

// main.c

extern int a ;

int main() {

a = 20;

printf("a = %d\n", a);

return 0;

}

// ln_const.c

const int a = 128;

-----结果---------

编译失败,运行时异常

这里,我们可以看出,变量的声明帮助编译器进行语法检查,但变量的定义决定了运行时的行为。

当static关键字和Const关键字同时修饰变量时,Const是否会修改变量的文件作用域呢?

// main.c

extern int a ;

int main() {

printf("a = %d\n", a);

return 0;

}

// ln_const.c

static const int a = 128;

-----结果---------

编译失败,无法解析外部符号a

总结:在C语言中,变量文件作用域一般都是外部链接,除非使用static关键字修饰,Const关键字并不会改变变量的文件作用域

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值