目录
引用和指针的区别
1.引用是C++语法,是一个变量的别名,并没有额外开辟空间。
而指针是一个变量存在实实在在的地址,而且占据4个或者8个字节。
2.指针更加复杂使用更容易出错。
3.引用必须初始化,而指针可以不初始化。
4.引用自加1就是引用的本体+1,而指针+1就是指向了下一个类型单元。
5.没有空引用但是有空指针
6.引用具有专一性,在引用了一个实体了以后不能在引用其他实体。而指针指向一个内容后可以改变指向指向另一块空间。
7.指针访问内容需要解引用,引用访问内容编译器自己处理。
8.在sizeof的含义不同 & 的含义就是引用的实体的类型的字节的大小;
而指针的sizeof是4/8。
什么是左值 右值?
左值一般可以修改比如变量。
右值不可以修改,有常属性。
常见的右值:
1.函数返回值
2.表达式返回值
3.临时变量
比如说
double a=1.11;
int b=a; 叫做隐式类型转换其实本质是:a生成一个具有常属性的临时变量(右值)然后赋值给b。
double d =15.6;
const 关键字
const 关键字 是保护变量不被修改的。是只读属性。
注意使用 const 的时候的权限的放大。
权限可以缩小和不变但是不能放大。
比如:
const int a=10; a 是只读 ,只能被读取,不能被存储和修改
int & b= a; b 是int 型 是可读可写 。权限的放大。
这个是权限的放大 。
double d =16.6;
int & b=d; 为什么错误?
因为 d 进行类型转换的时候中间产生一个临时变量 这个临时变量是常属性的,不能被修改。但是int&是可读可写的,这又是权限的放大。
换个角度,如果这个int & b=d; 表达式成立,那么 b 是d的别名。 b可以修改 d的具有常属性中间变量。这是不对的。
要保持权限的一致 只需这样
double d=16.6;
const int& b=d;
const + &在函数传参时候的作用
const Type & 比如(const int& a)可以接受各种变量 常量 类型转换,
在C++中 若函数传入的参数不会被改变就用 const Type &。
如果需要改变传入的参数来影响实参,那么就用传指针或者传引用。
形式参数传引用,传引用返回
形式参数传引用:
好处:节省时间,加快算法速度。不需要拷贝。
也可以传入输出型参数。比如传入双指针 int **p的时候你可以用传引用 int *& p
比较容易理解。写代码也比较方便。
传引用返回:
什么时候用?
当返回值不随着函数的栈帧的小时而销毁的时候可以用,比如返回的东西(静态区 全局变量 传入的形参)在这个函数之外的栈帧创建的。好处是可以修改函数返回的值。
区别一下传值函数返回:这个是一个拷贝放在寄存器或者上一个函数的栈帧中。不能修改返回值。
寄存器的内容不允许修改。
所有传值都需要拷贝,传值传参,传值返回 ,有代价。而传引用比较好,是变量的别名 ,不拷贝。
extern "C"
extern "C" 是C语言调用C++文件或者 C++调用C语言文件 所需要声明的,目的是让编译器在识别函数的时候用C语言的规则来识别。因为C++和C识别函数的方式不同。
C比较简单只看函数名,C++看函数名和形参,所以C++有个函数的重载。
C++调用用C写的程序:
在C++引用C的头文件包个 extern "C" 用{ }包括C的头文件
C调用C++写的程序:
还是在C++的程序内改,这里要一下简单的运用预处理
在C++的头文件前面写
#ifdef __cplusplus
#define EXTERN extern "C"
#else
#define EXTERN
#endif
然后下面在每个函数的声明前面加个EXTERN
__cplusplus 是C++的标识符
这个预处理的作用是,如果是c++把 EXTERN_C 替换为 extern "C"
否则(为C) 把EXTERN_C 替换为空。
这样做的目的是C++调用时显示 extern "C" ,如果为C调用时不显示 extern "C" 因为C不认识这个关键字。
C语言如何解决一个简单函数的重复调用?
C语言通常用宏定义 比如宏定义两个数的加法
#define ADD(X,Y) ((X)+(Y))
但是宏定义比较复杂 ,容易写错 ,注意每个小整体都要加()防止运算符优先级不同导致运算出错,整体外面还要加()防止外面出现个5*ADD(3,4) 出现错误。
而C++用 inline 关键字 放在函数类型前面
叫做内联函数。 为什么函数的调用会消耗?
函数的调用存在栈帧的创建和销毁,以及要用到一些寄存器,寄存器要压栈 出栈,这些都有消耗。
内联函数不需要函数调用了 ,它是在使用的地方直接展开 代价就是以空间换时间。
内联函数只是一种给编译器的建议,它不一定这样做,如果函数代码长,或者用了递归 编译器就不会用inline。
inline 由于是直接展开的 所以不要定义与声明分开。会出错
短小的频繁调用的函数建议定为内联