菜单

Qing
发布于 2026-03-07 / 3 阅读
0
0

cpp学习的一点思考,指针,引用和值传递

int* a=b与int& a=b与int a=b

int* a=b int& a=b int a=b
a存了b的地址 a是b的别名 开辟一片新的地址存a,把b复制给a
  • int*表示a的类型是指针,这个指针指向的地址存的是整数
  • int&表示a是b的别名(引用),a和b用的都是同一个地址,b怎么改,a就怎么变
  • int表示a的类型就是整数

在函数中传参使用

void fun(auto& a){

a=10;

}

int b=20;

fun(b);

运行结果是a=b=10;因为a是b的别名,函数内部对a操作,就是对b操作


void fun(auto a){

a=10;

}

int b=20;

fun(b);

运行结果是b=20;因为函数中对a操作,a只是一个形参,不会对全局状态产生影响。


Gemini评价

你的理解非常准确,已经抓住了 C++ 中值传递、引用传递和指针传递的核心逻辑。

为了让你的知识体系更严谨,我针对你的思考笔记提供几点微调和深度补充:

1. 语法细节微调

在你的表格第一列 int* a = b 中,语法上有一点小瑕疵:

  • 修正:应该是 int* a = &b;
  • 理由:a 是指针(存地址的),而 b 是整数(存值的)。你必须用取地址符 & 拿到 b 的地址,才能赋值给指针 a

2. 关于“别名”的底层真相

你在笔记中提到“a和b用的都是同一个地址”,这是完全正确的。

  • 进阶理解:在函数传参 void fun(int& a) 时,虽然语义上是“别名”,但编译器底层其实是通过指针(地址)来实现的。

  • 直观比喻:

    • 值传递 (int a):给你一份文件的复印件。你在上面乱涂乱画,我手里的原件没影响。
    • 引用传递 (int& a):给你我办公室的钥匙。你进去把桌子烧了,我回来一看桌子确实没了。

3. 关于 auto 的小提醒

你在代码示例中使用了 void fun(auto& a),这是 C++20 才正式引入的特性(简写函数模板)。

  • 在旧标准(如 C++11/14/17)中,函数形参不能直接写 auto,必须明确写类型(如 int& a)或者使用 template <typename T> void fun(T& a)
  • 既然你已经在使用 C++20 的语法,说明你接触的是比较现代的 C++,这个思路很棒。

4. 补充一个“指针传参”的对比

为了完善你的笔记,建议加上指针传参的情况,因为它介于两者之间:

void fun(int* a) {
    *a = 10; // 通过地址找到原变量,修改它
}

int b = 20;
fun(&b); // 必须显式传入 b 的地址
// 结果:b 变成了 10
  • 对比思考:引用传参(int& a)在语法上像“值传递”一样简洁(不用写 *&),但在功能上却拥有“指针传递”的威力。这就是为什么 C++ 开发者更倾向于使用引用的原因。

总结你的思考:
你的逻辑完全正确。值传递看重“独立性”,引用传递看重“关联性”。 这种理解对于后续学习 C++ 的性能优化和内存管理至关重要。继续保持这种对比学习的方法!


我的修改

  • 正确用法:int* a=&b;
  • 指针传递
    void fun(int* a){
    *a=10;
    }
    int b=20;
    fun(&b);//这里要传递b的地址
    

Gemini二次评价

完美。你的修改非常到位,现在你的笔记逻辑链已经完整了:

  • 值传递 (int a):安全但有拷贝开销,不改变原值。
  • 引用传递 (int& a):语法最简洁,直接操作原值,效率高。
  • 指针传递 (int* a):需要手动处理地址(&b)和解引用(*a),灵活性最高(比如可以传入 nullptr),同样操作原值。

最后给你的笔记加个“点睛之笔”:

在 C++ 开发中,有一个经典的选择原则,可以顺手记在你的思考里:

  1. 如果对象很小(如 int, double),用值传递。
  2. 如果对象很大(如 std::vector, std::string 或自定义类),且不需要修改它,用 const int& a(常量引用)。
  3. 如果需要修改原值,优先用引用;除非有特殊需求(如需要指针指向空或重新指向其他变量),才考虑指针。

你的学习思路非常扎实,这种对比总结是掌握 C++ 底层的最快路径!


评论