【C/C++】中const函数详解

2024-09-03 07:51:54 浏览数 (1)

形参带默认值的函数

给默认值的时候从右向左给 定义处可以给形参默认值,声明也可以给默认值 形参给默认值时,不管定义处给,还是声明处给,形参默认值只能给一次 调用有默认值的函数效率会增大

inline内联函数

inline内联函数: 在编译过程中就没有函数的调用开销了,在函数的调用点直接·把函数的代码进行展开处理了。 同时内联函数不再生成相应的函数符号。 inline只是建议 编译器把这个函数处理成内联函数。不一定会把所有的inline标志的函数处理成内联函数。

在debug版本上inline内联函数是不会起作用的,还是有mov,push,call指令。 在release版本下才可以实现 此处可以在Linux下验证:

代码语言:javascript复制
g   -c main.cpp -O2 
objdump -t main.o

这里面就找不到sum产生的符号了。

inline内联函数 和普通函数的区别

普通函数有标准的函数调用开销,相反内联函数没有。

如果函数在短时间内大量调用,并且函数十分简单可以声明成内联函数。

const

  1. 怎么理解const? const修饰的变量不能够再作为左值 初始化完成后,初始化的值不能够再修改。
  2. 在C与C 中const的区别?

const的编译方式不同。 在c中,const就是当作一个变量来编译生成指令的 在C 中,所有出现const常量名字的地方,都被常量的初始化替换了。

在C中 const修饰的量可以不用初始化,但是后边也就无法赋值了。其实它不叫常量,叫做常变量。 const int a = 20; const只是保持a不能作为左值赋值,但是 可以通过指针访问里面的内存,修改a的值 或者通过添加汇编指令修改。

代码语言:javascript复制
const int a = 20;
int *p = (int*)&a;
*p = 30;
printf("%d %d %d",a,*p,*(&a));
//打印出来的值都是30

在C 中 const 必须进行初始化。叫做常量 可以用于作为数组的下标。

代码语言:javascript复制
const int a = 20;
int *p = (int*)&a;
*p = 30;
printf("%d %d %d",a,*p,*(&a));
		// 结果:20  30  20
		注意:内存a的值已经被修改了,之所以没有打印出来,因为没有访问a的地址

当初始值不是一个立即数,是一个变量的时候,就叫做常变量了。

代码语言:javascript复制
int b =20;
const int a = b; //a叫做常变量。
int *p = (int*)&a;
*p = 30;
printf("%d %d %d",a,*p,*(&a));//这的运行结果也就都是30了
  1. cosnt修饰的量常出现的错误·: 1.cosnt修饰的量不能再作为左值(直接修改const修饰的量) 2.不能把cosnt修饰的量的地址泄漏给一个普通的指针或者普通的引用变量。(可以间接修改)
  2. const和一级指针的结合 C 语言规范:cosnt修饰的是离它最近的类型。 const int *p ; == int const *p; 可以指向不同的int类型的内存,但是不能通过指针间接修改指向的内存的值,

int *const p = &a; 这个指针p现在是常量,不能再指向其他内存,但是可以通过指针解引用修改指向的内存的

const int *const p = &a; 都不可以修改

总结

int* <= const int* (不可以) const int* <= int* (可以) const如果右边没有指针*的话,const是不参与类型 int** <= const int** (错误) const int** <= int**(错误) int ** <=int * const*(错误) int * const * <= int ** (正确)

cosnt和二级指针(多级)的结合

代码语言:javascript复制
int a = 10;
int* p = &a;
int**q = &p;

const int **q; //**q不能赋值
int * const* q; //*q不能赋值
int **const q; //q不能赋值

0 人点赞