1.指针和引用的区别 

1.定义和本质

特性 指针 引用
本质 存储变量地址的变量 变量的别名
定义语法

int*p;(*表示的是指针)

int&ra=a;(表示的是a的别名是ra)

初始化要求 定义的时候可以不初始化 必须初始化

2.内存与存储

特性 指针 引用
内存占用 占用内存(大小等于地址长度,如 4/8 字节) 无额外内存(与绑定变量共享内存)
存储内容 存储目标变量的地址 无存储内容,直接代表目标变量

3.可空性和可变性

特性 指针 引用
可空性 可以为 nullptrint* p = nullptr; 不能为 nullptr(必须绑定变量)
指向 / 绑定修改 可重新指向其他变量(p = &b; 一旦绑定,终身不能修改
多级指针 支持(如 int** pp; 指向指针的指针) 不支持多级引用(无意义)

4.语法和使用差异

特性 指针 引用
内存占用 占用内存(大小等于地址长度,如 4/8 字节) 无额外内存(与绑定变量共享内存)
存储内容 存储目标变量的地址 无存储内容,直接代表目标变量

5.代码演示

int a = 10;

// 指针
int* p;        // 定义时可暂不初始化(值为随机地址)
p = &a;        // 后绑定到a

// 引用
int& r = a;    // 必须初始化,直接绑定到a
// int& r;     // 编译错误:引用必须初始化

int a = 10, b = 20;

// 指针:可空、可换指向
int* p = nullptr; // 合法
p = &a;           // 指向a
p = &b;           // 重新指向b

// 引用:不可空、不可换绑定
int& r = a;       // 绑定a
// r = b;        // 不是“换绑定”,而是给a赋值为b的值!
// int& r = b;   // 编译错误:引用不能重新绑定

2.缺省函数

C++ 中的缺省函数(也叫 “默认参数函数”)是指:在函数声明或定义时,为一个或多个参数指定默认值。调用函数时,若未显式传递该参数,编译器会自动使用默认值;若传递了参数,则覆盖默认值。例如:

// 单个缺省参数
void printInfo(int age, string name = "Unknown") {
    cout << "Name: " << name << ", Age: " << age << endl;
}

// 多个缺省参数
int add(int a, int b = 0, int c = 0) {
    return a + b + c;
}
int main() {
    printInfo(20);          // 省略 name,使用默认值:Name: Unknown, Age: 20
    printInfo(25, "Alice"); // 显式传递 name,覆盖默认值:Name: Alice, Age: 25

    add(10);                // 省略 b、c:10 + 0 + 0 = 10
    add(10, 20);            // 省略 c:10 + 20 + 0 = 30
    add(10, 20, 30);        // 传递全部参数:60

    // 错误:不能跳过中间参数(必须从右往左省略)
    // add(10, , 30); // 编译报错
    return 0;
}

注意事项

  • 传递全部参数:正常使用;
  • 省略部分参数:从最右侧开始省略(必须连续),编译器自动填充默认值。
  • 不能跳过中间的参数
  • 缺省函数不能重复声明
  • 默认值必须是“编译期常量”
  • 缺省函数和函数重载的优先级
// 正确:从右往左连续缺省(c→b→a)
int func1(int a = 1, int b = 2, int c = 3);

// 错误:跳过 b 给 c 设默认值(左侧参数 a、b 无默认值,右侧 c 有默认值,不符合规则)
// int func2(int a, int b = 2, int c); 

// 错误:跳过 c 给 b 设默认值(右侧 c 无默认值,左侧 b 有默认值,不符合规则)
// int func3(int a, int b = 2, int c);
// 头文件 func.h(声明,指定默认参数)
void func(int a = 10, int b = 20);

// .cpp 文件 func.cpp(定义,不能重复默认参数)
void func(int a, int b) { // 正确:无默认参数
    cout << a + b << endl;
}

// 错误:定义中重复指定默认参数
// void func(int a = 10, int b = 20) { ... }
// 缺省函数:可省略 b
void func(int a, int b = 0) { cout << "func(a, b)" << endl; }

// 重载函数:只有一个参数
void func(int a) { cout << "func(a)" << endl; }

int main() {
    func(10); // 歧义:调用 func(10) 还是 func(10, 0)?编译报错
    return 0;
}

3.函数重载

在同一作用域内,允许定义多个同名函数,但要求它们的「参数列表」必须不同(编译器通过参数列表区分调用哪个函数)。其实就是:同名不同参,功能可关联。

一般有三种参数列表不同:

1.参数个数不同

int add(int a,int b){return a+b;}
int add(int a,int b,int c){return a+b+c;}

2.参数类型不同

int add(int a,int b);
double add(double a,double b);

3.参数顺序不同

void showInfo(int age, double height);
void showInfo(double weight, int grade);

函数重载的意义:避免了相似功能起了不同的名字,能够简化代码。

函数重载的规则:

1.如果两个函数重载的参数表相同,但是返回类型不同,会被标记为编译错误:函数的重复声明。

int my_max(int a,int b)
{
    return a>b?a:b;
}
unsigned my_max(int a,int b) //error
{
    return a>b?a:b;      
}
int main()
{
    int max=my_max(12,23);
    unsigned int=my_max(12,23);//error
    return 0;
}

2.参数列表的比较过程与参数名无关

3.如果在两个函数的参数表中,只有缺省函数实参不同,则第二个声明被视为第一个的重复声明。

void Print(int *br,int n);
void Print(int *br,int len=10);

4.当一个形参类型有const或volatile修饰时。如果形参是按值传递方式定义,在识别函数声明是否相同的时候,并不考虑const或volatile修饰

void fun(int a){ }

void fun(const int a){ }

5.函数调用的二定义:

如果在两个函数的参数表中,形参类型相同,而形参个数不同,形参默认值将会影响函数的重载

void fun(int a){}
void fun(int a,int b){}
void fun(int a,int b=10);

注意:C语言不支持函数重载。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