鱼C论坛

 找回密码
 立即注册
查看: 6875|回复: 51

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

[复制链接]
发表于 2018-10-4 01:39:41 | 显示全部楼层
claws0n 发表于 2018-10-4 00:48
vc6.0 ...... 加油
编译器:MinGW GCC 8.10 64位   状态:没问题
编译器:Borland C++ 64 ...

1.png
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-4 02:19:01 | 显示全部楼层

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. typedef struct Qnode//队列结点定义
  4. {
  5.         int data;
  6.         Qnode* next;
  7. }Qnode;

  8. typedef struct Lq//链队类型定义
  9. {
  10.         Qnode* front;
  11.         Qnode* rear;
  12. }Lq;

  13. bool is_empty(Lq *qu)//判断是否队空
  14. {
  15.         printf("%d\n", sizeof(qu));
  16.         if(qu->front == NULL || qu->rear == NULL)
  17.                 return true;
  18.         else
  19.                 return false;
  20. }

  21. // 初始化
  22. void init(Lq *qu)
  23. {
  24.         qu = (Lq *)malloc(sizeof(Lq));
  25.         (*qu).front = (*qu).rear = NULL;
  26.         printf("初始化成功!\n");
  27. }


  28. void in_qu(Lq *qu, int a)//入队
  29. {
  30.         Qnode *s;
  31.         s = (Qnode*)malloc(sizeof(Qnode));
  32.         s->next = NULL;
  33.         s->data = a;
  34.         printf("in\n");
  35.         if(is_empty(qu))
  36.         {
  37.                 printf("2\n");
  38.                 qu->front = qu->rear = s;
  39.         }
  40.         else
  41.         {
  42.                 printf("3\n");
  43.                 qu->rear->next = s;
  44.                 printf("4\n");
  45.                 qu->rear = s;
  46.         }
  47.         printf("in2\n");
  48.         return;
  49. }

  50. void out_qu(Lq *qu)//出队
  51. {
  52.         Qnode *p;
  53.         int a;
  54.         if(is_empty(qu))
  55.         {
  56.                 printf("队空不能出队!\n");
  57.                 return;
  58.         }
  59.         p = qu->front;
  60.         a = qu->front->data;
  61.         qu->front = p->next;
  62.         if(qu->front == NULL)//即队列中只有一个元素
  63.                 qu->rear = NULL;
  64.         free(p);
  65.         printf("出队的元素是:%d\n", a);
  66.         return;
  67. }

  68. void out_qu(Lq *qu);
  69. void in_qu(Lq *qu, int a);
  70. bool is_empty(Lq *qu);
  71. void init(Lq *qu);

  72. int main()
  73. {
  74.         Lq qu;

  75.         Lq *tmp = &qu;
  76.         printf("front:%.8X, rear:%.8X\n", tmp->front, tmp->rear);
  77.         init(&qu);
  78.         printf("front:%.8X, rear:%.8X\n", tmp->front, tmp->rear);
  79.        
  80.         printf("*******************************\n");
  81.         qu.front = NULL;
  82.         qu.rear = NULL;
  83.         printf("front:%.8X, rear:%.8X\n", tmp->front, tmp->rear);
  84.         exit(1);
  85.        
  86.         printf("1\n");
  87.         in_qu(&qu, 1);
  88.         printf("12\n");
  89.         out_qu(&qu);
  90.         return 0;

  91. }
复制代码

  1. front:CCCCCCCC, rear:CCCCCCCC
  2. 初始化成功!
  3. front:CCCCCCCC, rear:CCCCCCCC
  4. *******************************
  5. front:00000000, rear:00000000
  6. 请按任意键继续. . .
