# const那些事
## 1.const含义
常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的。
## 2.const作用
- 可以定义常量
``` c++
const int a = 100;
```
- 类型检查
const常量与#define宏定义常量的区别:~~const常量具有类型,编译器可以进行安全检查;#define宏定义没有数据类型,只是简单的字符串替换,不能进行安全检查~~。
- 防止修改,起保护作用,增加程序健壮性
``` c++
void f(const int i) {
i++; // error
}
```
- 可以节省空间,避免不必要的内存分配
const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是像#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝。
## 3.const对象默认为文件局部变量
**注意:非const变量默认为extern。要使const变量能够在其他文件中访问,必须在文件中显式地指定它为extern。**
``` c++
// file1.cpp
int ext
// file2.cpp
#include<iostream>
/**
* by eintr
* compile: g++ -o file file2.cpp file1.cpp
* execute: ./file
*/
extern int ext;
int main(){
std::cout<<(ext+10)<<std::endl;
}
```
**小结:可以发现未被const修饰的变量不需要extern显式声明!而const常量需要显式声明extern,并且需要做初始化!因为常量在定义后就不能被修改,所以定义时必须初始化。**
## 4.定义常量
``` c++
const int b = 10;
b = 0; // error b为常量,不可更改
const string s "helloworld";
const int i, j = 0; // i为常量,必须进行初始化!(因为常量在定义后就不能被修改,所以定义时必须初始化。)
```
## 5.指针与const
``` c++
const char * a; //指向const对象的指针或者说指向常量的指针。
char const * a; //同上
char * const a; //指向类型对象的const指针。或者说常指针、const指针。
const char * const a; //指向const对象的const指针。
```
``` c++
#include <iostream>
using namespace std;
int main() {
int i = 12;
int j = 10;
const int *ip = &i;
ip = &j;
int const *ip_ = &i;
ip_ = &j;
int * const iq = &i;
*iq = j;
const int * const ipq = &i;
}
```
小结:如果const位于*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量。
具体使用如下:
- (1)指向常量的指针
``` c++
const int *ptr;
*ptr = 10; //error
```
ptr是一个指向int类型const对象的指针,const定义的是int类型,也就是ptr所指向的对象类型,而不是ptr本身,所以ptr可以不用赋初始值。但是不能通过ptr去修改所指对象的值。
除此之外,也不能使用void*指针保存const对象的地址,必须使用const void*类型的指针保存const对象的地址。
``` c++
const int p = 10;
const void * vp = &p;
void *vp = &p; //error
```
另外一个重点是:允许把非const对象的地址赋给指向const对象的指针。
将非const对象的地址赋给const对象的指针:
``` c++
const int *ptr;
int val = 3;
ptr = &val; //ok
```
我们不能通过ptr指针来修改val的值,即使它指向的是非const对象!
我们不能使用指向const对象的指针修改基础对象,然而如果该指针指向了非const对象,可用其他方式修改其所指的对象。可以修改const指针所指向的值的,但是不能通过const对象指针来进行而已!如下修改:
``` c++
int *ptr1 = &val;
*ptr1=4;
cout<<*ptr<<endl;
```
小结:对于指向常量的指针,不能通过指针来修改对象的值。
也不能使用void`*`指针保存const对象的地址,必须使用const void`*`类型的指针保存const对象的地址。
允许把非const对象的地址赋值给const对象的指针,如果要修改指针所指向的对象值,必须通过其他方式修改,不能直接通过当前指针直接修改。
- (2)常指针
const指针必须进行初始化,且const指针的值不能修改。
``` c++
#include<iostream>
using namespace std;
int main(){
int num=0;
int * const ptr=# //const指针必须初始化!且const指针的值不能修改
int * t = #
*t = 1;
cout<<*ptr<<endl;
}
```
上述修改ptr指针所指向的值,可以通过非const指针来修改。
最后,当把一个const常量的地址赋值给ptr时候,由于ptr指向的是一个变量,而不是const常量,所以会报错,出现:const int* -> int *错误!
``` c++
#include<iostream>
using namespace std;
int main(){
const int num=0;
int * const ptr=# //error! const int* -> int*
cout<<*ptr<<endl;
}
```
上述若改为 const int *ptr或者改为const int *const ptr,都可以正常!
- (3)指向常量的常指针
理解完前两种情况,下面这个情况就比较好理解了:
``` c++
const int p = 3;
const int * const ptr = &p;
```
ptr是一个const指针,然后指向了一个int 类型的const对象。
## 6.函数中使用const
> cost修饰函数返回值
(1)const int
``` c++
const int func1();
```
这个本身无意义,因为参数返回本身就是赋值给其他的变量!
(2)const int*
``` c++
const int* func2();
```
指针指向的内容不变。
(3)int *const
``` c++
int *const func2();
```
指针本身不可变。
> const修饰函数参数
- (1)传递过来的参数及指针本身在函数内不可变,无意义!
``` c++
void func(const int var); // 传递过来的参数不可变
void func(int *const var); // 指针本身不可变
```
表明参数在函数体内不能被修改,但此处没有任何意义,var本身就是形参,在函数内不会改变。包括传入的形参是指针也是一样。
输入参数采用“值传递”,由于函数将自动产生临时变量用于复制该参数,该输入参数本来就无需保护,所以不要加const 修饰。
- (2)参数指针所指内容为常量不可变
``` c++
void StringCopy(char *dst, const char *src);
```
其中src 是输入参数,dst 是输出参数。给src加上const修饰后,如果函数体内的语句试图改动src的内容,编译器将指出错误。这就是加了const的作用之一。
- (3)参数为引用,为了增加效率同时防止修改。
``` c++
void func(const A &a)
```
对于非内部数据类型的参数而言,象void func(A a) 这样声明的函数注定效率比较低。因为函数体内将产生A 类型的临时对象用于复制参数a,而临时对象的构造、复制、析构过程都将消耗时间。
为了提高效率,可以将函数声明改为void func(A &a),因为“引用传递”仅借用一下参数的别名而已,不需要产生临时对象。但是函数void func(A &a) 存
在一个缺点:
“引用传递”有可能改变参数a,这是我们不期望的。解决这个问题很容易,加const修饰即可,因此函数最终成为
``` c++
void func(const A &a)。
```
以此类推,是否应将void func(int x) 改写为void func(const int &x),以便提高效率?完全没有必要,因为内部数据类型的参数不存在构造、析构的过程,而复制也非常快,“值传递”和“引用传递”的效率几乎相当。
**小结:对于非内部数据类型的输入参数,应该将“值传递”的方式改为“const 引用传递”,目的是提高效率。例如将void func(A a) 改为void func(const A &a)。
对于内部数据类型的输入参数,不要将“值传递”的方式改为“const 引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如void func(int x) 不应该改为void func(const int &x)。**
## 7.类中使用const
在一个类中,任何不会修改数据成员的函数都应该声明为const类型。如果在编写const�
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
【无积分此资源可私信博主有偿获取】 Linux项目是一个开放源代码的操作系统项目,由林纳斯·托瓦兹(Linus Torvalds)于1991年首次发布。该项目以Linux内核为核心,围绕其构建了一个完整的操作系统,包括各种系统工具、库、应用程序和硬件支持。 以下是Linux项目的一些主要特点和资料介绍: 开放源代码:Linux项目的所有源代码都是公开的,并允许任何人自由使用和修改。这为开发者提供了极大的灵活性和创新能力,同时也促进了全球范围内的协作和发展。 跨平台性:Linux操作系统可以在多种硬件架构和平台上运行,包括x86、ARM、MIPS等。这使得Linux成为了一种非常灵活的操作系统,适用于各种设备和应用场景。 可定制性:由于Linux的源代码是公开的,用户可以根据自己的需求进行定制和修改。这使得Linux成为了一种非常适合企业级应用的操作系统,可以根据企业的特定需求进行定制和优化。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。
资源推荐
资源详情
资源评论
收起资源包目录
linux项目工程资料-内容包括:C基础 C++面向对象编程 基础数据结构 linux系统编程以及一些操作系统.zip (550个子文件)
a 23B
entry.asm 2KB
b 12B
mpi_tsp_dyn.c 59KB
omp_tsp_dyn.c 35KB
mpi_tsp_stat.c 34KB
mpi_tsp_stat.c 34KB
omp_tsp_stat.c 26KB
omp_tsp_stat.c 26KB
bst.c 25KB
staticlink.c 23KB
inst.c 23KB
test_rbt.c 19KB
tsp_iter2.c 16KB
tsp_iter2.c 16KB
tsp_iter1.c 15KB
mem_alloc.c 13KB
test_bst.c 13KB
mpi_odd_even.c 13KB
test_shell.c 12KB
block.c 12KB
tsp_rec.c 11KB
tsp_rec.c 11KB
rbt.c 11KB
pagefault.c 11KB
merge_sort.c 11KB
interrupt.c 11KB
linkedlist.c 10KB
parseElf.c 10KB
split.c 9KB
vmarea.c 8KB
mesi.c 8KB
omp_count_sort.c 8KB
tsp_iter1.c 8KB
fork.c 8KB
isa.c 8KB
mpi_mat_vect_mult.c 8KB
redblack_tree.c 8KB
test_malloc.c 7KB
vector_add.c 7KB
mpi_mergesort.c 7KB
hashtable.c 7KB
test_pagefault.c 7KB
client.c 7KB
omp_producer_consumer.c 7KB
sram.c 7KB
test_fork.c 7KB
convert.c 6KB
explicit_list.c 6KB
medialib.c 6KB
server.c 6KB
mmu.c 5KB
test_context.c 5KB
relay.c 5KB
server.c 5KB
data_relay_epoll.c 5KB
dram.c 4KB
data_relay.c 4KB
data_relay_poll.c 4KB
odd_even.c 4KB
mytbf.c 4KB
test_run_isa.c 4KB
mypipe.c 4KB
ping_pong.c 4KB
trie.c 4KB
mpi_pingpong_clock_cal.c 4KB
mytbf.c 3KB
count_sort.c 3KB
small_list.c 3KB
mytbf.c 3KB
implicit_list.c 3KB
test.c 3KB
vector_mult.c 3KB
omp_schedule.c 3KB
omp_odd_even1.c 3KB
myls.c 3KB
llist.c 3KB
omp_odd_even2.c 3KB
false_sharing.c 3KB
thr_channel.c 3KB
thr_list.c 2KB
ysh.c 2KB
main.c 2KB
mpi_pingpong_message_size_change.c 2KB
mpi_pingpong_iter_num_change.c 2KB
mpi_pingpong.c 2KB
main.c 2KB
server.c 2KB
useexec.c 2KB
primer_pool.c 2KB
syscall.c 2KB
linklist.c 2KB
swap.c 2KB
main.c 2KB
server.c 2KB
main.c 2KB
omp_trap2a.c 2KB
main.c 2KB
server.c 2KB
omp_trap1.c 2KB
共 550 条
- 1
- 2
- 3
- 4
- 5
- 6
资源评论
妄北y
- 粉丝: 1w+
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- :基于java打造的深度学习框架,帮助你快速搭建神经网络,实现模型推理与训练,引擎支持自动求导,多线程与GPU运算
- 第九次作业(XY图,XY图显示,三维曲面,数字波形图)
- 微信小程序实战案例:打造高效便捷的在线书店.zip
- 1.0.5win(1)(1).exe
- ESP8266 WiFi模块入门教程:从连接到配置.zip
- 词频统计:从基础到实践的应用指南.zip
- 滑动窗口:深入理解与应用.zip
- WRF(Weather Research and Forecasting Model)模型:深入解析与实用操作指南.zip
- IngeekDK.json
- DHT11温湿度传感器:原理、应用与操作指南.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功