今天用学习用 C 实现队列结构时,编译执行阶段出现非常邪乎的问题

2021-07-30 19:02:32 +08:00
 JQiue

这是我的环境:

  1. Windows 10
  2. VS Code
  3. MinGW

下面是我的实现代码:

#include "stdio.h"
#include "stdlib.h"

#define OK 1
#define ERROR 0
#define CAPACITY 10

typedef int Status;
typedef int ElementType;

Status initQueue();
Status isEmpty();
Status isFull();
Status enQueue();
Status deQueue();

typedef struct
{
  ElementType *array;
  int front, rear;
  int capacity;
  int size;
} *Queue;

int main(void)
{
  Queue q = NULL;
  initQueue(&q);
  enQueue(q, 1);
  enQueue(q, 2);
  enQueue(q, 3);
  int foo;
  deQueue(q, &foo);
  deQueue(q, &foo);
  deQueue(q, &foo);
  printf("%d", foo);
  return 0;
}

Status initQueue(Queue *q)
{
  (*q) = (Queue)malloc(sizeof(Queue));
  (*q)->capacity = CAPACITY;
  printf("capacity = %d\n", (*q)->capacity);
  (*q)->array = (ElementType *)malloc((*q)->capacity * sizeof(ElementType));
  (*q)->front = (*q)->size = 0;
  (*q)->rear = (*q)->capacity - 1;
  printf("queue = %p, capacity = %d, size = %d, front = %d, rear = %d, array = %p\n", (*q), (*q)->capacity, (*q)->size, (*q)->front, (*q)->rear, (*q)->array);
  return OK;
}

Status isEmpty(Queue q)
{
  if (q->size == 0)
  {
    printf("Queqe is empty\n");
    return OK;
  }
  return ERROR;
}

Status isFull(Queue q)
{
  if (q->size == q->capacity)
  {
    printf("Queqe is full\n");
    return OK;
  }
  return ERROR;
}

Status enQueue(Queue q, ElementType e)
{
  if (isFull(q))
  {
    return ERROR;
  }
  q->rear = (q->rear + 1) % q->capacity;
  q->array[q->rear] = e;
  q->size++;
  printf("%d enqueued to queue\n", e);
  return OK;
}

Status deQueue(Queue q, ElementType *e)
{
  if (isEmpty(q))
  {
    return ERROR;
  }
  *e = q->array[q->front];
  q->front = (q->front + 1) % q->capacity;
  q->size--;
  printf("%d dequeued from queue\n", *e);
  return OK;
}

这个有意思的问题就是在终端中执行结果不太一致

比如我在 VS code 中的集成终端中( CMD )使用 GCC 编译并执行会是这样的结果:

gcc SequenceQueue.c -o SequenceQueue && SequenceQueue.exe

capacity = 10
queue = 006B1810, capacity = 10, size = 0, front = 0, rear = 9, array = 006B1850
1 enqueued to queue
2 enqueued to queue
3 enqueued to queue
1 dequeued from queue
2 dequeued from queue
3 dequeued from queue
3

如果将集成终端换成 PowerShell,却是这样的结果:

gcc SequenceQueue.c -o SequenceQueue; .\SequenceQueue

capacity = 10
queue = 00A015F0, capacity = 268435466, size = 0, front = 0, rear = 268435465, array = 00A01600
1 enqueued to queue
2 enqueued to queue
3 enqueued to queue
4 dequeued from queue
2 dequeued from queue
3 dequeued from queue
3

这 tm 太奇怪了,capacity 咋就变了,rear 是 capacity - 1 才是这样的结果,而且第一个出栈不是 1 而是 4,很明显 CMD 执行的是正确的结果,也不知道 PowerShell 发生了什么。为了排除 VS Code 的原因,直接单独打开 CMD 和 PowerShell 测试

CMD:

gcc SequenceQueue.c -o SequenceQueue && SequenceQueue

capacity = 10
queue = 007915B8, capacity = 10, size = 0, front = 0, rear = 9, array = 007915F0
1 enqueued to queue
2 enqueued to queue
3 enqueued to queue
1 dequeued from queue
2 dequeued from queue
3 dequeued from queue
3

