Mostrando postagens com marcador c++. Mostrar todas as postagens
Mostrando postagens com marcador c++. Mostrar todas as postagens

sexta-feira, 15 de outubro de 2010

Ponteiros em C

Olá, faz algum tempo que eu não posto nada relacionado a programação, estou muito ocupado ultimamente, trabalhando e estudando, fora os projetos pessoais que invadem a madrugada e finais de semana. Mas hoje, felizmente, tive um tempo para solucionar uma dúvida que pintou aqui na sala.

Os temidos PONTEIROS em C, por ter uma certa experiência em programação, foi fácil assimilar o conceito de endereço de memórias e afins, mas ainda tenho muito o que aprender sobre eles. Então, salve enganos, abaixo vou explicar tudo o que sei sobre esses facilitadores e solucionar algumas dúvidas.

Vamos lá...

 

Introdução

Primeiro, vamos definir o que é ponteiro:

"Em programação, um ponteiro ou apontador é um tipo de dado de uma linguagem de programação cujo valor se refere diretamente a um outro valor alocado em outra área da memória, através de seu endereço. Um ponteiro é uma simples implementação do tipo referência da ciência da computação."
(Wikipedia: http://pt.wikipedia.org/wiki/Ponteiro_(programa%C3%A7%C3%A3o))

Entendido? É simples, imagine da seguinte forma. Você declara uma variável A e atribui a ela o valor de 5.

int a = 5;

Imaginando que você é um super nerd espinhento que decorou os endereços de memória do seu computador, considere que o valor da variável A foi alocado no endereço:

0x10 = a = 5

Agora vamos declarar uma variável que guarda o ondereço de memórias de outras variáveis (isso é um ponteiro):

int *p;

Explicando... Em C, basicamente, quando você insere um asterísco (*) antes do nome da variável ela torna-se um ponteiro, que conterá o endereço de memória de uma variável do mesmo tipo que ela (no exemplo, o ponteiro P necessáriamente terá que apontar para um endereço de memória de uma variável do tipo INTEIRO).

Entendido isso, podemos agora guardar o endereço de memória de A em P, atribuindo A prescedido de um E comercial (&):

p = &a;

Prescedendo um variável qualquer (mesmo ponteiro) com um &, isso faz com que a variável retorne naquele momento seu próprio endereço de memória. Então, se dermos um PRINTF em &a:

// %p é o marcador para mostrar endereços de memória
printf("%p", &a); // exibe: 0x10

 

Trabalhando com Ponteiros

Agora podemos passar para o passo de pegar o valor da variável pelo seu endereço de memória, de uma forma ainda mais simples. Se dermos um PRINTF em P veremos:

printf("%p", p); // exibe: 0x10 (o endereço de memória de A)

E se usarmos o prescedente asterísco (*) em P, veremos:

printf("%i", *p); // exibe: 5 (o valor do endereço de memória, que no caso é o valor da variável A)

Compreendendo tudo isso, podemos definir algumas coisas baseadas em nosso exemplo:

a  = 5
&a = 0x10
p  = &a = 0x10
&p = ao endereço de memória de P, por exemplo, 0x11
*p = a = 5

O que é preciso definir muito bem é, que o ponteiro não se refere a quantidade de memória alocada pela variável (independente do tipo) e sim ao local quem está alocada na memória. Por exemplo, podemos ter a seguinte informação em sua memória:

0x10 = 10 Mb
0x11 = 1 Kb
0x12 = 5 Gb
0x13 = 7 Bytes
0x14 = 100 Tb

 

Vetor é um Ponteiro

Para continuarmos a entender e usar ponteiros, temos que ter em mente que um vetor é um ponteiro (matriz é um pouco diferente). Como assim?!

Um vetor (array para os íntimos), nada mais é que um ponteiro para o endereço de memória da primeira posição do vetor. Por exemplo:

int v[5] = {1, 2, 3, 4, 5};

E assumindo que o programa aloca os seguintes endereços de memória:

0x10 = 1
0x11 = 2
0x12 = 3
0x13 = 4
0x14 = 5

Se dermos um PRINTF em V:

printf("%p", v); // exibe: 0x10
printf("%p", &v[0]); // exibe: 0x10

Então, podemos complementar nossa tabela acima da seguinte forma:

0x10 = v[0] = 1
0x11 = v[1] = 2
0x12 = v[2] = 3
0x13 = v[3] = 4
0x14 = v[4] = 5

 

O Uso do Ponteiro

Em C, se incrementarmos (++) um ponteiro, ele passará a valer o próximo endereço de memória. Por exemplo:

printf("%p", p); // 0x10
p++;
printf("%p", p); // 0x11

Baseado nisso, poder percorrer um vetor incremetando o ponteiro:

int v[5] = {1, 2, 3, 4, 5};

for(i=0; i<5; i++)
{
    printf("V aponta para %p \n", v++);
}

Exibindo:

V aponta para 0x10
V aponta para 0x11
V aponta para 0x12
V aponta para 0x13
V aponta para 0x14

E se quisermos pegar o valor:

int v[5] = {1, 2, 3, 4, 5};

for(i=0; i<5; i++)
{
    printf("V aponta para o valor %i \n", *v++);
}

Exibindo:

V aponta para o valor 1
V aponta para o valor 2
V aponta para o valor 3
V aponta para o valor 4
V aponta para o valor 5

 

Exemplo Prático

Juntando tudo que você provavelmente aprendeu nesse post, tente entender o código abaixo. Está simples e didático:

/*
 * LearningPointers.c
 *
 * @Linux Ubuntu 10.4
 * @IDE Eclipse CDT
 * @Compiler Linux GCC
 *
 *  Created on: Oct 1, 2010
 *      Author: idemax - www.idemax.net
 */

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int x;

    int i=2, *p_int=&i;

    char str[5]="test", *p_str=str; // ou *p=&str

    printf("i\t<-\t%i\n*p_int\t<-\t%i\np_int\t<-\t%p", i, *p_int, p_int);

    printf("\np_str:\t");

    for(x=0; x<5; x++)
    {
        printf("%c", *p_str++); // percorrendo por ponteiro
    }

    return EXIT_SUCCESS;
}

 