复制代码

  1. // 初始化
  2. void init(Lq *qu)
  3. {
  4.         qu = (Lq *)malloc(sizeof(Lq));
  5.         (*qu).front = (*qu).rear = NULL;
  6.         printf("初始化成功!\n");
  7. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-4 02:28:53 | 显示全部楼层
  1. #include <stdio.h>

  2. void Fun1(int *n)
  3. {
  4.         n = 0;
  5. }

  6. void Fun2(int *n)
  7. {
  8.         *n = 0;
  9. }

  10. int main()
  11. {
  12.         int a = 10;
  13.        
  14.         printf("%.8X\n", a);
  15.         Fun1(&a);
  16.         printf("%.8X\n", a);
  17.         printf("\n");

  18.         printf("%.8X\n", a);
  19.         Fun2(&a);
  20.         printf("%.8X\n", a);

  21.         return 0;

  22. }
复制代码

  1. 0000000A
  2. 0000000A

  3. 0000000A
  4. 00000000
  5. 请按任意键继续. . .
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

引用和指针有区别吗?

  1. #include <stdio.h>

  2. void Fun1(int &n)
  3. {
  4.         n = 100;
  5. }

  6. void Fun2(int *n)
  7. {
  8.         *n = 100;
  9. }

  10. int main()
  11. {
  12.         int a = 10;
  13.         int b = 10;
  14.        
  15.         Fun1(a);
  16.         Fun2(&b);

  17.         return 0;

  18. }
复制代码

  1.         int a = 10;
  2. 0023175E C7 45 F8 0A 00 00 00 mov         dword ptr [a],0Ah  
  3.         int b = 10;
  4. 00231765 C7 45 EC 0A 00 00 00 mov         dword ptr [b],0Ah  
  5.        
  6.         Fun1(a);
  7. 0023176C 8D 45 F8             lea         eax,[a]  
  8. 0023176F 50                   push        eax  
  9. 00231770 E8 30 F9 FF FF       call        Fun1 (02310A5h)  
  10. 00231775 83 C4 04             add         esp,4  
  11.         Fun2(&b);
  12. 00231778 8D 45 EC             lea         eax,[b]  
  13. 0023177B 50                   push        eax  
  14. 0023177C E8 3D F9 FF FF       call        Fun2 (02310BEh)  
  15. 00231781 83 C4 04             add         esp,4  
复制代码

  1. void Fun1(int &n)
  2. {
  3. 002316C0 55                   push        ebp  
  4. 002316C1 8B EC                mov         ebp,esp  
  5. 002316C3 81 EC C0 00 00 00    sub         esp,0C0h  
  6. 002316C9 53                   push        ebx  
  7. 002316CA 56                   push        esi  
  8. 002316CB 57                   push        edi  
  9. 002316CC 8D BD 40 FF FF FF    lea         edi,[ebp-0C0h]  
  10. 002316D2 B9 30 00 00 00       mov         ecx,30h  
  11. 002316D7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
  12. 002316DC F3 AB                rep stos    dword ptr es:[edi]  
  13.         n = 100;
  14. 002316DE 8B 45 08             mov         eax,dword ptr [n]  
  15. 002316E1 C7 00 64 00 00 00    mov         dword ptr [eax],64h  
  16. }
  17. 002316E7 5F                   pop         edi  
  18. }
  19. 002316E8 5E                   pop         esi  
  20. 002316E9 5B                   pop         ebx  
  21. 002316EA 8B E5                mov         esp,ebp  
  22. 002316EC 5D                   pop         ebp  
  23. 002316ED C3                   ret  
复制代码

  1. void Fun2(int *n)
  2. {
  3. 00231700 55                   push        ebp  
  4. 00231701 8B EC                mov         ebp,esp  
  5. 00231703 81 EC C0 00 00 00    sub         esp,0C0h  
  6. 00231709 53                   push        ebx  
  7. 0023170A 56                   push        esi  
  8. 0023170B 57                   push        edi  
  9. 0023170C 8D BD 40 FF FF FF    lea         edi,[ebp-0C0h]  
  10. 00231712 B9 30 00 00 00       mov         ecx,30h  
  11. 00231717 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
  12. 0023171C F3 AB                rep stos    dword ptr es:[edi]  
  13.         *n = 100;
  14. 0023171E 8B 45 08             mov         eax,dword ptr [n]  
  15. 00231721 C7 00 64 00 00 00    mov         dword ptr [eax],64h  
  16. }
  17. 00231727 5F                   pop         edi  
  18. 00231728 5E                   pop         esi  
  19. 00231729 5B                   pop         ebx  
  20. 0023172A 8B E5                mov         esp,ebp  
  21. 0023172C 5D                   pop         ebp  
  22. 0023172D C3                   ret  
