返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++和C中const的区别详解
  • 320
分享到

C++和C中const的区别详解

2024-04-02 19:04:59 320人浏览 独家记忆
摘要

目录C中的constconst修饰局部变量const修饰全局变量const修饰的全局变量有外部链接属性const与指针c++中的constconst修饰普通全局变量const修饰普通

const,这个词字面意思为:常数。

这就表示这是一个不可以改变是数。同时,这也是C/C++里面的一个关键字,是一个限定符,但是const在C和C++中的用法是有区别的。

由于本人水平有限,难免会有出错的地方,如果错误,还请指正!

C中的const

const修饰局部变量

C语言中,const修饰局部变量,那么这个变量就是“常变量”。


void test(){
	const int b = 20;
}

int main() {
	const int a = 10;
	return 0;
}

上面的两个变量,无论是主函数中的a,还是普通的函数中的b,都是被从const修饰的变量,那么就是“常变量”。

“常变量”不可以直接通过变量名来对值进行修改,因为变量名被const修饰后,从原来的“可读可改”的属性,变成了只“可读”,“不可改”的属性。


void test(){
	const int b = 20;
	b = 40;//error
}

int main() {
	const int a = 10;
	a = 30;//error
	return 0;
}

上面的行为是错误的。

但是,“常变量”本质上还是一个“变量”,而不是“常量”。

只要是被const修饰的局部变量,都是在程序运行到这一行代码的时候,才会创建这个变量并且分配空间的。

而分配空间是在栈区分配的,栈区的空间都会有对应的地址,栈区的空间是“可读可写”的。

我们可以通过地址,来对值进行修改。


#include<stdio.h>

void test() {
	const int b = 20;
	int* pb = &b;
	*pb = 40;
	printf("%d\n", b);
}

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

上面的代码输出的结果是:30和40

也就是说,不论是main函数中的还是普通函数中的局部变量,只要是被const修饰的局部变量,是可以通过地址来进行修改的。

补充

一般我们在定义一个被const修饰的变量的时候,都应该定义并且初始化,如果像上面的那样,是被const修饰的局部变量,如果我们在定义的时候不进行初始化,那么就是一个随机值,想要修改就只能通过指针了。

const修饰全局变量

const修饰的全局变量,也就是定义在函数体之外的变量,内存空间是在文字常量区的,这个内存区域是只读的,不能通过变量名去修改变量的值,也不能通过指针去修改变量的值!


const int a = 10;//全局变量
int main() {
	int* pa = &a;
	*pa = 30;
	printf("%d\n", a);
	return 0;
}

上面的代码时错误的,被const修饰的全局变量不能通过变量名和地址对内容进行修改,程序会报错。

const修饰的全局变量有外部链接属性

在C语言中,只要时全局变量,不论有没有被const修饰,都是默认拥有外部链接属性的,也就是说这个全局变量不仅限于在当前文件下使用,只要我们在其他文件中,加上extern的声明,也是可以使用的。

const与指针

当const修饰非指针的普通变量的时候,不论const放在类型关键字前面还是后面,表达的意思都是一样的


#include<stdio.h>
const int c = 5;
int const c = 5;
void test() {
	const int b = 20;
	int const b = 20;
}

int main() {
	const int a = 10;		
	int const a = 10;
	return 0;
}

上面a,b,c,三个变量的两种写法表达的意思都是一样的,当然同名的变量不能重复定义,我只是演示一下而已。

当const修饰指针的时候,不同的写法会代表不同的意思。


int main() {
	const int a = 10;
	//const int* pa = &a;//与下一行的代码表达的意思一样
	int const* pa = &a;
	*pa = 30;
	printf("%d\n", a);
	return 0;
}

上面的代码时有错的,const修饰指针的时候,const在*星号的左边(上面演示的两种情况都可以),那么表示的是,指针pa指向的空间的内容不可以修改,但是指针变量本身的值可以修改,也就是该指针变量可以改变指向的空间。


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

上面的代码是错误的,const在*星号的右边,那么表示的是指针变量pa里面存放的地址不可以被修改,也就是不能修改当前指针变量所指向的空间,但是空间的内容可以通过指针来进行修改。

C++中的const

const修饰普通全局变量

与C一样,当const修饰普通的全局变量的时候,不能通过变量名和地址来修改变量的值。

另外

与C不一样的是,C语言中的const修饰的普通全局变量默认是外部链接属性的,但是在C++中被const修饰的普通全局变量是内部链接属性的。

也就是说当我们在一个文件中定义了一个如下的全局变量


const int a = 10;//定义全局变量
int main() {
	return 0;
}

我们在另外一个文件中,使用extern来声明,也是不可以的。


//另外一个文件
extern const int a;//在另外的文件中声明

上面这种做法是不可以的,C++中被const修饰的全局变量默认是内部链接属性,不能直接在另外的文件中使用,如果想要在另外的文件中使用,就需要在定义该全局的变量的文件中用extern来修饰。


//定义的文件
extern const int a = 10;
//另外一个文件声明
extern const int a;

const修饰普通局部变量

如果const修饰的局部变量是基础的类型(int char double等等),并且初始化使用字面常量的话,不会给该变量分配空间。

例如:


void test() {
	const int a = 10;//用字面常量10来初始化
	a = 20;//error
}

但是,当我们对这个变量进行取地址的操作的时候,系统会为该变量分配空间。


void test() {
	const int a = 10;
	//a = 20;//error
	int* p = (int*)&a;
	*p = 20;
	cout << a << endl;
	cout << *p << endl;
}

上面的结果是:

10和20

这是因为,当我们定义一个被const修饰并且使用字面常量来初始化的局部变量的时候,系统会把这个变量看作是一个符号,放入到符号表中,这么变量名就是一个符号,值就是这个符号的值,类似于#define的作用。

当我们对这个变量取地址的时候,由于原来没有空间,就没有地址,现在需要取地址,所以才被迫分配一块空间,我们通过地址的解引用可以修改这个空间的值,这也就是为什么第二个结果为20的原因,但是如果我们还是通过变量名来访问数据的话,系统会认为这还是一个符号,直接用符号表里面的值替换。

但是!

如果初始化不是用字面常量而是用变量,那么系统会直接分配空间。


void test() {
	int b = 20;
	const int a = b;
}

这时候的a是有空间的,不会被放入到符号表中。

const与类

如果是自定义数据类型(结构体、对象)

我们在创建对象(结构体)的时候,如果这个对象是被const修饰的话,那么不管这个对象是全局的还是局部的,系统都会直接分配空间

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

const,这个词字面意思为:常数。

这就表示这是一个不可以改变是数。同时,这也是C/C++里面的一个关键字,是一个限定符,但是const在C和C++中的用法是有区别的。

由于本人水平有限,难免会有出错的地方,如果错误,还请指正!

C中的const

const修饰局部变量

在C语言中,const修饰局部变量,那么这个变量就是“常变量”。


void test(){
	const int b = 20;
}

int main() {
	const int a = 10;
	return 0;
}

上面的两个变量,无论是主函数中的a,还是普通的函数中的b,都是被从const修饰的变量,那么就是“常变量”。

“常变量”不可以直接通过变量名来对值进行修改,因为变量名被const修饰后,从原来的“可读可改”的属性,变成了只“可读”,“不可改”的属性。


void test(){
	const int b = 20;
	b = 40;//error
}

int main() {
	const int a = 10;
	a = 30;//error
	return 0;
}

上面的行为是错误的。

但是,“常变量”本质上还是一个“变量”,而不是“常量”。

只要是被const修饰的局部变量,都是在程序运行到这一行代码的时候,才会创建这个变量并且分配空间的。

而分配空间是在栈区分配的,栈区的空间都会有对应的地址,栈区的空间是“可读可写”的。

我们可以通过地址,来对值进行修改。


#include<stdio.h>

void test() {
	const int b = 20;
	int* pb = &b;
	*pb = 40;
	printf("%d\n", b);
}

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

上面的代码输出的结果是:30和40

也就是说,不论是main函数中的还是普通函数中的局部变量,只要是被const修饰的局部变量,是可以通过地址来进行修改的。

补充

一般我们在定义一个被const修饰的变量的时候,都应该定义并且初始化,如果像上面的那样,是被const修饰的局部变量,如果我们在定义的时候不进行初始化,那么就是一个随机值,想要修改就只能通过指针了。

const修饰全局变量

const修饰的全局变量,也就是定义在函数体之外的变量,内存空间是在文字常量区的,这个内存区域是只读的,不能通过变量名去修改变量的值,也不能通过指针去修改变量的值!


const int a = 10;//全局变量
int main() {
	int* pa = &a;
	*pa = 30;
	printf("%d\n", a);
	return 0;
}

上面的代码时错误的,被const修饰的全局变量不能通过变量名和地址对内容进行修改,程序会报错。

const修饰的全局变量有外部链接属性