Conclusão

Espero ter esclarecido suas dúvidas com ponteiro em C. Qualquer dúvida me mande um e-mail no:
idemax@gmail.com

Até a próxima...

sábado, 19 de junho de 2010

ControlToy v.1

Depois de algumas madrugadas a dentro e "perdendo" algumas aulas de ditado na faculdade, consegui concluir meu primeiro projeto em linguagem C usando a IDE Dev-C++, para a faculdade. Um programa para gerenciamento de loja com controle de estoque, caixa, entrada de produtos e listagem de com paginação!

Tela Principal

Código Fonte

ControlToy v.1.c
Onde é chamado os métodos correspondentes a opção selecionada pelo usuário.
/*
 * ControlToy v.1 - 2010
 * Desenvolvido por Marcelo L. Filho ( Idemax )
 * idemax@idemax.net - www.idemax.net
 * Todos os direitos intelectuais reservados ao uso educacional.
 */

#include "includes.c"

void main()
{
    char option;
    
    // Descomente a linha abaixo para o programa cadastrar 100 produtos automaticamente.    
    // testProducts();
    
    while(option != '6')
    {
        system("cls");
        
        printf("\n\t------------------");
        printf("\n\t| ControlToy v.1 |");
        printf("\n\t------------------");
        
        printf("\n\n\tMENU PRINCIPAL\n");
        printf("\n\t1) Cadastrar Produtos");
        printf("\n\t2) Frente de Caixa");
        printf("\n\t3) Consultar Estoque");
        printf("\n\t4) Entrada de Produtos");
        printf("\n\t5) Listagem de Produtos");
        printf("\n\t6) Sair");
        printf("\n\n\tSelecione a opcao desejada: ");
        fGetCH(&option);
        
        switch(option)
        {
            case '1': // Cadastrar Produtos
                createNewProduct();
                break;
            case '2': // Frente de Caixa
                cashier();
                break;
            case '3': // Consultar Estoque
                checkStock();
                break;
            case '4': // Entrada de Produtos
                entryProduct();
                break;
            case '5': // Listagem de Produtos
                listProducts();
                break;
            case '6': // Sair
                if( !confirm(CONFIRMACAO_SAIR, 1) )
                    option = 0;
                break;
            default:
                alert(OPCAO_INVALIDA, 1);
                break;
        }
    }
}

includes.c
Aqui é concentrado todos os includes necessários para o funcionamento do programa.
/*
 * ControlToy v.1 - 2010
 * Desenvolvido por Marcelo L. Filho ( Idemax )
 * idemax@idemax.net - www.idemax.net
 * Todos os direitos intelectuais reservados ao uso educacional.
 */

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <math.h>

#include "Constants.c"
#include "Prototypes.c"
#include "Structs.c"
#include "db.c"
#include "Utils.c"
#include "Functions.c"