复制代码


  1. #include <stdio.h>

  2. void Fun1(int *&n)
  3. {
  4.         static int test = 0;
  5.         n = &test;
  6. }

  7. void Fun2(int **n)
  8. {
  9.         static int test = 0;
  10.         *n = &test;
  11. }

  12. int main()
  13. {
  14.         int *a = NULL;
  15.         int *b = NULL;
  16.        
  17.         Fun1(a);
  18.         Fun2(&b);

  19.         return 0;

  20. }
复制代码

  1.         int *a = NULL;
  2. 00A3175E C7 45 F8 00 00 00 00 mov         dword ptr [a],0  
  3.         int *b = NULL;
  4. 00A31765 C7 45 EC 00 00 00 00 mov         dword ptr [b],0  
  5.        
  6.         Fun1(a);
  7. 00A3176C 8D 45 F8             lea         eax,[a]  
  8. 00A3176F 50                   push        eax  
  9. 00A31770 E8 83 FB FF FF       call        Fun1 (0A312F8h)  
  10. 00A31775 83 C4 04             add         esp,4  
  11.         Fun2(&b);
  12. 00A31778 8D 45 EC             lea         eax,[b]  
  13. 00A3177B 50                   push        eax  
  14. 00A3177C E8 31 FB FF FF       call        Fun2 (0A312B2h)  
  15. 00A31781 83 C4 04             add         esp,4  
复制代码

  1. void Fun1(int *&n)
  2. {
  3. 00A316C0 55                   push        ebp  
  4. 00A316C1 8B EC                mov         ebp,esp  
  5. 00A316C3 81 EC C0 00 00 00    sub         esp,0C0h  
  6. 00A316C9 53                   push        ebx  
  7. 00A316CA 56                   push        esi  
  8. 00A316CB 57                   push        edi  
  9. 00A316CC 8D BD 40 FF FF FF    lea         edi,[ebp-0C0h]  
  10. 00A316D2 B9 30 00 00 00       mov         ecx,30h  
  11. 00A316D7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
  12. 00A316DC F3 AB                rep stos    dword ptr es:[edi]  
  13.         static int test = 0;
  14.         n = &test;
  15. 00A316DE 8B 45 08             mov         eax,dword ptr [n]  
  16. 00A316E1 C7 00 38 91 A3 00    mov         dword ptr [eax],offset test (0A39138h)  
  17. }
  18. 00A316E7 5F                   pop         edi  
  19. }
  20. 00A316E8 5E                   pop         esi  
  21. 00A316E9 5B                   pop         ebx  
  22. 00A316EA 8B E5                mov         esp,ebp  
  23. 00A316EC 5D                   pop         ebp  
  24. 00A316ED C3                   ret  
复制代码

  1. void Fun2(int **n)
  2. {
  3. 00A31700 55                   push        ebp  
  4. 00A31701 8B EC                mov         ebp,esp  
  5. 00A31703 81 EC C0 00 00 00    sub         esp,0C0h  
  6. 00A31709 53                   push        ebx  
  7. 00A3170A 56                   push        esi  
  8. 00A3170B 57                   push        edi  
  9. 00A3170C 8D BD 40 FF FF FF    lea         edi,[ebp-0C0h]  
  10. 00A31712 B9 30 00 00 00       mov         ecx,30h  
  11. 00A31717 B8 CC CC CC CC       mov         eax,0CCCCCCCCh  
  12. 00A3171C F3 AB                rep stos    dword ptr es:[edi]  
  13.         static int test = 0;
  14.         *n = &test;
  15. 00A3171E 8B 45 08             mov         eax,dword ptr [n]  
  16. 00A31721 C7 00 3C 91 A3 00    mov         dword ptr [eax],offset test (0A3913Ch)  
  17. }
  18. 00A31727 5F                   pop         edi  
  19. 00A31728 5E                   pop         esi  
  20. 00A31729 5B                   pop         ebx  
  21. 00A3172A 8B E5                mov         esp,ebp  
  22. 00A3172C 5D                   pop         ebp  
  23. 00A3172D C3                   ret  
复制代码



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

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


小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

使用道具 举报

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

站在汇编语言的角度看引用,你会看到它和指针是多么的相似,甚至于找不到区别
引用就是指针
指针就是引用
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

引用就是指针
指针就是引用
没有区别
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

把你现在的问题完整的说一下,要完整的
上面太乱了
重新,完整的,说一下
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

  1. #include <cstdio>
  2. #include <cstdlib>

  3. typedef struct Qnode
  4. {
  5.         int data;
  6.         Qnode *next;
  7. }Qnode;

  8. typedef struct Lq
  9. {
  10.         Qnode *front;
  11.         Qnode *rear;
  12. }Lq;

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

  19. int main()
  20. {
  21.         Lq qu;
  22.         Lq *p;
  23.         p = &qu;
  24.         init(p);

  25.         return 0;

  26. }
复制代码

  1. #include <cstdio>
  2. #include <cstdlib>

  3. typedef struct Qnode
  4. {
  5.         int data;
  6.         Qnode *next;
  7. }Qnode;

  8. typedef struct Lq
  9. {
  10.         Qnode *front;
  11.         Qnode *rear;
  12. }Lq;

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

  19. int main()
  20. {
  21.         Lq qu;
  22.         init(&qu);

  23.         return 0;
  24. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-4 19:35:42 | 显示全部楼层    本楼为最佳答案   
我们遇见过 发表于 2018-10-4 19:11
嗯。。对对,我想着应该就只出在实参和形参那。。所以就说了那么多,就是第一个可以编译,第二个不可以


r1是一个引用,引用了变量a
r2是一个const引用,引用了常量3
如果不加const会报错,因为引用的是右值,常量是右值
  1. int main()
  2. {
  3.         int a = 100;
  4.         int &r1 = a;
  5.         const int &r2 = 3;

  6.         return 0;
  7. }
复制代码

  1. &qu
复制代码

一个&和qu组成的表达式的值是一个右值
要引用这个右值,需要const引用
下面代码可以通过编译
  1. #include <cstdio>
  2. #include <cstdlib>

  3. typedef struct Qnode
  4. {
  5.         int data;
  6.         Qnode *next;
  7. }Qnode;

  8. typedef struct Lq
  9. {
  10.         Qnode *front;
  11.         Qnode *rear;
  12. }Lq;

  13. void init(Lq *const &qu)
  14. {
  15.         /*qu = (Lq *)malloc(sizeof(Lq));
  16.         (*qu).front = (*qu).rear = NULL;
  17.         printf("初始化成功!\n");*/
  18. }

  19. int main()
  20. {
  21.         Lq qu;
  22.         init(&qu);

  23.         return 0;
  24. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-4 20:00:02 | 显示全部楼层
claws0n 发表于 2018-10-4 19:57
那样是可以编译通过,不过就废了

?

  1. #include <cstdio>
  2. #include <cstdlib>

  3. typedef struct Qnode
  4. {
  5.         int data;
  6.         Qnode *next;
  7. }Qnode;

  8. typedef struct Lq
  9. {
  10.         Qnode *front;
  11.         Qnode *rear;
  12. }Lq;

  13. void init(Lq *const &qu)
  14. {
  15.         qu->front = NULL;
  16.         qu->rear = NULL;

  17.         /*qu = (Lq *)malloc(sizeof(Lq));
  18.         (*qu).front = (*qu).rear = NULL;
  19.         printf("初始化成功!\n");*/
  20. }

  21. int main()
  22. {
  23.         Lq qu;
  24.         Lq *tmp = &qu;

  25.         printf("front:%.8X, rear:%.8X\n", tmp->front, tmp->rear);
  26.         init(&qu);
  27.         printf("front:%.8X, rear:%.8X\n", tmp->front, tmp->rear);
  28.         return 0;
  29. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-10-4 20:00:54 | 显示全部楼层
claws0n 发表于 2018-10-4 19:57
那样是可以编译通过,不过就废了

引用了一个指针
这个引用是const的,指针又不是
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-9-29 09:04

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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