Biblioteca estática para manipulação de pilhas
Publicado por Vinícius dos Santos Oliveira (última atualização em 17/11/2009)
[ Hits: 8.661 ]
Homepage: https://vinipsmaker.github.io/
Precisei fazer uma biblioteca de manipulação de pilhas em C, então estou compartilhando (GPL) ela. Ela manipula pilhas (aqui chega a 32768) de todos os tipos (é só modificar um typedef). Ela usa comentários estilo doxygen.
Stack_id minha_pilha = stack_new();
a = stack_pop(minha_pilha);
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include "vinipsmaker_stacks.h"
/**
*@file pilhas.c
*@brief A static library to manipulate stacks
*
*@details It can manipulate up to SHRT_MAX + 1 stacks.
*\n
*@code
* #include <stdio.h>
* #include <limits.h>
*
* int main(){
* printf("You can use up to %u stacks\n",SHRT_MAX + 1);
* }
* @endcode
* Each stack can store up to UINT_MAX plates.
*@code
* #include <stdio.h>
* #include <limits.h>
*
* int main(){
* printf("Each stack that you use can store up to %u plates\n",UINT_MAX);
* @endcode
* Some examples\n
* 32-bit \> 32,768 stacks with 4,294,967,295 plates
*
*@author 2009 Vinícius dos Santos Oliveira
*
*@todo Encontrar se o número de pilhas esgotou
* antes de tentar criar uma nova pilha.
*
*/
static unsigned short int number_of_stacks = 0;
static struct {
Plate_t * stack;
Stack_size_t size;
Stack_id id;
} * stacks = NULL,aux,* err;
/**
*@addtogroup pilhas
*@{
*/
inline Stack_id stack_get_index(Stack_id id){
register int i;
if(id<0)
return -1;
for(i=0;i<number_of_stacks;++i){
if(id == stacks[i].id){
return i;
}
}
return -1;
}
/**
*@fn unsigned short int stacks_see_number
*@code
* printf("There are %hu stacks now\n",stacks_see_number());
* @endcode
*
*@return It returns the number os stacks in the memory.
*
*/
unsigned short int stacks_see_number( void ){
/**
*@{
*/
return number_of_stacks;
/**
*@}
*/
}
/**
*@fn Stack_id stack_new
*@brief It create a stack
*
*@details Example of use
*@code
* Stack_id my_stack = stack_new();
* if(my_stack < 0){
* fprintf(stderr,"Failure on stack creating\n");
* }
* @endcode
*
*@return It returns -1 if no stack was created
* or the stack id if a stack was created.
*
*@see Stack_id
*
*/
Stack_id stack_new( void ){
/**
*@{
*/
err = stacks;
stacks = realloc(stacks,sizeof(aux)*(++number_of_stacks));
if(stacks == NULL){
stacks = err;
--number_of_stacks;
return -1;
}
stacks[number_of_stacks-1].stack = NULL;
stacks[number_of_stacks-1].size = 0;
stacks[number_of_stacks-1].id = -1;
{
register int i,j,num=0;
register Bool_t nfound = TRUE;
for(i=0;nfound;num=0){
for(j=0;j<number_of_stacks;++j){
if(i == stacks[j].id){
++i;
}else{
++num;
}
}
if(num == number_of_stacks)
nfound = FALSE;
}
stacks[number_of_stacks-1].id = i;
}
return stacks[number_of_stacks-1].id;
/**
*@}
*/
}
/**
*@fn Bool_t stack_exist
*
*@details Example of use
*@code
* if(!stack_exist(my_stack)){
* my_stack = -1;
* printf("Stack already was destroyed\n");
* }else{
* printf("Stack still exist\n");
* }
* @endcode
*
*@return It returns TRUE if the stack exist
* and FALSE if the stack don't exist.
*
*/
Bool_t stack_exist(Stack_id stack){
/**
*@{
*/
Stack_id index = stack_get_index(stack);
if(index == -1)
return FALSE;
else
return TRUE;
/**
*@}
*/
}
/**
*@fn Bool_t stack_is_empty
*
*@details Example of use
*@code
* if(stack_is_empty(my_stack)){
* printf("Stack is empty or not exist\n");
* }
* @endcode
*
*@warning You don't must use this function
* with invalid stack indexs to discovery
* if the stack exist. You must use stack_exist
* instead or you'll get a warning on stderr.
*
*/
Bool_t stack_is_empty(Stack_id stack){
/**
*@{
*/
Stack_id index = stack_get_index(stack);
if(index == -1){
fprintf(stderr,"\nStack not exist: %hi\n",stack);
return TRUE;
}
if(stacks[index].size){
return FALSE;
}else{
return TRUE;
}
/**
*@}
*/
}
/**
*@fn SStack_size_t stack_size
*@return It returns the stack size or
* -1 if the stack don't exist.
*
*@see SStack_size_t
*
*/
SStack_size_t stack_size(Stack_id stack){
/**
*@{
*/
Stack_id index = stack_get_index(stack);
if(index == -1){
return -1;
}
return stacks[index].size;
/**
*@}
*/
}
/**
*@fn Bool_t stack_push
*@brief Add a element to stack.
*
*@details You can use this function to
* put a \p plate on the \p stack. \n
* Example
*\n
*@code
* Plate_t my_plate;
* if(stack_push(my_stack,my_plate)){
* printf("A new plate was added to the stack\n");
* }
* @endcode
*
*@return It returns TRUE on success and
* FALSE on failure.
*
*/
Bool_t stack_push(Stack_id stack,Plate_t plate){
/**
*@{
*/
Stack_id index = stack_get_index(stack);
if(index == -1){
fprintf(stderr,"\nStack not exist: %hi\n",stack);
return FALSE;
}
aux = stacks[index];
stacks[index].stack = realloc(stacks[index].stack,sizeof(Plate_t)*(stacks[index].size+1));
if(stacks[index].stack == NULL){
stacks[index] = aux;
fprintf(stderr,"\nFailure on realloc\n");
return FALSE;
}
(stacks[index].stack)[(stacks[index].size)++] = plate;
return TRUE;
/**
*@}
*/
}
/**
*@fn Plate_t stack_pop
*@brief Remove one plate from the \p stack
*
*@details Example
*@code
* Plate_t new_plate = stack_pop(my_stack);
* @endcode
*
*@return It returns the plate or garbage
* when the memory is empty or the stack
* don't exist.
*
*/
Plate_t stack_pop(Stack_id stack){
/**
*@{
*/
Stack_id index = stack_get_index(stack);
if(index == -1){
fprintf(stderr,"\nStack not exist: %hi\n",stack);
return;
}
if(stack_is_empty(stack)){
fprintf(stderr,"\nStack %hi is empty!\n",stack);
return;
}
Plate_t plate = (stacks[index].stack)[stacks[index].size-1];
aux = stacks[index];
stacks[index].stack = realloc(stacks[index].stack,sizeof(Plate_t)*(--(stacks[index].size)));
if((stacks[index].stack == NULL)&&(stacks[index].size != 0)){
stacks[index] = aux;
fprintf(stderr,"\nFailure on realloc\n");
++(stacks[index].size);
}
return plate;
/**
*@}
*/
}
/**
*@fn Plate_t stack_see_top
*@brief Returns one plate of the stack
* without removing it.
*
*@details Example
*@code
* Plate_t new_plate = stack_see_top(my_stack);
* @endcode
*
*@return It returns the plate or garbage
* when the memory is empty or the stack
* don't exist.
*
*@see stack_pop
*
*/
Plate_t stack_see_top(Stack_id stack){
/**
*@{
*/
Stack_id index = stack_get_index(stack);
if(index == -1){
fprintf(stderr,"\nStack not exist: %hi\n",stack);
return;
}
if(stack_is_empty(stack)){
fprintf(stderr,"\nStack %hi is empty!\n",stack);
return;
}
return (stacks[index].stack)[stacks[index].size-1];
/**
*@}
*/
}
/**
*@fn Bool_t stack_free
*@brief Destroy \p stack
*
*@return Returns TRUE on succes and
* FALSE on FAILURE
*
*@see stacks_free
*
*/
Bool_t stack_free(Stack_id stack){
/**
*@{
*/
Stack_id index = stack_get_index(stack);
if(index == -1){
fprintf(stderr,"\nStack not exist: %hi\n",stack);
return FALSE;
}
if(number_of_stacks == 1){
free(stacks[0].stack);
free(stacks);
stacks = NULL;
number_of_stacks = 0;
return TRUE;
}
aux = stacks[number_of_stacks-1];
err = stacks;
stacks = realloc(stacks,sizeof(aux)*(--number_of_stacks));
if(stacks == NULL){
stacks = err;
++number_of_stacks;
fprintf(stderr,"\nFailure on realloc\n");
return FALSE;
}
if(index == number_of_stacks-1){
free(aux.stack);
return TRUE;
}else{
free(stacks[index].stack);
stacks[index] = aux;
return TRUE;
}
/**
*@}
*/
}
/**
*@fn Bool_t stacks_free
*@brief Destroy all stacks
*
*@return It returns TRUE on success
* and FALSE on failure.
*
*@see stack_free
*
*/
Bool_t stacks_free( void ){
/**
*@{
*/
if(number_of_stacks==0){
return TRUE;
}
{
register unsigned short int i;
for(i=0;i<number_of_stacks;++i){
free(stacks[i].stack);
}
}
free(stacks);
stacks = NULL;
number_of_stacks = 0;
return TRUE;
/**
*@}
*/
}
/**
*@}
*/
Ponteiro para Ponteiro para Ponteiro
Sudokou em C feito com matrizes e listas
Busca, inserção e remoção de elementos numa lista
Nenhum comentário foi encontrado.
Como extrair chaves TOTP 2FA a partir de QRCODE (Google Authenticator)
Linux em 2025: Segurança prática para o usuário
Desktop Linux em alta: novos apps, distros e privacidade marcam o sábado
IA chega ao desktop e impulsiona produtividade no mundo Linux
Novos apps de produtividade, avanços em IA e distros em ebulição agitam o universo Linux
Como instalar o repositório do DBeaver no Ubuntu
Como instalar o Plex Media Server no Ubuntu
Digitando underscore com "shift" + "barra de espaços"
Como ativar a lixeira e recuperar aquivos deletados em um servidor Linux
Como mudar o nome de dispositivos Bluetooth via linha de comando
É normal não gostar de KDE? (9)
Linux é a solução para o fim do Windows10? (2)
Problemas com Driver NVIDIA (4)