Constants.c
Constantes usadas no programa avisar e informar o usuário.
/*
 * ControlToy v.1 - 2010
 * Desenvolvido por Marcelo L. Filho ( Idemax )
 * idemax@idemax.net - www.idemax.net
 * Todos os direitos intelectuais reservados ao uso educacional.
 */

// menu
#define OPCAO_INVALIDA   "Opcao invalida!"

// db
#define FIRST_ID   100
#define DB_SIZE    500

// novo produto
#define PRODUTO_SUCESSO     "Produto cadastrado com sucesso!"
#define QTD_PAGINACAO       5

// caixa
#define QUANTIA_INDISPONIVEL    "Quantidade nao disponivel em estoque!"
#define INSERIR_NOVO            "Deseja inserir novo produto na lista de compra? ( s:SIM, n:NAO )"
#define FINALIZAR_LISTA         "Deseja finalizar a lista de compra? ( s:SIM, n:NAO )"
#define NOVO_PRODUTO_CAIXA_ERRO "Produto ja existe da lista de compra!"
#define NAO_HA_PRODUTOS_CAIXA   "Nao existem produtos cadastrados na lista de compra!"
#define CONFIRMAR_LISTA_COMPRA  "Efetuar saida dos produtos e baixa em estoque? ( s:SIM, n:NAO )"
#define NOVA_LISTA              "Deseja iniciar uma nova lista de compra? ( s:SIM, n:NAO )"
#define VENDA_FINALIZADA        "Saida de produtos efetuada com sucesso!"

// consulta
#define ID_NAO_ENCONTRADO   "Produto nao encontrado, tente novamente!"
#define CONTINUAR_BUSCA     "Deseja consultar outro produto? ( s:SIM, n:NAO )"

// entrada
#define ENTRAR_OUTRO    "Novos dados gravados com sucesso!\n\n\tDeseja da entrada em outro produto? ( s:SIM, n:NAO )"
#define CONFIRMAR_INFO  "Deseja alterar os valores de compra e venda do produto? ( s:SIM, n:NAO )"

// lista
#define NUMERO_PRE_CADASTRO 100
#define SAIR_LISTAGEM       "Pressione qualquer tecla para voltar ao menu inicial..."
#define NAO_HA_PRODUTOS     "Nao existe produto cadastrado!"

// sair
#define CONFIRMACAO_SAIR "Tem certeza que deseja sair? ( s:SIM, n:NAO )"

Prototypes.c
Mantém as assinaturas dos métodos que são necessários antes da implementação.
/*
 * ControlToy v.1 - 2010
 * Desenvolvido por Marcelo L. Filho ( Idemax )
 * idemax@idemax.net - www.idemax.net
 * Todos os direitos intelectuais reservados ao uso educacional.
 */

void alert(char text[], char cleanScreen);
float *sumPurchases(); // [0]: quantidade total, [1]: valor total
void completeShoppingList();

Structs.c
Estruras necessárias para tipar conjuntos de dados.
/*
 * ControlToy v.1 - 2010
 * Desenvolvido por Marcelo L. Filho ( Idemax )
 * idemax@idemax.net - www.idemax.net
 * Todos os direitos intelectuais reservados ao uso educacional.
 */

typedef struct products
{
    int id;
    char description[100];
    float sale, purchase;
    int stored;
}product;

db.c
Variáveis e métodos usados para gerenciar as entradas e saídas de dados do vetor que guarda os produtos.
/*
 * ControlToy v.1 - 2010
 * Desenvolvido por Marcelo L. Filho ( Idemax )
 * idemax@idemax.net - www.idemax.net
 * Todos os direitos intelectuais reservados ao uso educacional.
 */

int id = FIRST_ID, index = 0, cashierIndex = 0, cashierProducts[DB_SIZE][2];
product products[DB_SIZE];

int getNewId()
{
    return ++id;
}

void insertNewProduct(product newProduct)
{
    newProduct.id = getNewId();
    
    products[index] = newProduct;
    
    index++;
}

void insertNewProductVariables(char description[], float sale, float purchase, int stored)
{
    product newProduct;
    
    strncpy(newProduct.description, description, 100);
    newProduct.sale = sale;
    newProduct.purchase = purchase;
    newProduct.stored = stored;
    
    insertNewProduct( newProduct );
}

