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(错误)。
- 只要队列包含一个以上的值:
一世。假设队列中实际包含n个值,那么它会弹出一个值,然后一次又一次地推回n-1次。
二.现在将弹出接下来的 2 个值。如果它们相等,过程将继续(不会将它们推回)。如果他们不这样做,它将结束并返回 0(假)。
- 如果上一节会结束,表示队列为空或只有一个值,则返回1(true,因为是回文)。
更新:
感谢 Christian Gibbons 和 Yunnosch,我用另一个队列解决了这个问题(我只能复制数组,但我希望整个解决方案都按队列)。
有没有办法不用额外的数据结构(队列、栈、数组等)就可以判断一个队列是否为回文?
如果你复制一个包含指针的结构,那么副本将包含相同的指针地址,都指向相同的内存。
如果您随后更改该内存,两个副本中的指针虽然本身未更改,但将指向同一内存,因为它们没有被更改,尽管如此。
所以副本和原件都仍然包含指向更改值的指针。
#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(错误)。
- 只要队列包含一个以上的值: 一世。假设队列中实际包含n个值,那么它会弹出一个值,然后一次又一次地推回n-1次。 二.现在将弹出接下来的 2 个值。如果它们相等,过程将继续(不会将它们推回)。如果他们不这样做,它将结束并返回 0(假)。
- 如果上一节会结束,表示队列为空或只有一个值,则返回1(true,因为是回文)。
更新:
感谢 Christian Gibbons 和 Yunnosch,我用另一个队列解决了这个问题(我只能复制数组,但我希望整个解决方案都按队列)。
有没有办法不用额外的数据结构(队列、栈、数组等)就可以判断一个队列是否为回文?
如果你复制一个包含指针的结构,那么副本将包含相同的指针地址,都指向相同的内存。
如果您随后更改该内存,两个副本中的指针虽然本身未更改,但将指向同一内存,因为它们没有被更改,尽管如此。
所以副本和原件都仍然包含指向更改值的指针。