鱼C论坛

 找回密码
 立即注册
查看: 1502|回复: 31

[已解决]c++ 函数传指针 和引用有啥区别

[复制链接]
发表于 2021-9-11 20:40:23 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
int abc(int &a,int &b,int &c)
...
传引用的话,是不是不用创建一个临时的对象(不用临时空间
而传指针的话 , 还要创建一个指针对象


百度查了查,都是抄来抄去的
最佳答案
2021-9-14 00:35:45
万千只cnm 发表于 2021-9-13 23:49
啥意思
引用和指针作为形参 都不需要额外空间嘛
但是指针本身不是一个对象吗

你非要说指针本身就是一个对象,这也完全可以,不能说你错
下面这么说是可以的
#include <iostream>

class test_t {
public:
    test_t(): n(0) {}
private:
    int n;
};

int main() {
    int a = 0;          // 创建了一个对象 a,类型是 int
    int *pa = &a;       // 创建了一个对象 pa,类型是 int *
    int &ra = a;        // 创建了一个对象 ra,类型是 int &
    test_t t;           // 创建了一个对象 t,类型是 test_t
    test_t *pt = &t;    // 创建了一个对象 pt,类型是 test_t *
    test_t &rt = t;     // 创建了一个对象 rt, 类型是 test_t &
    return 0;
}


下面这个代码,你说调用函数 func 的时候,变量 c,需要额外空间吗?
如果你说需要,那么变量 a 和变量 b 也需要
如果你说变量 c 不需要,那么变量 a 和变量 b 也不需要
变量 a,b,c,这 3 个变量是一样的,都是函数的参数,都是局部变量
不一样的地方也有
变量 c 中存储的是数字 0,变量 c 占用 4 个字节的内存空间
变量 a 和变量 b 中存储的都是同一个数字,这个数字的值是 &x,这个 &x 就是一个地址,一个数字,一个比较大的数字
变量 a 和变量 b,占用 8 个字节
而变量 c 占用 4 个字节
注意,这是在我这边,在别的机器上,输出可能会不一样
#include <iostream>

void func(int &a, int *b, int c) {
    printf("a: %lu\n", sizeof(a));
    printf("b: %lu\n", sizeof(b));
    printf("c: %lu\n", sizeof(c));
}

int main() {
    int x = 0;
    func(x, &x, x);
    return 0;
}

/*
a: 4
b: 8
c: 4
*/

这里输出的 a 是 4,但是变量 a 不是占用 4 个字节,一定不是,一定是和变量 b 相同,b 是 8,a 一定是 8
之所以这里输出的 a 是 4,是因为这是在 C++ 层,因为变量 a 引用了 变量 x,这里的 sizeof(a),就是 sizeof(x),所以会得到 4,但是在汇编语言层,变量 a 占用 8 个字节,和变量 b 一样
main:
.LFB1738:
        pushq        %rbp
        .seh_pushreg        %rbp
        movq        %rsp, %rbp
        .seh_setframe        %rbp, 0
        subq        $48, %rsp
        .seh_stackalloc        48
        .seh_endprologue
        call        __main
        movl        $0, -4(%rbp)        # int x = 0;
        movl        -4(%rbp), %ecx      # c 使用 movl 指令,4 个字节
        leaq        -4(%rbp), %rdx      # b 使用 leaq 指令,8 个字节
        leaq        -4(%rbp), %rax      # a 使用 leaq 指令,8 个字节
        movl        %ecx, %r8d
        movq        %rax, %rcx
        call        _Z4funcRiPii        # call func
        movl        $0, %eax
        addq        $48, %rsp
        popq        %rbp
        ret


也就是说,所有的对象都不需要额外的空间,有这个对象本身的空间就够了
函数的参数就是个局部变量
具体每一个对象占用多少字节,用 sizeof 算一下就是了
但是,但是这个 sizeof 对引用无效,一个引用 使用 sizeof 算出来的是 引用的那个对象的大小,不是引用本身的大小,引用本身的大小和指针的大小是一样的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-9-11 20:55:46 | 显示全部楼层
都要用临时空间吧,局部变量的作用域都是在创建它的那个函数的开始到结束
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-11 21:42:48 | 显示全部楼层
https://www.zhihu.com/question/37608201
视频中说引用的本质是常量指针
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-11 23:20:29 | 显示全部楼层
而传指针的话 , 还要创建一个指针对象
传指针也不需要创建对象,指针就是一个地址
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-12 08:15:14 From FishC Mobile | 显示全部楼层
函数运行时的时候,数据一般是放在栈里面的,等函数运行结束,栈会恢复原来的状态。也就是函数内的局部变量会作废。所以函数体内要改变函数外的数据,必定要告诉函数地址。因而引用也需要在函数调用前就需要开辟一临时空间用于存储地址。但64位代码和一些编译器也会把地址存入CPU的寄存器中而不是在内存中开辟一临时空间。其实在函数中计算机处理指针变量在这里和引用没什么区别
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-12 11:04:41 | 显示全部楼层
引用在绝大多数情况下都是用指针实现的
所以你可以认为对于编译后的源码,指针和引用没有任何区别
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-13 13:35:46 | 显示全部楼层
routty 发表于 2021-9-12 08:15
函数运行时的时候,数据一般是放在栈里面的,等函数运行结束,栈会恢复原来的状态。也就是函数内的局部变量 ...

原来你是个高手,深藏不露!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-13 13:54:38 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-9-13 21:06:02 | 显示全部楼层
指针是一个地址,但是他的数据在栈里,在代码块结束后就会还原,不会对外面的数据造成影响,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-13 21:07:36 | 显示全部楼层
2736946915 发表于 2021-9-13 21:06
指针是一个地址,但是他的数据在栈里,在代码块结束后就会还原,不会对外面的数据造成影响,

指针变量也不一定在栈区的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-13 21:13:02 | 显示全部楼层
指针是一个地址,但是他的数据在栈里,在代码块结束后就会还原,不会对外面的数据造成影响,
引用是要创建对象的,传的也是一个地址,但是是对象的地址,数据是保存在堆区,会直接修改外面的值,

总结一下就是:
传指针为了临时用用,不想它对外面的数据改来改去,随便玩对外面数据不造成影响,
传引用能改变外面的数据,为了改变某个状态,某个变量之类的,不然数据改了后可能会导致其他地方出现BUG
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-13 21:14:08 | 显示全部楼层
lhgzbxhz 发表于 2021-9-12 11:04
引用在绝大多数情况下都是用指针实现的
所以你可以认为对于编译后的源码,指针和引用没有任何区别

还是有区别的,一个栈区的生命怎么能和堆区比...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-13 21:17:46 | 显示全部楼层
routty 发表于 2021-9-13 21:07
指针变量也不一定在栈区的

那是静态变量,分配在堆上,这种情况很少,一般都会封装,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-13 21:34:29 | 显示全部楼层
2736946915 发表于 2021-9-13 21:13
指针是一个地址,但是他的数据在栈里,在代码块结束后就会还原,不会对外面的数据造成影响,
引用是要创建 ...

?
#include <iostream>

void func(int *p) {
    *p = 123;
}

int main() {
    int a = 0;
    printf("%d\n", a);
    func(&a);
    printf("%d\n", a);
    return 0;
}
#include <iostream>

void func(const int &p) {
    p = 123;
}

int main() {
    int a = 0;
    printf("%d\n", a);
    func(a);
    printf("%d\n", a);
    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-13 21:35:11 | 显示全部楼层
2736946915 发表于 2021-9-13 21:13
指针是一个地址,但是他的数据在栈里,在代码块结束后就会还原,不会对外面的数据造成影响,
引用是要创建 ...

全局指针变量,也不是随便用用的。应该说函数内的局部变量,包括局部指针变量,或形参是指针变量的那是在栈区,函数结束就会被作废
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-13 21:35:16 | 显示全部楼层
2736946915 发表于 2021-9-13 21:13
指针是一个地址,但是他的数据在栈里,在代码块结束后就会还原,不会对外面的数据造成影响,
引用是要创建 ...

指针和引用一样,都是一个地址,都不需要创建对象的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-13 21:37:12 | 显示全部楼层
人造人 发表于 2021-9-13 21:35
指针和引用一样,都是一个地址,都不需要创建对象的

引用没有对象你引用谁?编译器都会直接报错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-13 21:38:24 | 显示全部楼层
2736946915 发表于 2021-9-13 21:37
引用没有对象你引用谁?编译器都会直接报错

"引用" 引用的是已经存在的对象,不创建对象的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-13 21:44:49 | 显示全部楼层
routty 发表于 2021-9-13 21:35
全局指针变量,也不是随便用用的。应该说函数内的局部变量,包括局部指针变量,或形参是指针变量的那是在 ...

全局的确实也是,但是极不推荐,这样做会害死其他人,让别人都不敢碰你代码,一般来说都会去写个接口函数,一为减少BUG,二为安全,别人破解也不会那么简单找到你的ECX,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-9-13 21:45:57 | 显示全部楼层
人造人 发表于 2021-9-13 21:38
"引用" 引用的是已经存在的对象,不创建对象的

对,其实底层汇编以后处理方式和指针差不多,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-15 21:08

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表