C/C++ 关于 const
2021/6/25 20:27:10
本文主要是介绍C/C++ 关于 const,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
const
关键字用来保护数据不被修改,简而言之就像常量一样,它类似于"符号常量"#define
指令。
#define
"符号常量"宏定义是这样:
#define PI 3.14159
宏定义的本质其实就是字符替换,很容易出错,所以要特别注意加括号(()
)。
const
变量这样声明:
const double PI = 3.14159;
const
的用法相比#define
形式的"符号常量"更加灵活。可以创建const数组
、const 指针
、指向 const 的指针
。
举例说明:
1.
const int days[] = {1, ...}; days[0] = 5; // 编译出错,不允许修改值。
2.
double rates[] = {1.0, ...}; const double *pd = rates; ... *pd = 5.5; // 不允许 pd[0] = 5.5; // 不允许 rates[0] = 3.3; // 允许 因为 rates 没有被 const 限制
3.
把const
数据或非const
数据的地址初始化为指向const
指针或为其赋值是合法的:
double rates[] = {88.99, ...}; const double locked[] = {0.08, ...}; const double *pc = rates; // 有效 pc = locked; //有效 pc = &rates[1]; // 有效
然而,只能把非const
数据的地址赋给普通指针:
double rates[] = {88.99, ...}; const double locked[] = {0.08, ...}; double *pnc = rates; // 有效 pnc = locked; // 无效 pnc = &rates[3]; // 有效
pnc = locked; // 无效
可以这样理解,如果其有效那岂不是可以通过指针pnc
修改locked[]
数组的值了,这是不允许的。
申明一个函数:
void show_arry(const double *ar, int n);
由以上可知,函数show_arry(const double *ar, int n)
既可以接受普通数组作为参数,又可以接受const
数组作为参数。因为,这两种参数都可以初始化const
修饰的指针。
4.
const
修饰的其他两种位置:
double rates[] = {1, ...}; double const *pc = rates; // pc 指向数组的开始位置 pc = &rates[3]; // 不允许,不能修改 pc 的指向 *pc = 1.23; // 可以的,允许修改 pc 所指向地址的值
使用两次const
修饰指针;
double rates[] = {1, ...}; const double const *pc = rates; // pc 指向数组的开始位置 pc = &rates[3]; // 不允许,不能修改 pc 的指向 *pc = 1.23; // 不允许,不允许修改 pc 所指向地址的值
C++ 允许在声明数组大小时使用 const 整数,而 C 是不允许的。C++ 的指针赋值检查也更为严格:
const int y; const int *p2 = &y; int *p1; p1 = p2; // C++中不允许这样做,但 C中只给出警告;
C++ 中不允许把 const 指针赋给非 const 指针。而 C 是可以的。上面的代码示例中,如果通过
p1
修改y
的值,其行为是未定义的。
这里还必须注意的的地方是,把 const 指针赋给非 const 指针是不安全的,因为这样可以通过使用新的指针改变 const 指针指向的数据。编译器可能给出警告,然而执行这样的代码是未定义的。不过,把非 const 指针赋给 const 指针没有问题。
参考:
《C Primer Plus》。
这篇关于C/C++ 关于 const的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享