在C语言中,只要时全局变量,不论有没有被const修饰,都是默认拥有外部链接属性的,也就是说这个全局变量不仅限于在当前文件下使用,只要我们在其他文件中,加上extern的声明,也是可以使用的。

const与指针

当const修饰非指针的普通变量的时候,不论const放在类型关键字前面还是后面,表达的意思都是一样的


#include<stdio.h>
const int c = 5;
int const c = 5;
void test() {
	const int b = 20;
	int const b = 20;
}

int main() {
	const int a = 10;		
	int const a = 10;
	return 0;
}

上面a,b,c,三个变量的两种写法表达的意思都是一样的,当然同名的变量不能重复定义,我只是演示一下而已。

当const修饰指针的时候,不同的写法会代表不同的意思。


int main() {
	const int a = 10;
	//const int* pa = &a;//与下一行的代码表达的意思一样
	int const* pa = &a;
	*pa = 30;
	printf("%d\n", a);
	return 0;
}

上面的代码时有错的,const修饰指针的时候,const在*星号的左边(上面演示的两种情况都可以),那么表示的是,指针pa指向的空间的内容不可以修改,但是指针变量本身的值可以修改,也就是该指针变量可以改变指向的空间。


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

上面的代码是错误的,const在*星号的右边,那么表示的是指针变量pa里面存放的地址不可以被修改,也就是不能修改当前指针变量所指向的空间,但是空间的内容可以通过指针来进行修改。

C++中的const

const修饰普通全局变量

与C一样,当const修饰普通的全局变量的时候,不能通过变量名和地址来修改变量的值。

另外

与C不一样的是,C语言中的const修饰的普通全局变量默认是外部链接属性的,但是在C++中被const修饰的普通全局变量是内部链接属性的。

也就是说当我们在一个文件中定义了一个如下的全局变量


const int a = 10;//定义全局变量
int main() {
	return 0;
}

我们在另外一个文件中,使用extern来声明,也是不可以的。


//另外一个文件
extern const int a;//在另外的文件中声明

上面这种做法是不可以的,C++中被const修饰的全局变量默认是内部链接属性,不能直接在另外的文件中使用,如果想要在另外的文件中使用,就需要在定义该全局的变量的文件中用extern来修饰。


//定义的文件
extern const int a = 10;
//另外一个文件声明
extern const int a;

const修饰普通局部变量

如果const修饰的局部变量是基础的类型(int char double等等),并且初始化使用字面常量的话,不会给该变量分配空间。

例如:


void test() {
	const int a = 10;//用字面常量10来初始化
	a = 20;//error
}

但是,当我们对这个变量进行取地址的操作的时候,系统会为该变量分配空间。


void test() {
	const int a = 10;
	//a = 20;//error
	int* p = (int*)&a;
	*p = 20;
	cout << a << endl;
	cout << *p << endl;
}

上面的结果是:

10和20

这是因为,当我们定义一个被const修饰并且使用字面常量来初始化的局部变量的时候,系统会把这个变量看作是一个符号,放入到符号表中,这么变量名就是一个符号,值就是这个符号的值,类似于#define的作用。

当我们对这个变量取地址的时候,由于原来没有空间,就没有地址,现在需要取地址,所以才被迫分配一块空间,我们通过地址的解引用可以修改这个空间的值,这也就是为什么第二个结果为20的原因,但是如果我们还是通过变量名来访问数据的话,系统会认为这还是一个符号,直接用符号表里面的值替换。

但是!

如果初始化不是用字面常量而是用变量,那么系统会直接分配空间。


void test() {
	int b = 20;
	const int a = b;
}

这时候的a是有空间的,不会被放入到符号表中。

const与类

如果是自定义数据类型(结构体、对象)

我们在创建对象(结构体)的时候,如果这个对象是被const修饰的话,那么不管这个对象是全局的还是局部的,系统都会直接分配空间

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: C++和C中const的区别详解

