![]() |
| | #1 |
| Registered User Join Date: Jan 2005
Posts: 42
| Finished Stack stack.h Code: #ifndef _STACK_H_
#define _STACK_H_
#include <stddef.h> /* size_t */
typedef
struct stack
stack_t;
struct stack {
void **stack;
size_t top;
size_t capacity;
unsigned int err;
};
enum {
STACK_ERR_OK,
STACK_ERR_MEMORY
};
stack_t * stack_create(void);
void stack_destroy(stack_t *stack);
void stack_push(stack_t *stack, void *item);
void * stack_pop(stack_t *stack);
void * stack_peek(stack_t *stack);
int stack_isempty(stack_t *stack);
/*******************************************************************************
*
* stack_create
* Dynamically allocates and initializes a new stack. Returns a valid pointer
* if successful, NULL otherwise.
*
* stack_destroy
* Frees all memory dynamically allocated by the associated stack functions.
* It will *not* free items that have been pushed on the stack. If you
* dynamically allocated these items yourself then you must free them
* yourself.
*
* stack_push
* Pushes the given item onto the stack. The stack will increase in size if
* necessary. If memory could not be allocated to accomodate the stack's new
* size, the stack will retain its state prior to the function call and the
* member 'err' is set to STACK_ERR_MEMORY. The member 'err' is otherwise
* guarenteed to hold the value STACK_ERR_OK.
*
* stack_pop
* Removes and returns the last item pushed onto the stack. If the stack is
* empty the behavior is undefined.
*
* stack_peek
* Returns the last item pushed onto the stack. If the stack is empty the
* behavior is undefined.
*
* stack_isempty
* Returns a value that evaluates to true if the stack is empty, false
* otherwise.
*
******************************************************************************/
#endif
Code: #ifndef _STACK_C_
#define _STACK_C_
#include <stddef.h> /* NULL size_t */
#include <stdlib.h> /* malloc realloc free */
#include "stack.h"
#define STACK_INITIAL_CAPACITY (8 * sizeof(int))
#define STACK_CAPACITY_INCREMENT (8 * sizeof(int))
stack_t *
stack_create(void)
{
stack_t *stack;
stack = malloc(sizeof(stack_t));
if (stack == NULL)
return NULL;
stack->stack = malloc(STACK_INITIAL_CAPACITY * sizeof(void *));
if (stack->stack == NULL) {
free(stack);
return NULL;
}
stack->top = (size_t)-1;
stack->capacity = STACK_INITIAL_CAPACITY;
stack->err = STACK_ERR_OK;
return stack;
}
void
stack_destroy(stack_t *stack)
{
free(stack->stack);
free(stack);
}
void
stack_push(stack_t *stack, void *item)
{
stack->err = STACK_ERR_OK;
stack->top++;
if (stack->top == stack->capacity)
{
void *bigger_stack;
stack->capacity += STACK_CAPACITY_INCREMENT;
bigger_stack = realloc(stack->stack, stack->capacity * sizeof(void *));
if (bigger_stack == NULL) {
stack->err = STACK_ERR_MEMORY;
stack->top--;
stack->capacity -= STACK_CAPACITY_INCREMENT;
return;
}
stack->stack = bigger_stack;
}
stack->stack[stack->top] = item;
}
void *
stack_pop(stack_t *stack)
{
stack->top--;
if (stack->capacity - stack->top - 1 >= 1.5 * STACK_CAPACITY_INCREMENT)
{
void *smaller_stack;
stack->capacity -= STACK_CAPACITY_INCREMENT;
smaller_stack = realloc(stack->stack, stack->capacity * sizeof(void *));
if (smaller_stack == NULL)
stack->capacity += STACK_CAPACITY_INCREMENT;
else
stack->stack = smaller_stack;
}
return stack->stack[1 + stack->top];
}
void *
stack_peek(stack_t *stack)
{
return stack->stack[stack->top];
}
int
stack_isempty(stack_t *stack)
{
return stack->top == (size_t)-1;
}
#endif
Last edited by the pooper; 01-31-2005 at 10:38 AM. |
| the pooper is offline | |
| | #2 |
| Gawking at stupidity Join Date: Jul 2004
Posts: 2,324
| It looks pretty good to me. I would add some error checking to stack_pop(). If stack_top == (size_t)-1 then you're going to run into problems. You might want to add a STACK_ERR_EMPTY or some such error if someone pops from an empty stack. You could make stack_peek() use the same error. Also, I don't think you need the _STACK_C_ wrapper ifdef unless you plan on #include'ing the .c file for some strange reason.
__________________ If you understand what you're doing, you're not learning anything. Ignore any "advice" esbo tries to give you. It's wrong. |
| itsme86 is offline | |
| | #3 |
| Registered User Join Date: Jan 2005
Posts: 89
| Code: #ifndef _STACK_H_ #define _STACK_H_
__________________ Kampai! |
| Sake is offline | |
| | #4 |
| +++ OK NO CARRIER Join Date: Oct 2001
Posts: 10,619
| No, I don't believe it actually does. It's a #define, not a variable. These are preprocessor directives. I don't believe they're considered in the same catergory as standard naming conventions, simply because the preprocessor handles the macro in its entirety first. For example, you can make macros which have the name of reserved keywords, and the compiler won't complain, because the preprocessor takes care of them all before the compiler ever sees them. Quzah.
__________________ Hundreds of thousands of dipshits can't be wrong. Are you up for the suck? |
| quzah is offline | |
| | #5 | |||
| Registered User Join Date: Jan 2005
Posts: 42
| Quote:
Quote:
So while I did choose to check for and report errors that the user would have no control over (e.g., memory allocation), I chose not to bloat the code for detecting mistakes that are the fault of the user. Quote:
| |||
| the pooper is offline | |
| | #6 |
| +++ OK NO CARRIER Join Date: Oct 2001
Posts: 10,619
| It's usually never a good idea to leave error checking up to the user. The reason being, most users are idiots. My includes usually take on something like this: Code: #ifndef FOO_H_ #define FOO_H_ #endif Quzah.
__________________ Hundreds of thousands of dipshits can't be wrong. Are you up for the suck? |
| quzah is offline | |
| | #7 |
| Registered User Join Date: Jan 2005
Posts: 89
| >>No, I don't believe it actually does. It's a #define, not a variable. It doesn't have to be a variable, just an identifier. The standard describes an identifier to be "a sequence of nondigit characters (including the underscore _, the lowercase and uppercase Latin letters, and other characters) and digits, which designates one or more entities as described in 6.2.1." The referenced section says that an identifier can denote "an object; a function; a tag or a member of a structure, union, or enumeration; a typedef name; a label name; a macro name; or a macro parameter." The section that gives the rule that's broken says "All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use." I could be wrong, but if you flip around to the right places, it's pretty clear that the inclusion guards posted are using reserved identifiers.
__________________ Kampai! |
| Sake is offline | |
| | #8 |
| +++ OK NO CARRIER Join Date: Oct 2001
Posts: 10,619
| Thanks. I couldn't locate it. I was trying to find it in "C: A Reference Manual, 5th Edition", but the only thing with namespaces refers to C++, and the only thing with the _ covered is just that you can include it in names. Quzah.
__________________ Hundreds of thousands of dipshits can't be wrong. Are you up for the suck? |
| quzah is offline | |
| | #9 |
| Registered User Join Date: Jan 2005
Posts: 89
| >>I was trying to find it in "C: A Reference Manual, 5th Edition" Try page 313, secton 10.1.1. It covers what you want in the third paragraph saying "for macros, keywords, or global variables, identifiers beginning with _ and either a second _ or an uppercase letter". But from what I can tell, that book is short on a good description of exactly what constitutes an identifier. That's why I've learned to back up my claims with the standard itself. The people I work with are hardcore when it comes to this stuff.
__________________ Kampai! |
| Sake is offline | |
| | #10 |
| +++ OK NO CARRIER Join Date: Oct 2001
Posts: 10,619
| Well I don't know why the hell it's not in the index. :P Quzah.
__________________ Hundreds of thousands of dipshits can't be wrong. Are you up for the suck? |
| quzah is offline | |
| | #11 | |||
| Registered User Join Date: Jan 2005
Posts: 42
| Quote:
Quote:
So I just want to confirm now that everyone agrees that defines with a leading underscore is bad practice? And that's because this naming convention is reserved for the standard library, correct? Quote:
| |||
| the pooper is offline | |
| | #12 |
| Code Goddess Join Date: Sep 2001
Posts: 9,664
| >So I just want to confirm now that everyone agrees that defines with a leading underscore is bad practice? I don't know about everyone, but most of the people you want to listen to agree. ![]() >And that's because this naming convention is reserved for the standard library, correct? Correct.
__________________ My best code is written with the delete key. |
| Prelude is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| stack and pointer problem | ramaadhitia | C Programming | 2 | 09-11-2006 11:41 PM |
| Question about a stack using array of pointers | Ricochet | C++ Programming | 6 | 11-17-2003 10:12 PM |
| error trying to compile stack program | KristTlove | C++ Programming | 2 | 11-03-2003 06:27 PM |
| What am I doing wrong, stack? | TeenyTig | C Programming | 2 | 05-27-2002 02:12 PM |
| Stack Program Here | Troll_King | C Programming | 7 | 10-15-2001 05:36 PM |