PowerShell:

gcc SequenceQueue.c -o SequenceQueue; .\SequenceQueue

capacity = 10
queue = 001F2AD0, capacity = 134217738, size = 0, front = 0, rear = 134217737, array = 001F2AE0
1 enqueued to queue
2 enqueued to queue
3 enqueued to queue
4 dequeued from queue
2 dequeued from queue
3 dequeued from queue
3

这看起来和 VS Code 本身没啥关系,似乎 PowerShell 有点问题?把编译和运行命令分开执行试一下

gcc .\SequenceQueue.c -o .\SequenceQueue

.\SequenceQueue

capacity = 10
queue = 00E62AD0, capacity = 134217738, size = 0, front = 0, rear = 134217737, array = 00E62AE0
1 enqueued to queue
2 enqueued to queue
3 enqueued to queue
4 dequeued from queue
2 dequeued from queue
3 dequeued from queue
3

好吧,看起来还是不行,capacity 的值乱七八糟,第一个出栈的还是 4 而不是 1 。但是,如果不指定生成后的文件名,PowerShell 它似乎又正确了

(默认生成的 exe 程序名为 a)

gcc .\SequenceQueue.c

.\a.exe

capacity = 10
queue = 00B22E40, capacity = 134217738, size = 0, front = 0, rear = 134217737, array = 02144020
1 enqueued to queue
2 enqueued to queue
3 enqueued to queue
1 dequeued from queue
2 dequeued from queue
3 dequeued from queue
3

但是 capacity 又是乱七八糟的值,那么可能是 GCC 编译的时候出现了问题?于是在 CMD 中使用 GCC 编译并执行程序,然后在 PowerShell 中执行程序

这是 CMD 中的执行结果:

gcc SequenceQueue.c -o SequenceQueue
SequenceQueue.exe

capacity = 10
queue = 00BB15B8, capacity = 10, size = 0, front = 0, rear = 9, array = 00BB15F8
1 enqueued to queue
2 enqueued to queue
3 enqueued to queue
1 dequeued from queue
2 dequeued from queue
3 dequeued from queue
3

这是 PowerShell 中的执行结果:

.\SequenceQueue.exe

capacity = 10
queue = 001E2AD0, capacity = 134217738, size = 0, front = 0, rear = 134217737, array = 001E2AE0
1 enqueued to queue
2 enqueued to queue
3 enqueued to queue
4 dequeued from queue
2 dequeued from queue
3 dequeued from queue
3

不是吧,PowerShell 咋回事?那么在 PowerShell 中编译并执行,然后在 CMD 中执行

这是 PowerShell 的:

gcc .\SequenceQueue.c
.\SequenceQueue.exe

capacity = 10
queue = 00AB2AD0, capacity = 134217738, size = 0, front = 0, rear = 134217737, array = 00AB2AE0
1 enqueued to queue
2 enqueued to queue
3 enqueued to queue
4 dequeued from queue
2 dequeued from queue
3 dequeued from queue
3

这是 CMD 的:

gcc SequenceQueue.c -o SequenceQueue
SequenceQueue.exe

capacity = 10
queue = 00B515B8, capacity = 10, size = 0, front = 0, rear = 9, array = 00B515F8
1 enqueued to queue
2 enqueued to queue
3 enqueued to queue
1 dequeued from queue
2 dequeued from queue
3 dequeued from queue
3

妈妈,我想放弃学习了,这都啥跟啥啊,真想一脚踩烂 PowerShell 。好吧,也许不是 GCC 的锅,目前为止我也不知道代码实现是否有哪个地方的问题导致这样的结果,所以希望各位大佬能否复刻一下这种情况,产生这个问题的原因是,我使用 VScode 某个插件一键调用 GCC 编译且执行,总是得到 PowerShell 的结果,然后调试了半天发现不知道问题在哪,于是将代码换到了一些在线运行 C 的网站,发现我的代码似乎没什么太大问题,于是才有了这样的疑问

2750 次点击
所在节点    C
21 条回复
araraloren
2021-08-02 12:21:03 +08:00
改用 rust 就不会有这么多毛病了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/792765

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX