一、指针和引用的特点区别1.程序为指针变量分配内存空间而不为引用分配内存空间int main() { int a 10, b 20; int* p a; int* s p; int* rp p;//int*类型指针的别名 //int* rp p;//不能定义指针指向引用引用没有空间 }2.解引用是指针使用时要在前面加“*”才能得到值引用可以直接使用与变量无异int main() { int ar[10] { 12,23,34,45,56,67,78,89 }; int ra ar[0]; int* p ar[0];//int* ra;//值-1-13 p;//地址-4-*p:23 cout ra: ra endl; cout *p: *p endl; }3.指针变量的值可以发生改变存储不同实例的地址引用在定义时就被初始化之后无法改变int main() { int a 10, b 20; int* p a; int ra a; //int * const raa;引用相当于不可以改变指向的常变量指针 //rab; *p 100; ra 200; }4.指针的变量值可以为NULL引用没有空引用定义引用必须初始化int main() { int a 10, b 20; int* p NULL;//指针有空指针 p a; *p 100; p b; *p 200; //int raNULL;引用没有空引用 //int ra;引用必须初始化 }5.指针变量作为形参需要测试合法性判空引用不需要判空6.对指针变量使用sizeof得到的是指针变量的大小对引用使用sizeof得到的是变量的大小void funa(int *br,int n) { cout funa:br[5] size: sizeof(br) endl; } void funb(int(rar)[5]) {//引用元素个数不可或缺 cout funa:(rar)[5] size: sizeof(rar) endl; } int main() { const int n 5; int ar[n] { 12,23,34,45,56 };//int* cout main:ar size: sizeof(ar) endl;//20 funa(ar,n);//4 funb(ar);//20 return 0; }7.理论上指针等级数没有上限引用没有等级数int main() { int a 10, b 20; int* p a;//一级指针 int** q p;//二级指针 int ra a;//ra-a;a-ra; //int raa ra;没有引用的引用 }二、左值与右值左值:可以取地址、有名字、能出现在赋值号左边的值不一定必须在左边。简单说就是 “有身份、能定位” 的对象。右值:不能取地址、没有名字、只能出现在赋值号右边的值。简单说就是 “临时的、用完就销毁” 的对象。int main() { int a 10; int* p nullptr;//C11 类型值类别 char ch a; const int b 20; a;//左值可以取地址 //10;//右值不可以取地址 b;//常性左值可以取地址 }左值引用 1个 右值引用 2个int main() { int a 10; int ra a;//左值引用 const int cra a;//左值常引用 //int rb 10;//右值引用 int rb 10; const int rc 10; const int rcc 10;//常性左值引用和常性右值引用等价 rb 10; cout rc rcc endl; }三、缺省函数1.缺省值可以是常量//-------------------从右向左依次赋值给完e在给d... void func(int a 5, int b 4, int c 3, int d 2 , int e 1) { printf(a%d b%d c%d d%d e%d\n, a, b, c, d, e); } int main() { func(); func(50, 40); func(50, 40, 30);//从左到右依次 }2.缺省值也可以是函数int My_rand() { srand(time(nullptr));//用秒级系统时间戳给 rand() 设置动态种子避免随机数序列固定 int numrand() % 100; return num; } void func(int a, int b My_rand()) { printf(a%d b%d\n, a, b); } int main() { func(1, 2); func(12); return 0; }3.缺省值也可以是指针int getlintenfd(const char* ip 127.0.0.1, int port 8090) { assert(ip ! NULL); int fd 0; return fd; } int main() { int fd getlintenfd(192.9.9.1); }4.缺省值在声明当C函数的声明和定义分离时缺省值在函数声明中//y.h extern void func(int a 0);//extern声明一个函数或文件是外部的 //y.cpp void func(int a 10) { }此时a0,由函数声明决定四、函数重载1.什么是函数重载函数名相同参数列表不同称为函数重载int my_max(int a, int b) { return a b ? a : b; } char my_max(char a, char b) { return a b ? a : b; } double my_max(double a, double b) { return a b ? a : b; } //不可以以返回类型作为函数重载的依据 //char my_max(int a, int b) { return a b ? a : b; } int main() { cout my_max(12, 23) endl; cout my_max(a, b) endl; cout my_max(12.3, 23.3) endl; return 0; }2.名字粉碎技术1.C 编译器为了解决函数重载、命名空间、类成员函数等特性带来的「同名标识符」问题对原函数 / 变量名进行的一种「编码重命名」机制。2.C 语言没有函数重载编译器直接用函数原名作为符号名但 C 支持重载同名函数不同参数、类、命名空间必须通过「粉碎」生成唯一的符号名让链接器能准确找到对应的函数实现。简单说名字粉碎的核心目的是为每个唯一的函数 / 变量生成全局唯一的符号名解决 C 的多态、重载等特性带来的命名冲突问题。