C 函数,它接收一个结构,并导致它在函数外部发生变化,即使该结构没有作为指针发送

C function, that receives a struct, and causes it to change outside of the function, even though the struct not sent as a pointer

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

typedef struct queue
{
    int *arr, // array to store values
    size, // queue size (array size)
    put, // index location which the next value will be pushed in
    take, // index location which the next value will be popped out
    countVals; // Counts the number of values that the queue contains
} queue;

// queue nitialization
void newQueue (queue *q, int size)
{
    if (size < 0)
        q->arr = NULL;
    else
    {
        q->arr = (int*) malloc (sizeof (int) * size);
        q->size = size;
        q->put = q->take = q->countVals = 0;
    }
}

// free array allocated to queue
void freeQueue (queue *q)
{
    free (q->arr);
}

// is the queue full?
int isFullQueue (queue q)
{
    return q.countVals == q.size;
}

// is the queue empty?
int isEmptyQueue (queue q)
{
    return q.countVals == 0;
}

// how many values queue contains?
int countQueueVals (queue q)
{
    return q.countVals;
}

// push value to queue
void pushQueue (queue *q, int val)
{
    if (q->arr && !isFullQueue (*q))
    {
        q->arr[q->put] = val;
        q->put = (q->put + 1) % q->size;
        q->countVals++;
    }
}

// pop out value from queue
void popQueue (queue *q)
{
    if (q->arr && !isEmptyQueue (*q))
    {
        q->take = (q->take + 1) % q->size;
        q->countVals--;
    }
}

// What is the value at top of queue
int topQueue (queue q)
{
    if (q.arr && !isEmptyQueue (q))
        return q.arr[q.take];
    return -1;
}

// show all queue values
void showQueue (queue q)
{
    if (q.arr)
        while (!isEmptyQueue(q))
        {
            printf ("%d ", topQueue(q));
            popQueue (&q);
        }
        //  printf ("\n");
}

// are values of queue arranged in palindrome?
int isQueuePalindrome (queue q)
{
    int i, num1, num2;
    queue tmpQ;

    if (!q.arr)
        return -1;

    newQueue (&tmpQ, q.countVals);
    while (!isEmptyQueue(q))
    {
        pushQueue (&tmpQ, topQueue(q));
        popQueue (&q);
    }

    while (tmpQ.countVals > 1)
    {
        for (i = 0; i < tmpQ.countVals - 1; i++)
        {
            num1 = topQueue (tmpQ);
            popQueue (&tmpQ);
            pushQueue (&tmpQ, num1);
        }

        num1 = topQueue (tmpQ);
        popQueue (&tmpQ);

        num2 = topQueue (tmpQ);
        popQueue (&tmpQ);

        if (num1 != num2)
        {
            freeQueue (&tmpQ);
            return 0;
        }
    }
    freeQueue (&tmpQ);
    return 1;
}

void main ()
{
    queue q;
    newQueue (&q, -1);
    showQueue (q);
    printf ("%d\n", isQueuePalindrome(q)); // -1
    newQueue (&q, 5);
    showQueue (q);
    printf ("-> %d\n", isQueuePalindrome (q)); // 1
    pushQueue (&q, 10);
    showQueue (q);
    printf ("-> %d\n", isQueuePalindrome (q)); // 1
    pushQueue (&q, 10);
    showQueue (q);
    printf ("-> %d\n", isQueuePalindrome (q)); // 1
    popQueue (&q);
    pushQueue (&q, 20);
    showQueue (q);
    printf ("-> %d\n", isQueuePalindrome (q)); // 0
    pushQueue (&q, 30);
    showQueue (q);
    printf ("-> %d\n", isQueuePalindrome (q)); // 0
    pushQueue (&q, 20);
    showQueue (q);
    printf ("-> %d\n", isQueuePalindrome (q)); // 0
    pushQueue (&q, 10);
    showQueue (q);
    printf ("-> %d\n", isQueuePalindrome (q)); // 1
}

我尝试用函数检查,队列的值是否按回文排列。

我不明白为什么当我调用函数时,函数会更改它的值,即使我没有将队列作为指针发送。另外,我不明白为什么它只在队列已满时发生。

该函数根据以下算法检查队列:

  1. 如果队列未正确分配,将返回 -1(错误)。
  2. 只要队列包含一个以上的值: 一世。假设队列中实际包含n个值,那么它会弹出一个值,然后一次又一次地推回n-1次。 二.现在将弹出接下来的 2 个值。如果它们相等,过程将继续(不会将它们推回)。如果他们不这样做,它将结束并返回 0(假)。
  3. 如果上一节会结束,表示队列为空或只有一个值,则返回1(true,因为是回文)。

更新:

感谢 Christian Gibbons 和 Yunnosch,我用另一个队列解决了这个问题(我只能复制数组,但我希望整个解决方案都按队列)。

有没有办法不用额外的数据结构(队列、栈、数组等)就可以判断一个队列是否为回文?

如果你复制一个包含指针的结构,那么副本将包含相同的指针地址,都指向相同的内存。
如果您随后更改该内存,两个副本中的指针虽然本身未更改,但将指向同一内存,因为它们没有被更改,尽管如此。
所以副本和原件都仍然包含指向更改值的指针。