C for 循环与 rolled out 循环有不同的效果
C for loop has different effect than rolled out loop
我正在使用跟踪最后一个元素的链表用 c 编写一个简单的队列。
这是我的代码:
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
typedef struct node_s {
uint32_t x, y;
} node;
// very cheap linked list queue that lives as long as its scope
typedef struct queue_s {
node* node;
struct queue_s* next;
} queue;
bool isEmpty(queue** queue)
{
return !*queue;
}
node* dequeue(queue** head, queue** tail)
{
if (isEmpty(head)) {
printf("attempting to dequeue from an empty queue\n");
return NULL;
}
node* ret = (**head).node;
*head = (*head)->next;
if (isEmpty(head)) *tail = NULL;
printf("next %p\n", (void*) *head);
// no need to free anything, the queue lives as long as its scope
return ret;
}
void enqueue(queue** head, queue** tail, queue* new)
{
if (isEmpty(head)) {
// has no head -> make new head
*head = new;
*tail = new;
printf("empty\n");
} else {
// has head -> make new tail // TODO does this work?
(*tail)->next = new;
*tail = (*tail)->next;
printf("not empty\n");
}
}
int main()
{
queue* head = NULL;
queue* tail = NULL;
enqueue(&head, &tail, &(queue) {.node=&(node) {1, 1}, NULL});
printf("h %i\n", head->node->x);
printf("t %i\n", tail->node->x);
enqueue(&head, &tail, &(queue) {.node=&(node) {2, 2}, NULL});
printf("h %i\n", head->node->x);
printf("t %i\n", tail->node->x);
enqueue(&head, &tail, &(queue) {.node=&(node) {3, 3}, NULL});
printf("h %i\n", head->node->x);
printf("t %i\n", tail->node->x);
// for (int i = 1; i <= 3; ++i) {
// enqueue(&head, &tail, &(queue) {.node=&(node) {i, i}, NULL});
// printf("h %i\n", head->node->x);
// printf("t %i\n", tail->node->x);
// }
return 0;
}
现在 main() 中推出的 for 循环表现正确,因为在新元素排队时头元素保持为 1:
empty
h 1
t 1
not empty
h 1
t 2
not empty
h 1
t 3
...但是 for 循环本身给出了错误的输出,因为头元素总是等于尾元素:
empty
h 1
t 1
not empty
h 2
t 2
not empty
h 3
t 3
我是一个 c 初学者,这让我发疯,有人可以帮助我吗?
此代码:
for (int i = 1; i <= 3; ++i) {
enqueue(&head, &tail, &(queue) {.node=&(node) {i, i}, NULL});
printf("h %i\n", head->node->x);
printf("t %i\n", tail->node->x);
}
相当于:
for (int i = 1; i <= 3; ++i)
queue next = {.node=&(node) {i, i}, NULL};
enqueue(&head, &tail, &next);
printf("h %i\n", head->node->x);
printf("t %i\n", tail->node->x);
} // End of scope
新元素 next
将在范围末尾不复存在(请参阅注释)。要使它在循环中工作,您需要做的是动态内存分配。
我正在使用跟踪最后一个元素的链表用 c 编写一个简单的队列。
这是我的代码:
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
typedef struct node_s {
uint32_t x, y;
} node;
// very cheap linked list queue that lives as long as its scope
typedef struct queue_s {
node* node;
struct queue_s* next;
} queue;
bool isEmpty(queue** queue)
{
return !*queue;
}
node* dequeue(queue** head, queue** tail)
{
if (isEmpty(head)) {
printf("attempting to dequeue from an empty queue\n");
return NULL;
}
node* ret = (**head).node;
*head = (*head)->next;
if (isEmpty(head)) *tail = NULL;
printf("next %p\n", (void*) *head);
// no need to free anything, the queue lives as long as its scope
return ret;
}
void enqueue(queue** head, queue** tail, queue* new)
{
if (isEmpty(head)) {
// has no head -> make new head
*head = new;
*tail = new;
printf("empty\n");
} else {
// has head -> make new tail // TODO does this work?
(*tail)->next = new;
*tail = (*tail)->next;
printf("not empty\n");
}
}
int main()
{
queue* head = NULL;
queue* tail = NULL;
enqueue(&head, &tail, &(queue) {.node=&(node) {1, 1}, NULL});
printf("h %i\n", head->node->x);
printf("t %i\n", tail->node->x);
enqueue(&head, &tail, &(queue) {.node=&(node) {2, 2}, NULL});
printf("h %i\n", head->node->x);
printf("t %i\n", tail->node->x);
enqueue(&head, &tail, &(queue) {.node=&(node) {3, 3}, NULL});
printf("h %i\n", head->node->x);
printf("t %i\n", tail->node->x);
// for (int i = 1; i <= 3; ++i) {
// enqueue(&head, &tail, &(queue) {.node=&(node) {i, i}, NULL});
// printf("h %i\n", head->node->x);
// printf("t %i\n", tail->node->x);
// }
return 0;
}
现在 main() 中推出的 for 循环表现正确,因为在新元素排队时头元素保持为 1:
empty
h 1
t 1
not empty
h 1
t 2
not empty
h 1
t 3
...但是 for 循环本身给出了错误的输出,因为头元素总是等于尾元素:
empty
h 1
t 1
not empty
h 2
t 2
not empty
h 3
t 3
我是一个 c 初学者,这让我发疯,有人可以帮助我吗?
此代码:
for (int i = 1; i <= 3; ++i) {
enqueue(&head, &tail, &(queue) {.node=&(node) {i, i}, NULL});
printf("h %i\n", head->node->x);
printf("t %i\n", tail->node->x);
}
相当于:
for (int i = 1; i <= 3; ++i)
queue next = {.node=&(node) {i, i}, NULL};
enqueue(&head, &tail, &next);
printf("h %i\n", head->node->x);
printf("t %i\n", tail->node->x);
} // End of scope
新元素 next
将在范围末尾不复存在(请参阅注释)。要使它在循环中工作,您需要做的是动态内存分配。