int verifyProductID( int pID )
{
    int i, rtn = 0, found = 0;
    product prod;
    
    for(i = 0; i < index; i++)
    {
        if(pID == products[i].id)
        {
            rtn = pID;
            found = 1;
            break;
        }
    }
    
    if( !found )
    {
        alert(ID_NAO_ENCONTRADO, 1);
        return -1;
    }
    
    return rtn;
}

int getProductByID( int pID )
{
    int i, rtn = 0, found = 0;
    product prod;
    
    for(i = 0; i < index; i++)
    {
        if(pID == products[i].id)
        {
            rtn = i;
            found = 1;
            break;
        }
    }
    
    if( !found )
    {
        alert(ID_NAO_ENCONTRADO, 1);
        return -1;
    }
    
    return rtn;
}

float getProductSellingPrice(int pID)
{
    float rtn = 0.0;
    int i;

    for(i = 0; i < index; i++)
    {
        if(pID == products[i].id)
        {
            rtn = products[i].sale;
            break;
        }
    }
    
    return rtn;
}

void startNewCashier()
{
    int i;
    
    for(i = 0; i < DB_SIZE; i++)
    {
        cashierProducts[i][0] = -1;
        cashierProducts[i][1] = -1;
    }
    
    cashierIndex = 0;
}

void inserNewCashierProduct(int pID, int qtd)
{
    cashierProducts[cashierIndex][0] = pID;
    cashierProducts[cashierIndex][1] = qtd;
    
    cashierIndex++;
}

int hasProductInCashier(int pID)
{
    int i;
    
    for(i = 0; i < cashierIndex; i++)
        if(cashierProducts[i][1] == pID)
            return 1;
    
    return 0;
}

Utils.c
Métodos e variáveis usadas globalmente pelo programa, para auxiliar no feedback do usuário e na execução de operações.
/*
 * ControlToy v.1 - 2010
 * Desenvolvido por Marcelo L. Filho ( Idemax )
 * idemax@idemax.net - www.idemax.net
 * Todos os direitos intelectuais reservados ao uso educacional.
 */

// Mostra uma mensagem na tela
void alert(char text[], char cleanScreen)
{
    if(cleanScreen)
        system("cls");
        
    printf("\n\n\n\t*** AVISO ***\n\n\t%s\n\n\n\n\t", text);
    system("pause");
}

void pause(char text[])
{
    printf("%s", text);
    fflush(stdin);
    getch();
}

void fGetCH(char * value)
{
    fflush(stdin);
    *value = getch();
}

void fGetS(char * value)
{
    fflush(stdin);
    gets(value);
}

int confirm(char text[], char cleanScreen)
{
    int rtn = 0;
    char choice;
    
    if(cleanScreen)
        system("cls");
    
    printf("\n\n\n\t*** ATENCAO ***\n\n\t%s\n\t", text);
    fGetCH(&choice);
    
    if(choice == 'S' || choice == 's' || choice == 13)
        rtn = 1;
    
    return rtn;
}

int stopPagination(int cPage, int tPage)
{
    int rtn = 1;
    char key;
    
    printf("\n\tPagina %i de %i.\n\tQualquer tecla: proxima pagina \\ ESQ: menu principal", cPage, tPage);    
    fGetCH(&key);
    
    if(key == 27)
        rtn = 0;
        
    return rtn;
}

void showProductInfo(int pID)
{
    printf("\t[%i] %s\n\t\tVenda R$ %.2f - Compra R$ %.2f // Estoque: %d unidades\n\n", products[pID].id, products[pID].description, products[pID].sale, products[pID].purchase, products[pID].stored);
}

void showCashierProductInfo(int pID)
{
    int correctID = getProductByID(cashierProducts[pID][0]);
    
    printf("\t[%i] %s\n\t\tQuantidade: %i unidades - Total: R$ %.2f\n\n", products[correctID].id, products[correctID].description, cashierProducts[pID][1], cashierProducts[pID][1] * products[correctID].sale);
}

