鱼C论坛

 找回密码
 立即注册
楼主: 我们遇见过

[已解决]链式队列的一个问题,为什么第一种可以运行,第二种没有报错但是运行会中断

[复制链接]
发表于 2018-10-4 14:33:20 | 显示全部楼层
我们遇见过 发表于 2018-10-4 14:20
不明白...抛开这道题int*p=&q,将p作为一个参数传入另一个函数,与,直接将&q作为一个参数传入另一个函数 ...

这个例子应该可以让你明白
int a, b;
swap(int x, int y), swap(a, b);    // 你知道为什么这个不能对调吗?因为传入的是副本。
swap(int *x, int*y), swap(&a, &b);   //这个很基础,应该要明白。但是传入的是指针,不是变量本身。派代表而已
swap(int &x, int &y), swap(a,b);    // 这个因为是 &x,传入的不是副本,所以可以对调。

赋值在底层是副本拷贝
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-10-4 15:15:03 | 显示全部楼层
claws0n 发表于 2018-10-4 14:33
这个例子应该可以让你明白
int a, b;
swap(int x, int y), swap(a, b);    // 你知道为什么这个不能对 ...

这三个我都知道。。可我们现在的问题不是swap(int *&x, int* &y), swap(&a,&b); 吗...
不过我好像有点明白了...引用的时候是不是不能直接引用地址啊....还有其他的一些操作都不能直接对地址操作,,必须把地址赋给一个指针进行操作..
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-4 15:29:21 | 显示全部楼层
我们遇见过 发表于 2018-10-4 15:15
这三个我都知道。。可我们现在的问题不是swap(int *&x, int* &y), swap(&a,&b); 吗...
不过我好像有点明 ...

呃…… 这样说吧,因为我给的例子是 int a, b; 所以 swap(int &x, int &y); 但如果不是整型,而是指针, int *a, *b; swap(int* &x, int* &y); swap(a,b); 最后调用的方式还是一样。这个在你第一种的代码里就呈现了。
引用是直接引用地址……嗯,你要这样理解也可以,不过应该也要了解此时传入的不再是副本。此时,传入的是变量本身。如果变量是指针,那就是指针,如果变量是纯量,那就是纯量。
后面的不是很明白你要表达的,不能对地址操作,必须把地址赋给一个指针进行操作?
如果只是地址,那么也可理解为右值,不能被赋值
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-10-4 15:55:00 | 显示全部楼层
claws0n 发表于 2018-10-4 15:29
呃…… 这样说吧,因为我给的例子是 int a, b; 所以 swap(int &x, int &y); 但如果不是整型,而是指针,  ...

我明白了引用是直接对本身的。然后我就想..因为你看 直接init(&qu)不对,但是int*p=&qu,init(p)就是对的..第二个跟第一个相比,不就是把地址赋给了指针,然后对指针进行操作吗。。然后第一个是直接取qu的地址进行操作就错了..然后我就想是不是不能直接对(&qu)这个东西进行操作,必须把它给一个指针,然后对指针进行操作
然后我试了一下,发现我错了。。对(&qu)也可以进行.啊->的操作..
算啦不想了.真的想不明白..痛苦。。。反正就以后碰到取地址就直接给一个指针,对指针操作算了...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-4 16:06:05 | 显示全部楼层
我们遇见过 发表于 2018-10-4 15:55
我明白了引用是直接对本身的。然后我就想..因为你看 直接init(&qu)不对,但是int*p=&qu,init(p)就是 ...

引用和指针有区别吗?
#include <stdio.h>

void Fun1(int &n)
{
        n = 100;
}

void Fun2(int *n)
{
        *n = 100;
}

int main()
{
        int a = 10;
        int b = 10;
        
        Fun1(a);
        Fun2(&b);

        return 0;

}
        int a = 10;
0023175E C7 45 F8 0A 00 00 00 mov         dword ptr [a],0Ah  
        int b = 10;
00231765 C7 45 EC 0A 00 00 00 mov         dword ptr [b],0Ah  
        
        Fun1(a);
0023176C 8D 45 F8             lea         eax,[a]  
0023176F 50                   push        eax  
00231770 E8 30 F9 FF FF       call        Fun1 (02310A5h)  
00231775 83 C4 04             add         esp,4  
        Fun2(&b);
00231778 8D 45 EC             lea         eax,[b]  
0023177B 50                   push        eax  
0023177C E8 3D F9 FF FF       call        Fun2 (02310BEh)  
00231781 83 C4 04             add         esp,4  
void Fun1(int &n)
{
002316C0 55                   push        ebp  
002316C1 8B EC                mov         ebp,esp  
002316C3 81 EC C0 00 00 00    sub         esp,0C0h  
002316C9 53                   push        ebx  
002316CA 56                   push        esi  
002316CB 57                   push        edi  
002316CC 8D BD 40 FF FF FF    lea         edi,[ebp-0C0h]  
002316D2 B9 30 00 00 00       mov         ecx,30h  
002316D7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
002316DC F3 AB                rep stos    dword ptr es:[edi]  
        n = 100;
002316DE 8B 45 08             mov         eax,dword ptr [n]  
002316E1 C7 00 64 00 00 00    mov         dword ptr [eax],64h  
}
002316E7 5F                   pop         edi  
}
002316E8 5E                   pop         esi  
002316E9 5B                   pop         ebx  
002316EA 8B E5                mov         esp,ebp  
002316EC 5D                   pop         ebp  
002316ED C3                   ret  
void Fun2(int *n)
{
00231700 55                   push        ebp  
00231701 8B EC                mov         ebp,esp  
00231703 81 EC C0 00 00 00    sub         esp,0C0h  
00231709 53                   push        ebx  
0023170A 56                   push        esi  
0023170B 57                   push        edi  
0023170C 8D BD 40 FF FF FF    lea         edi,[ebp-0C0h]  
00231712 B9 30 00 00 00       mov         ecx,30h  
00231717 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
0023171C F3 AB                rep stos    dword ptr es:[edi]  
        *n = 100;
0023171E 8B 45 08             mov         eax,dword ptr [n]  
00231721 C7 00 64 00 00 00    mov         dword ptr [eax],64h  
}
00231727 5F                   pop         edi  
00231728 5E                   pop         esi  
00231729 5B                   pop         ebx  
0023172A 8B E5                mov         esp,ebp  
0023172C 5D                   pop         ebp  
0023172D C3                   ret  

#include <stdio.h>

void Fun1(int *&n)
{
        static int test = 0;
        n = &test;
}

void Fun2(int **n)
{
        static int test = 0;
        *n = &test;
}

int main()
{
        int *a = NULL;
        int *b = NULL;
        
        Fun1(a);
        Fun2(&b);

        return 0;

}
        int *a = NULL;
00A3175E C7 45 F8 00 00 00 00 mov         dword ptr [a],0  
        int *b = NULL;
00A31765 C7 45 EC 00 00 00 00 mov         dword ptr [b],0  
        
        Fun1(a);
00A3176C 8D 45 F8             lea         eax,[a]  
00A3176F 50                   push        eax  
00A31770 E8 83 FB FF FF       call        Fun1 (0A312F8h)  
00A31775 83 C4 04             add         esp,4  
        Fun2(&b);
00A31778 8D 45 EC             lea         eax,[b]  
00A3177B 50                   push        eax  
00A3177C E8 31 FB FF FF       call        Fun2 (0A312B2h)  
00A31781 83 C4 04             add         esp,4  
void Fun1(int *&n)
{
00A316C0 55                   push        ebp  
00A316C1 8B EC                mov         ebp,esp  
00A316C3 81 EC C0 00 00 00    sub         esp,0C0h  
00A316C9 53                   push        ebx  
00A316CA 56                   push        esi  
00A316CB 57                   push        edi  
00A316CC 8D BD 40 FF FF FF    lea         edi,[ebp-0C0h]  
00A316D2 B9 30 00 00 00       mov         ecx,30h  
00A316D7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
00A316DC F3 AB                rep stos    dword ptr es:[edi]  
        static int test = 0;
        n = &test;
00A316DE 8B 45 08             mov         eax,dword ptr [n]  
00A316E1 C7 00 38 91 A3 00    mov         dword ptr [eax],offset test (0A39138h)  
}
00A316E7 5F                   pop         edi  
}
00A316E8 5E                   pop         esi  
00A316E9 5B                   pop         ebx  
00A316EA 8B E5                mov         esp,ebp  
00A316EC 5D                   pop         ebp  
00A316ED C3                   ret  
void Fun2(int **n)
{
00A31700 55                   push        ebp  
00A31701 8B EC                mov         ebp,esp  
00A31703 81 EC C0 00 00 00    sub         esp,0C0h  
00A31709 53                   push        ebx  
00A3170A 56                   push        esi  
00A3170B 57                   push        edi  
00A3170C 8D BD 40 FF FF FF    lea         edi,[ebp-0C0h]  
00A31712 B9 30 00 00 00       mov         ecx,30h  
00A31717 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
00A3171C F3 AB                rep stos    dword ptr es:[edi]  
        static int test = 0;
        *n = &test;
00A3171E 8B 45 08             mov         eax,dword ptr [n]  
00A31721 C7 00 3C 91 A3 00    mov         dword ptr [eax],offset test (0A3913Ch)  
}
00A31727 5F                   pop         edi  
00A31728 5E                   pop         esi  
00A31729 5B                   pop         ebx  
00A3172A 8B E5                mov         esp,ebp  
00A3172C 5D                   pop         ebp  
00A3172D C3                   ret  


