Reputation: 235
This is only a part of the program but I don't understand these codes why did we declare int* array in structure what does it mean? Also we generally use int or void before function type why did we write struct Stack * before create function and also what is the use of unsigned here? Click the link to view the actual program. a link
struct Stack {
int top;
unsigned capacity;
int* array;
};
struct Stack* createStack(unsigned capacity) {
struct Stack* stack = (struct Stack*) malloc(sizeof(struct Stack));
stack->capacity = capacity;
stack->top = -1;
stack->array = (int*) malloc(stack->capacity * sizeof(int));
return stack;
}
int main() {
struct Stack* stack = createStack(100);
}
Upvotes: 0
Views: 508
Reputation: 123488
why did we declare int* array in structure what does it mean?
The array
member is used to store the contents of the stack. However, we don't know ahead of time how many elements the stack will need to hold, so we can't declare it as a regular array (whose size must be known at compile time1). Instead, we'll allocate the memory at runtime using the malloc
library function, which returns a pointer to the first element of the dynamically allocated block; this pointer will be stored to the array member.
why did we write struct Stack * before create function
Because the createStack
function is returning a pointer to a new struct Stack
instance:
struct Stack *createStack( ... ) ----------------+
{ | The type of the expression in the
struct Stack *stack = ...; -----+ | `return` statement must match the
... | | return type of the function
return stack; <-----------------+---------------+
}
what is the use of unsigned here
unsigned
is short for unsigned int
; it guarantees that only non-negative values can be used for the stack size.
Here's what memory looks like after the createStack
function has been called:
+---+
stack: | |----+ // The stack variable points to a struct Stack instance
+---+ |
... |
+---+ |
stack->top: | |<---+ // The actual struct Stack instance is created on the heap
+---+ // The -> operator allows us to refer to the members of the
stack->capacity: | | // instance through the stack pointer variable.
+---+
stack->array: | |----+ // The memory for the stack contents is allocated in a
+---+ | // separate malloc call, and the resulting pointer is
... | // stored in the instance's array member.
+---+ |
stack->array[0]: | |<---+
+---+
stack->array[1]: | |
+---+
stack->array[2]: | |
+---+
...
+---+
stack->array[N-1]: | | // N == stack->capacity
+---+
The stack
variable in main
points to an instance of struct Stack
; this instance is created by the line
struct Stack* stack = (struct Stack*) malloc(sizeof(struct Stack));
in the createStack
function. The memory for the stack instance is taken from the "heap" (a region of memory reserved for dynamic allocation). Within the stack instance, the array
member also points to a region of dynamic memory reserved by another call to malloc
:
stack->array = (int*) malloc(stack->capacity * sizeof(int));
This function sets aside enough memory to store as many int
objects as specified in the capacity
member.
Edit
Note that both malloc
calls can be cleaned up as follows:
struct Stack *stack = malloc( sizeof *stack );
...
stack->array = malloc( stack->capacity * sizeof *stack->array );
Unless you're using a C++ compiler or a C compiler that predates the 1989 standard, the cast is unnecessary (and on C89 implementations, dangerous).
The sizeof
expressions use the dereferenced target expression, rather than a type name; this cleans up a little of the visual clutter, and it reduces maintenance if you ever decide to change the type of the target variable (from int *
to double *
, for example). The type of the expression *stack
is struct Stack
, so it follows that sizeof *stack == sizeof (struct Stack)
. Similarly, the type of the expression *stack->array
is int
, so sizeof *stack->array == sizeof (int)
. Note that parentheses are only required if the operand of sizeof
is a type name.
Upvotes: 1
Reputation: 5291
1) int * is used because we dont know before hand how huge the array is going to be, so we declare it as a pointer and do malloc using the capacity of the stack.
If we had used an array, we had to perform additonal checks to see if our initial declared size was overflown and would be a huge overhead across the program.
2) The function create stack is returning the structure ponter of type stack, according to the syntax for functions.
Syntas:
<return type> function_name(<Parameters>){<Statements>}
3) We want the program to give us an error if some one tries to declare a negative capacity. Unsigned ensures that that is satisfied
Hope this helps.
Upvotes: 1