int closeShoppingList()
{
    if(cashierIndex == 0)
    {
        alert(NAO_HA_PRODUTOS_CAIXA, 1);
        return 0;
    }
    
    int listIndex = 0, i, cPage = 1, tPage, rest, rtn = 1;
    
    tPage = cashierIndex / QTD_PAGINACAO;
    rest = cashierIndex % QTD_PAGINACAO;
    
    if(rest < 5)
        tPage++;
    else
        tPage--;
    
    for(i = 0; i < cashierIndex; i++)
    {
        if(listIndex == 0)
        {
            system("cls");
            
            printf("\n\t--------------------");
            printf("\n\t| FINALIZAR COMPRA |");
            printf("\n\t--------------------\n\n");
        }
        
        if(listIndex < QTD_PAGINACAO)
        {
            showCashierProductInfo(i);
            listIndex++;
        }
        
        if(listIndex >= QTD_PAGINACAO)
        {
            if( !stopPagination(cPage, tPage) )
                break;

            cPage++;
            listIndex = 0;
        }
        
        if(listIndex != 0 && i == cashierIndex - 1)
        {
            float *sum = sumPurchases();
            
            printf("\n\tPagina %i de %i.\n\n\t-------------------------------------------------------\n\tFIM DA LISTA DE COMPRA\n\n\tTotal de produtos: %.0f - Total da compra: R$ %.2f\n", cPage, tPage, sum[0], sum[1]);
            
            if(confirm(CONFIRMAR_LISTA_COMPRA, 0))
                completeShoppingList();
            else
                rtn = 0;
        }
    }
    
    return rtn;
}

float *sumPurchases() // [0]: quantidade total, [1]: valor total
{
    float *rtn, qtd = 0.0, pSum = 0, saleValue, result[2];
    int i;
    
    for(i = 0; i < cashierIndex; i++)
    {
        qtd += cashierProducts[i][1];
        
        saleValue = getProductSellingPrice(cashierProducts[i][0]);
        pSum += saleValue * cashierProducts[i][1];
    }
    
    result[0] = qtd;
    result[1] = pSum;
    
    rtn = &result;
    
    return rtn;
}

void completeShoppingList()
{
    int i, productID;
    
    for(i = 0; i < cashierIndex; i++)
    {
        productID = getProductByID(cashierProducts[i][0]);
        products[productID].stored -= cashierProducts[i][1];
    }
    
    alert(VENDA_FINALIZADA, 1);
}

Functions.c
Métodos e variáveis do menu principal.
/*
 * ControlToy v.1 - 2010
 * Desenvolvido por Marcelo L. Filho ( Idemax )
 * idemax@idemax.net - www.idemax.net
 * Todos os direitos intelectuais reservados ao uso educacional.
 */

// popula o DB de produtos para testes
void testProducts()
{
    int i, n, t = NUMERO_PRE_CADASTRO;
    product testProduct;
    
    for(i = 0; i < t; i++)
    {
        n = i + 1;
        insertNewProductVariables("Produto", n*4, n*2, n*6);
    }
}

// 1- Cadastrar Produtos
void createNewProduct()
{
    system("cls");
    
    product newProduct;
    
    printf("\n\t--------------------------");
    printf("\n\t| CADASTRAR NOVO PRODUTO |");
    printf("\n\t--------------------------\n");
    printf("\n\n\tDigite a descricao do produto:\n\t");
    
    fGetS( newProduct.description );
    
    printf("\n\n\tDigite o valor de compra do produto:\n\t");
    scanf("%f", &newProduct.purchase);
    
    printf("\n\n\tDigite o valor de venda do produto:\n\t");
    scanf("%f", &newProduct.sale);
    
    printf("\n\n\tDigite a quantia que o produto tem em estoque:\n\t");
    scanf("%d", &newProduct.stored);
    
    insertNewProduct( newProduct );
    
    printf("\n\n\tNovo produto \"%s\" cadastrado com o ID: %i\n\n\t", newProduct.description, id);
    system("pause");
    
    alert(PRODUTO_SUCESSO, 1);
}

// 2- Frente de Caixa
void cashier() // cashier = caixa de supermercado ( http://www.liveenglishprogram.com/caixa.html )
{
    startNewCashier();
    
    int continueRegistration = 1, listSize = cashierIndex, pID, qtd, qtdError;
    
    while( continueRegistration )
    {
        system("cls");
        
        printf("\n\t-------------------");
        printf("\n\t| FRENTE DE CAIXA |");
        printf("\n\t-------------------\n\n");
        
        printf("\tProdutos da lista: %i", listSize);
        
        printf("\n\n\tDigite o ID do produto a ser inserido:\n\t\t( 0: menu principal, 1: finalizar lista )\n\t");
        scanf("%i", &pID);
        
        if( pID == 0 )
            return;
            
        if( pID != 1 ) // novo produto da lista
        {
            pID = verifyProductID(pID);
            
            if(pID > -1)
            {
                if( hasProductInCashier(pID) )
                {
                    alert(NOVO_PRODUTO_CAIXA_ERRO, 1);
                    continue;
                }
                
                qtdError = 1;
                while( qtdError )
                {
                    printf("\n\n");
                    showProductInfo(getProductByID(pID));
                    
                    printf("\tDigite a quantidade comprada: ");
                    scanf("%i", &qtd);
                    
                    if( qtd > products[getProductByID(pID)].stored )
                        alert(QUANTIA_INDISPONIVEL, 0);
                    else
                        qtdError = 0;
                }
                
                inserNewCashierProduct(pID, qtd);
                
                listSize = cashierIndex;
                
                if(confirm(INSERIR_NOVO, 1))
                {
                    continue;
                }
                else if(confirm(FINALIZAR_LISTA, 0))
                {
                    if(!closeShoppingList() && confirm(NOVA_LISTA, 1))
                        cashier();
                    
                    continueRegistration = 0;
                }
                else
                {
                    continueRegistration = 0;
                }
            }
        }
        else // finaliza a lista
        {
            if(listSize != 0 && !closeShoppingList() && confirm(NOVA_LISTA, 1))
                cashier();
            
            continueRegistration = 0;
        }
    }
}