本文链接: https://lsjlt.com/news/158563.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++和C中const的区别详解
    目录C中的constconst修饰局部变量const修饰全局变量const修饰的全局变量有外部链接属性const与指针C++中的constconst修饰普通全局变量const修饰普通...
    99+
    2024-04-02
  • const在c和c++中的区别
    在 c 和 c++ 中,const 关键字用于声明常量。在 c 中,const 只能修饰变量,不能修饰指针或数组;在 c++ 中,const 可以修饰变量、指针和数组。主要的差异在于:作...
    99+
    2024-04-28
    c++ 作用域
  • C++和C中const的区别是什么
    本篇内容介绍了“C++和C中const的区别是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!const,这个词字面意思为:常数。这就表示...
    99+
    2023-06-21
  • C++中const char*、char const*、char * const三者的区别
    目录一、const char *ptr;二、char const *ptr;三、char * const ptr;C/C++ 中关于以下三种定义: const char *...
    99+
    2024-04-02
  • 详解C++中的const和constexpr
    目录一.const常量与#define比较二.const修饰1.修饰普通变量,必须初始化2.修饰类变量和成员变量3.修饰成员函数4.修饰指针5.修饰引用三.const转换四.顶层co...
    99+
    2024-04-02
  • C和C++的区别详解
    目录通过程序来介绍1.iostream文件2.头文件名的区别C语言C++3.名称空间namespace封装性4.使用cout进行C++的输出指针和数组名的区别反汇编查看区别结论解引用...
    99+
    2024-04-02
  • C语言中const和define的区别你了解嘛
    目录define和const使用const和define区别总结define和const使用 const和define区别 #include <stdio.h> #...
    99+
    2024-04-02
  • 浅谈C++中const与constexpr的区别
    目录一.const常量与#define比较二.const修饰1.修饰普通变量,必须初始化2.修饰类变量和成员变量3.修饰成员函数4.修饰指针5.修饰引用三.const转换四.顶层co...
    99+
    2024-04-02
  • C语言中const和define的区别是什么
    本文小编为大家详细介绍“C语言中const和define的区别是什么”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言中const和define的区别是什么”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。def...
    99+
    2023-06-29
  • C语言中auto,register,static,const,volatile的区别详细解析
    1)auto这个关键字用于声明变量的生存期为自动,即将不在任何类、结构、枚举、联合和函数中定义的变量视为全局变量,而在函数中定义的变量视为局部变量。这个关键字不怎么多写,因为所有的变...
    99+
    2022-11-15
    register static const volatile
  • 关于C语言 const 和 define 区别
    目录一.const使用1.const修饰变量2.const修饰指针3.const修饰在函数名前面当4.const修饰在函数名后面5.const修饰函数参数二.define使用1.de...
    99+
    2024-04-02
  • C# const和static readonly区别是什么
    这篇文章主要介绍“C# const和static readonly区别是什么”,在日常操作中,相信很多人在C# const和static readonly区别是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答...
    99+
    2023-06-17
  • 详解C++中typedef 和 #define 的区别
    1、执行上不同 关键字 typedef 在编译阶段有效,由于是在编译阶段,因此 typedef 有类型检查的功能。 #define 则是宏定义,发生在预处理阶段,也就是编译之前,它只...
    99+
    2024-04-02
  • C++中const与constexpr的区别是什么
    这篇文章主要讲解了“C++中const与constexpr的区别是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++中const与constexpr的区别是什么”吧!一.const常量...
    99+
    2023-06-21
  • C#中的const和readonly关键字详解
    const和readonly经常被用来修饰类的字段,两者有何异同呢? const 1、声明const类型变量一定要赋初值吗? 一定要赋初值 public class Student ...
    99+
    2022-11-13
    C# const关键字 readonly关键字
  • C++中的struct和class的区别详解
    目录1. C++的struct和class的区别1.1 成员访问范围的差异structclass1.1 继承关系访问范围的差异struct : structstruct : clas...
    99+
    2022-11-13
    C++中的struct C++中的class struct和class的区别
  • C/C++编程中const的使用详解
    目录1 概述:const和define的区别2. 修饰局部变量3. 常量指针与指针常量4. 修饰函数的参数5. 修饰函数的返回值6. 修饰全局变量总结1 概述:const和defin...
    99+
    2024-04-02
  • c语言和c++语言中const修饰的变量区别浅析
    目录c:修饰全局变量:修饰局部变量:c++:修饰全局变量:修饰局部变量:总结:在c语言中:在c++语言中:总结c: 修饰全局变量: 用const修饰的全局变量是没有办法直接修改的,间...
    99+
    2024-04-02
  • c和c++中static的区别
    static 在 c 和 c++ 中的区别包括:作用域:c 中仅限于文件,c++ 可为文件或类作用域;链接:c 中仅链接到所在文件,c++ 中链接到整个程序;初始化:c 中默认为 0,c...
    99+
    2024-05-14
    c++ 作用域
  • C++中左值和右值的区别详解
    目录左值右值定义:特性左值引用, 右值引用总结左值右值定义: 左值指的是既能够出现在等号左边也能出现在等号右边的变量(或表达式),右值指的则是只能出现在等号右边的变量(或表达式). ...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作