在汇编语言层,引用和指针没有区别
普通变量的引用就是一级指针
一级指针的引用就是二级指针

要修改普通变量,要用一级指针(普通引用)
要修改一级指针,要用二级指针(引用一级指针)


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-4 16:17:22 | 显示全部楼层
我们遇见过 发表于 2018-10-4 15:55
我明白了引用是直接对本身的。然后我就想..因为你看 直接init(&qu)不对,但是int*p=&qu,init(p)就是 ...

第一个代码,那个 qu 是废的,根本没有实质的作用。虽然一开始指针参考的是它,但是进入函数之后,却被重新赋值了(申请动态内存)。所以你后面的想多了。你把 qu 删了,也是可以执行

第二个代码错,基本上是因为它不是指针,而你透过小技巧强行把它化为指针,那是很危险的。
void init(Lq *qu); //参考 Lq 类型,而 Lq qu; init(&qu); 这里没有错,但是 qu = (Lq *)malloc(sizeof(Lq)); 这句我觉得是有问题的。你的问题不明显,我觉得是巧合,如果真的是指针,那么 sizeof(qu) 始终是 4 或 8。而你的 typedef struct Qnode {int , Qnode*} 也是 8,但 64位就是 12。即使说这句没有问题,到后面,bool is_empty(Lq *qu); void in_qu(Lq *qu, int a){...  if(is_empty(qu))  ...} 你的 qu 到底是什么类型?你改也好,还是结构,不是指针
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-10-4 16:17:50 | 显示全部楼层
人造人 发表于 2018-10-4 16:06
引用和指针有区别吗?

不是我感觉我现在迷惑的是如果 int*p=&qu;那么p和&pu有什么区别啊,应该有区别吧,如果没有怎么会init(p)是对的而init(&qu)是错的..
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-10-4 16:26:50 | 显示全部楼层
claws0n 发表于 2018-10-4 16:17
第一个代码,那个 qu 是废的,根本没有实质的作用。虽然一开始指针参考的是它,但是进入函数之后,却被重 ...

跟后面的没关系吧。。因为我把后面的全部注释掉值留下init这个函数,只执行init(&qu)还是不对的,,然后我想找个错是不是因为int*p=&qu;p和&qu是不一样的啊,引用的时候只能引用p而不能引用(&qu)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-4 16:36:29 | 显示全部楼层
我们遇见过 发表于 2018-10-4 16:17
不是我感觉我现在迷惑的是如果 int*p=&qu;那么p和&pu有什么区别啊,应该有区别吧,如果没有怎么会init( ...

放下这个问题继续向后学吧,因为现在不管怎么解释,你也应该还是无法理解
想要理解这个,你一定要学习汇编语言
在汇编语言层,指针就是引用
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-4 16:38:18 | 显示全部楼层
我们遇见过 发表于 2018-10-4 16:17
不是我感觉我现在迷惑的是如果 int*p=&qu;那么p和&pu有什么区别啊,应该有区别吧,如果没有怎么会init( ...

站在汇编语言的角度看引用,你会看到它和指针是多么的相似,甚至于找不到区别
引用就是指针
指针就是引用
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-4 16:40:18 | 显示全部楼层
我们遇见过 发表于 2018-10-4 16:17
不是我感觉我现在迷惑的是如果 int*p=&qu;那么p和&pu有什么区别啊,应该有区别吧,如果没有怎么会init( ...

现在你要想理解这个,那就只能看我上面的那个代码了,如果看不懂,那就暂时放下这个问题吧
之后你还会遇到的,带上汇编语言再来看这个问题好吗?

引用就是指针
指针就是引用
没有区别
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-10-4 16:43:12 | 显示全部楼层
人造人 发表于 2018-10-4 16:40
现在你要想理解这个,那就只能看我上面的那个代码了,如果看不懂,那就暂时放下这个问题吧
之后你还会遇 ...

不是啊。。我感觉现在不是引用的问题...是为什么int*p=&qu,引用p是对的,引用(&qu)就是错的...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-4 16:45:33 | 显示全部楼层
我们遇见过 发表于 2018-10-4 16:26
跟后面的没关系吧。。因为我把后面的全部注释掉值留下init这个函数,只执行init(&qu)还是不对的,,然 ...

p = &qu; 当然有区别,它们的地址不一样,还是两个变量。p 能作用在 qu 上,但是 qu 不能作用在 p 上。单向性的操作。
呃……这中间衍生出三四个代码了,不知道你说的是哪一个,如果是 10 楼给的那一个,就是我说的东西。但不管是哪一个代码,数据类型不匹配
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-10-4 16:57:45 | 显示全部楼层
claws0n 发表于 2018-10-4 16:45
p = &qu; 当然有区别,它们的地址不一样,还是两个变量。p 能作用在 qu 上,但是 qu 不能作用在 p 上。单 ...

所以啊 我这个问题现在简单来说不就是引用p是对的,引用(&qu)是错的。。是他们的区别造成的。。?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-4 17:06:20 | 显示全部楼层
我们遇见过 发表于 2018-10-4 16:43
不是啊。。我感觉现在不是引用的问题...是为什么int*p=&qu,引用p是对的,引用(&qu)就是错的...

把你现在的问题完整的说一下,要完整的
上面太乱了
重新,完整的,说一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-4 17:10:30 | 显示全部楼层
我们遇见过 发表于 2018-10-4 16:57
所以啊 我这个问题现在简单来说不就是引用p是对的,引用(&qu)是错的。。是他们的区别造成的。。?{:10_ ...

代码一,把 qu 删掉,然后想一想,然后就对了
数据类型………………
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-10-4 18:33:32 | 显示全部楼层
claws0n 发表于 2018-10-4 17:10
代码一,把 qu 删掉,然后想一想,然后就对了
数据类型………………

代码一本来就是对的啊。。。代码一我理解啊,,,Lq*p=&qu,p和&qu的数据类型不一样吗。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-10-4 18:39:05 | 显示全部楼层
人造人 发表于 2018-10-4 17:06
把你现在的问题完整的说一下,要完整的
上面太乱了
重新,完整的,说一下

就是我代码里有一个函数
void init(Lq*&qu)//Lq是一个结构体
然乎main{
  Lq * p;init(p)//这个是对的
  Lq    p;init(&p)//这个编译器会报错。 错误信息是不能将一个 Lq*型转变为Lq*&型,不明白这个为什么会错。正确的那个里面,p不也是 Lq*型吗
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-4 18:50:15 | 显示全部楼层
我们遇见过 发表于 2018-10-4 18:39
就是我代码里有一个函数
void init(Lq*&qu)//Lq是一个结构体
然乎main{

你都不愿意详细描述一下你的问题吗?我还特别强调了详细描述
我整理了一下代码,你现在的问题是不是
这两个代码为什么第一个可以通过编译,第二个无法通过编译?
#include <cstdio>
#include <cstdlib>

typedef struct Qnode
{
        int data;
        Qnode *next;
}Qnode;

typedef struct Lq
{
        Qnode *front;
        Qnode *rear;
}Lq;

void init(Lq *&qu)
{
        qu = (Lq *)malloc(sizeof(Lq));
        (*qu).front = (*qu).rear = NULL;
        printf("初始化成功!\n");
}

int main()
{
        Lq qu;
        Lq *p;
        p = &qu;
        init(p);

        return 0;

}
#include <cstdio>
#include <cstdlib>

typedef struct Qnode
{
        int data;
        Qnode *next;
}Qnode;

typedef struct Lq
{
        Qnode *front;
        Qnode *rear;
}Lq;

void init(Lq *&qu)
{
        qu = (Lq *)malloc(sizeof(Lq));
        (*qu).front = (*qu).rear = NULL;
        printf("初始化成功!\n");
}

int main()
{
        Lq qu;
        init(&qu);

        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-10-4 19:11:35 | 显示全部楼层
人造人 发表于 2018-10-4 18:50
你都不愿意详细描述一下你的问题吗?我还特别强调了详细描述
我整理了一下代码,你现在的问题是不是
这 ...

嗯。。对对,我想着应该就只出在实参和形参那。。所以就说了那么多,就是第一个可以编译,第二个不可以
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-24 02:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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