// 3- Consultar Estoque
void checkStock()
{
    system("cls");
    
    printf("\n\t---------------------");
    printf("\n\t| CONSULTAR ESTOQUE |");
    printf("\n\t---------------------\n\n");
    
    int pID;
    
    printf("\tDigite o ID do produto a ser consultado ( 0: menu principal ):\n\t");
    scanf("%i", &pID);
    
    if( pID == 0 )
        return;
        
    pID = getProductByID(pID);
        
    if(pID > -1)
    {
        printf("\n\n");
        showProductInfo(pID);
        
        if(!confirm(CONTINUAR_BUSCA, 0))
            return;
    }
    
    checkStock();
}

// 4- Entrada de Produtos
void entryProduct()
{
    system("cls");
    
    printf("\n\t-----------------------");
    printf("\n\t| ENTRADA DE PRODUTOS |");
    printf("\n\t-----------------------\n\n");
    
    int pID;
    
    printf("\tDigite o ID do produto a ser dada entrada ( 0: menu principal ):\n\t");
    scanf("%i", &pID);
    
    if( pID == 0 )
        return;
        
    pID = getProductByID(pID);
        
    if(pID > -1)
    {
        printf("\n\n");
        showProductInfo(pID);
        
        float sale, purchase;
        int stored;
        
        printf("\tDigite a quantidade de produtos que esta sendo adquirida:\n\t");
        scanf("%i", &stored);
        
        products[pID].stored  += stored; //  No PDF pedia a quantidade adquirida nao a nova quantidade, por isso é adicionado a quantidade atual, nao atualizado.
        
        /*
        Contribuição abaixo de Xandão ( http://www.twitter.com/xandao_luchetti )
        */
        if(!confirm(CONFIRMAR_INFO, 0))
            return;
        
        printf("\n\n\tDigite o novo preco de compra:\n\t");
        scanf("%f", &purchase);
        
        printf("\n\n\tDigite o novo preco de venda:\n\t");
        scanf("%f", &sale);
        
        products[pID].purchase = purchase;
        products[pID].sale     = sale;
        
        if(!confirm(ENTRAR_OUTRO, 0))
            return;
    }
    
    entryProduct();
}

// 5- Listagem de Produtos
void listProducts()
{
    if(index == 0)
    {
        alert(NAO_HA_PRODUTOS, 1);
        return;
    }
    
    int listIndex = 0, i, cPage = 1, tPage, rest;
    
    tPage = index / QTD_PAGINACAO;
    rest = index % QTD_PAGINACAO;
    
    if(rest < 5)
        tPage++;
    else
        tPage--;
    
    for(i = 0; i < index; i++)
    {
        if(listIndex == 0)
        {
            system("cls");
            
            printf("\n\t------------------------");
            printf("\n\t| LISTAGEM DE PRODUTOS |");
            printf("\n\t------------------------\n\n");
        }
        
        if(listIndex < QTD_PAGINACAO)
        {
            showProductInfo(i);
            listIndex++;
        }
        
        if(listIndex >= QTD_PAGINACAO)
        {
            if( !stopPagination(cPage, tPage) )
                break;

            cPage++;
            listIndex = 0;
        }
        
        if(listIndex != 0 && i == index - 1)
        {
            printf("\n\tPagina %i de %i.\n\t", cPage, tPage);
            pause(SAIR_LISTAGEM);
        }
    }
}

Baixe os códigos fontes: ControlToy v.1.rar (16.39 KB)