Question: I'm studying Data Structures, and I'm not getting why stacks and queues need to be declared like:

```
struct stack *Stack;

```

(forget about the `struct` syntax)

I mean, why it is always declared as a pointer?

Answer: 
It depends on how your stack structure is defined (not just the layout of the `struct`, but the operations that manipulate it as well). 

It's entirely possible to define a stack as a simple array and index, such as

```
struct stack_ {
  T data[N]; // for some type T and size N
  size_t stackptr; // Nobody caught that error, so it never existed, right? ;-)
} stack;

stack.stackptr = N; // stack grows towards 0

// push operation
if (stack.stackptr)
  stack.data[--stack.stackptr] = some_data();
else
  // overflow

// pop operation
if (stack.stackptr < N)
  x = stack.data[stack.stackptr++];
else
  // underflow

```

However, fixed-sized arrays are limiting. One easy method of implementing a stack is to use a list structure:

```
struct stack_elem {
  T data;
  struct stack_elem *next;
};

```

The idea is that the head of the list is the top of the stack. Pushing an item onto the stack adds an element at the head of the list; popping an item removes that element from the head of the list:

```
int push(struct stack_elem **stack, T data)
{
  struct stack_elem *s = malloc(sizeof *s);
  if (s)
  {
    s->data = data;   // new element gets data
    s->next = *stack; // set new element to point to current stack head
    *stack = s;       // new element becomes new stack head
  }
  return s != NULL;
}

int pop(struct stack_elem **stack, T *data)
{
  int stackempty = (*stack == NULL);

  if (!stackempty)
  {
    struct stack_elem *s = *stack; // retrieve the current stack head
    *stack = (*stack)->next;       // set stack head to point to next element
    *data = s->data;               // get the data
    free(s);                       // deallocate the element
  }

  return r;
}

int main(void)
{
  struct stack_elem *mystack = NULL; // stack is initially empty
  T value;
  ...
  if (!push(&mystack, some_data()))
    // handle overflow
  ...
  if (!pop(&mystack, &value))
    // handle underflow
  ...
}  

```

Since `push` and `pop` need to be able to write new pointer values to `mystack`, we need to pass a pointer to it, hence the double indirection for `stack` in `push` and `pop`.
No, they don't have to be declared as pointers.

One can as well allocate stacks and queues as global variables:

```
struct myHash { int key; int next_idx; int data[4]; } mainTable[65536];
struct myHash duplicates[65536*10];
int stack[16384];

```

myHash also includes a linked list for duplicate entries using indices.

But as stated in the comments, if one has to add more elements to the structures, that was initially planned, then pointers come handy.

An additional reason to declare structures as pointers is that it typically with pointers one can access both the complete structure as a whole, any individual element of the structure or some subset of the elements. That makes the syntax more versatile. Also when the structure is passed as a parameter to some external function, a pointer is inevitable.