Ir ao conteúdo
  • Cadastre-se

C++ Criar um procedure que trabalha com array


MUrisCuri

Posts recomendados

Pretendo criar um array de valor 20, usando uma função. O usuário digita um valor (limite) que será no máximo 20. Esse valor será usado como índice do array em uma função "build_table", na qual haverá armazenamento de números inteiros. Por exemplo: o usuário digita 8. Esse valor será usado na função, onde através do comando "for" haverá formação do array do tipo tab[ind]. Então, o usuário digitará os 8 números inteiros que serão armazenados no array. Segue meu código abaixo. Dá erro na minha função.

#include <iostream>
#include <stdlib.h>
#define meunome cout << "\n\n\t\t Mauricio Bainy Curi - Sistema de informações\n\n\t\t Metodo Knuth\n\n ";
using namespace std;

short int build_table(short int lim){
	short int ind;
	int tab[20];
	
	for (ind=1;ind<=lim;ind++){
		cout << "/n Digite o número da posicao " << ind << ":";
		cin >> tab[ind];
	}
		cout << "Os numeros digitados são: \n\n";
		for (ind=1;ind<=lim;ind++){
			cout << "Tab[" << ind <<"]/n";
		}
}
int main(){
	short int limite;
	meunome;
	cout << "/n Digite a quantidade (limite) de numeros que serao ordenados: ";
	cin >> limite;
	short int build_table(short int lim)=limite;
	return 0;
}

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

tem alguns problemas no codigo ai..

 

o primeiro é que você declara o tab com 20 posições mas seu for pode fazer um acesso ilegal de memoria nas posições acima de 20..

 

você também esta deixando o primeiro item do array sem preencher porque você comeca o for do 1 e nao do 0.

 

e essa linha aqui

 

short int build_table(short int lim)=limite;

 

nao sei o que você quis fazer, mas um dos erros do codigo tá ai..

 

outro tá aqui

 

#define meunome cout << "\n\n\t\t Mauricio Bainy Curi - Sistema de informações\n\n\t\t Metodo Knuth\n\n ";

 

usa o define só pra fazer substituicao de strings, nao coloca funcoes no meio dela assim...

 

e você nao tá fazendo ordenacao nenhuma, o que possivelmente era o objetivo do programa.

 

Link para o comentário
Compartilhar em outros sites

5 horas atrás, DiogoM12 disse:

tem alguns problemas no codigo ai..

 

o primeiro é que você declara o tab com 20 posições mas seu for pode fazer um acesso ilegal de memoria nas posições acima de 20..

 

você também esta deixando o primeiro item do array sem preencher porque você comeca o for do 1 e nao do 0.

 

e essa linha aqui

 

short int build_table(short int lim)=limite;

 

nao sei o que você quis fazer, mas um dos erros do codigo tá ai..

 

outro tá aqui

 

#define meunome cout << "\n\n\t\t Mauricio Bainy Curi - Sistema de informações\n\n\t\t Metodo Knuth\n\n ";

 

usa o define só pra fazer substituicao de strings, nao coloca funcoes no meio dela assim...

 

e você nao tá fazendo ordenacao nenhuma, o que possivelmente era o objetivo do programa.

 

A pretendia com short int build_table(short int lim)=limite; que o valor digitado pelo usuário fosse passado para dentro dessa função build_table, e tal valor fosse assumido por "int" que é o índice do array.

Como sou inexperiente em C++, pretendo montar o código aos poucos. Primeiramente, quero armazenar números inteiros em um array que deverá ter um índice definido pelo usuário. Isso, não direto na função "main", mas em uma função criada para isso.

Obrigado Diogo, deu certo!

#include <iostream>
#include <stdlib.h>
#define meunome cout << "\n\n\t\t Mauricio Bainy Curi - Sistema de informações\n\n\t\t Metodo Knuth\n\n ";
using namespace std;

void build_table(){
    short int ind=0, limite;
    int tab[ind];
    cout << "\n Digite a quantidade (limite) de numeros que serao ordenados: ";
    cin >> limite;
    for (ind;ind<limite;ind++){
        cout << "\n Digite o numero da posicao " << ind << ": ";
        cin >> tab[ind];
    }
        cout << "Os numeros digitados sao: \n\n";
        for (ind=0;ind<limite;ind++){
            cout << tab[ind] <<"\n";
        }
}
int main(){
    meunome;
    build_table();
    return 0;
}

 

Link para o comentário
Compartilhar em outros sites

8 horas atrás, MUrisCuri disse:

Obrigado Diogo, deu certo!

 

Não, não "deu certo".

 

  • Ao invés de passar o parâmetro, que seria o tamanho do tal array, você simplesmente passou a leitura para dentro da função e esvaziou main(), que sequer vai ter acesso ao vetor. Esse não é o propósito de se escrever uma função/
     
  • Você disse que está aprendendo C++ mas postou um programa em C... São linguagens muito distintas e não basta usar cin e cout para criar um programa em C++. Sim, o que escreveu é válido C++, mas só isso.
     
  • Cuidado com efeitos colaterais de um #define. Isso sempre cai na sua cabeça. Nesse caso seu define já tem um ';'. Má ideia. Isso termina um comando e tem outro no programa:
8 horas atrás, MUrisCuri disse:

    meunome;

 

E nada acrescentou ao seu programa. Só ficou mais difícil de ler.

 

  • nunca use isso
     
          for (ind=0;ind<limite;ind++){
                cout << tab[ind] <<"\n";
            ...


    Sempre declare as variáveis de controle do loop no loop. Em C++ você pode declarar variáveis dentro de um if, de um switch... Ou claro dentro de qualquer bloco { } . Todo o propósito é diminuir o scope, o tempo de vida de variáveis. Isso dá muito problema. Em especial com variáveis com nomes ingênuos tipo i e j soltas pelo programa... Use algo como
     

        for ( unsigned ind = 0; ind<tamanho; ind+=1)
        {
            cout << "Digite o numero da posicao " << 1+ind <<
            " de " << tamanho << ": ";
            cin >> vetor[ind];
        };

     

  • O que você quer em geral é escrito assim, em relação ao array:
     

    • você declara seu array em main() com o tamanho certo
       

      	short tab[20];

       

    • você escreve a função e passa o endereço de início do tal array e o total de valores que quer ler
       

          void build_table( short tamanho, short vetor[] ){};


      para ler 'tamanho' valores no 'vetor'. Garanta tamanho <= 20 antes de chamar.
       

    • chame a função depois de ler o tamanho, algo assim:
       

          cout << "\n Digite a quantidade (limite) de numeros que serao ordenados: ";
          cin >> limite;
          if ( limite <= 20 ) build_table(limite,tab);
                          ...


      Entenda que o limite pode ser negativo então seria melhor declarar como unsigned para não ter que testar. -1000 é menor que 20... ;) 
       

  • Entenda que é certo que vai precisar mostrar os valores, já que pretende depois ordenar o tal vetor. Então faça o simples e escreva logo uma função que mostra o vetor, ao invés de deixar isso fixo DENTRO da função que lê porque ela fica muito menos útil...

Eis um exemplo do que tentou fazer até aqui, com algumas correções:
 

#define meunome cout << "\n\n\t\t Mauricio Bainy Curi - Sistema de \
informações\n\n\t\t Metodo Knuth\n\n ";

#include <iostream>
using namespace std;

void build_table(unsigned short, short[]);
void show_table(unsigned short, short[]);

int main(void)
{
    short tab[20];
    unsigned limite = 0;
    meunome
    cout << "\n [1] Digite a quantidade (limite) de numeros que serao ordenados: ";
    cin >> limite;
    if ( limite >= 20 ) return -1;
    cout << endl;
    build_table( limite, tab );
    show_table( limite, tab );
    // uma segunda vez para ajudar a entender porque se usa uma funcao afinal
    cout << "\n [2] Digite a quantidade (limite) de numeros que serao ordenados: ";
    cin >> limite;
    if ( limite >= 20 ) return -1;
    cout << endl;
    build_table( limite, tab );
    show_table( limite, tab );
    return 0;
};

void build_table(unsigned short tamanho, short vetor[])
{
    for ( unsigned ind = 0; ind<tamanho; ind+=1)
    {
        cout << "Digite o numero da posicao " << 1+ind <<
        " de " << tamanho << ": ";
        cin >> vetor[ind];
    };
    return;
}

void show_table(unsigned short tamanho, short v[])
{
    cout << "Os numeros digitados: ";
    for ( unsigned ind = 0; ind<tamanho; ind+=1)
        cout << v[ind] <<" ";
    cout << endl;
    return;
}

 

 

Isso mostra por exemplo

 

toninho@DSK-2009:/mnt/c/Users/toninho/projects/um$ g++ -Wall -std=c++17 ar.cpp
toninho@DSK-2009:/mnt/c/Users/toninho/projects/um$ ./a.out


                 Mauricio Bainy Curi - Sistema de informações

                 Metodo Knuth

 
 [1] Digite a quantidade (limite) de numeros que serao ordenados: 2

Digite o numero da posicao 1 de 2: 1
Digite o numero da posicao 2 de 2: 2
Os numeros digitados: 1 2 

 [2] Digite a quantidade (limite) de numeros que serao ordenados: 6

Digite o numero da posicao 1 de 6: 1
Digite o numero da posicao 2 de 6: 2
Digite o numero da posicao 3 de 6: 3
Digite o numero da posicao 4 de 6: 4
Digite o numero da posicao 5 de 6: 5
Digite o numero da posicao 6 de 6: -78
Os numeros digitados: 1 2 3 4 5 -78 

 

 

Compare com o modo como escreveu e procure entender as diferenças.

 

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

7 horas atrás, MUrisCuri disse:

Mas, percebo que não avanço, pois ainda não absorvi conteúdos como a orientação a objetos

 

Nao conheço esse livro. Mas pode ser que esteja ainda no início e muitos desses livros não começam por objetos e sim com um subconjunto da linguagem, mínimo, com algumas estruturas de loop e teste e comandos de entrada e saída básicos. 

 

Você pode usar o conceito de objetos em qualquer linguagem e programa. E também pode escrever bons programas de produção sem muitos desses conceitos. Herança, polimorfismo e encapsulamento são os conceitos básicos.

 

Pode aplicar isso ao próprio programa que postou aqui. Pode ser um bom começo :) 

Você entendeu a diferença entre o programa que escreveu e o programa que te mostrei? Rodou o programa que te mostrei?

 

Quanto aos livros, não conheço quase nada. Mas recomendo muito (como todo mundo) "A Tour of C++" e "Programming Principles And Practice Using C++" de Bjarne Stroustrup, e Effective C++ de Scott Meyers. E claro "Elements of Programming" de A. Stepanov.

 

Sobre orientação a objetos o melhor livro que existe provavelmente é esse: "Design Patterns: Elements of Reusable Object-Oriented Software" 

 

Você entende inglês? O suficiente para ler um livro ou seguir um curso?

 

Claro, esta é apenas minha opinião. E minhas opiniões não são assim muito populares :D

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

A diferenca é que no seu desenvolvimento há possibilidade de reutilizar valores das variaveis dentro da funcao principal, passando os 2 valores para serem usados em build_table (passagem de valores por parâmetros, é isso?). Pratico Inglês mas ainda sou iniciante. Vou tentar acessar conteúdos dos autores que recomendaste, caso haja online. Não compreendi as aulas sobre orientacao a objetos, mas agora me esforçarei pois sei q nada sei, o que me incentiva a aprender. Caso surjam dúvidas sobre implementar com orientacao a objetos, deverei postar um novo assunto? Muito obrigado pela ajuda!

Link para o comentário
Compartilhar em outros sites

3 minutos atrás, MUrisCuri disse:

Não compreendi as aulas sobre orientacao a objetos, mas agora me esforçarei pois sei q nada sei, o que me incentiva a aprender. Caso surjam dúvidas sobre implementar com orientacao a objetos, deverei postar um novo assunto?

 

Que conceito não entendeu? Aplique algum NESSE programa aqui. Vai te ajudar.

Link para o comentário
Compartilhar em outros sites

@MUrisCuri C++ é uma linguagem "enorme". Recomendo muita paciência. ;) 

 

Em relação à orientação a objetos há linguagens mais simples. De todo modo os conceitos mais importantes são, eu acho, encapsulamento, herança e polimorfismo. Eu incluiria generic programming --- templates no caso de C++.

 

O mesmo programa que te mostrei, reorganizado para usar um pouco desses conceitos, podia ser escrito assim:
 

#include <iostream>
using namespace std;

class Tabela
{
private:
    unsigned    tamanho;
    short       tabela[20];

public: 
    Tabela();

    void        build_table(unsigned);
    void        show_table();
    
};

int main(void)
{
    Tabela tab;
    tab.show_table();

    // le outra tabela
    cout << "\n [2] Digite a quantidade (limite) de numeros que serao ordenados: ";
    unsigned limite = 0;   
    cin >> limite;
    cout << endl;
    if ( limite >= 20 ) limite = 20;
    tab.build_table( limite );
    tab.show_table();

    return 0;
};

Tabela::Tabela()
{
    unsigned limite = 20;
    cout << "\n [1] Digite a quantidade (limite) de numeros que serao ordenados: ";
    cin >> limite;
    cout << endl;
    if ( limite < 20 ) tamanho = limite;
    build_table(limite);
};

void        Tabela::build_table(unsigned limite)
{
    for ( unsigned ind = 0; ind<limite; ind+=1)
    {
        cout << "Digite o numero da posicao " << 1+ind <<
        " de " << tamanho << ": ";
        cin >> tabela[ind];
    };
    tamanho = limite;
    return;
}

void        Tabela::show_table()
{
    cout << "Os numeros digitados: ";
    for ( unsigned ind = 0; ind<tamanho; ind+=1)
        cout << tabela[ind] <<" ";
    cout << endl;
    return;
}

 

Rode, compare, identifique os conceitos e pergunte algo se precisar. Posso te ajudar a implementar todos os conceitos nesse pequeno programa. 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

arfneto, pode verificar se estão corretas minha afirmações sobre a interpretação dos trechos de código seu abaixo?

 

1)

Tabela tab; //Cria uma instância ("tab" é um objeto) para a classe Tabela  
 tab.show_table(); //Chama o método através do objeto "tab"

 

2)

//Definição do método Tabela() o qual pertence à classe Tabela
Tabela::Tabela() 
{
   ...
};

 

3)

//Definição do método build_table que pertence à classe Tabela
void        Tabela::build_table(unsigned limite)
{
  ...
}

 

Porque você criou método Tabela() sem mencionar se retorna ou não algo? Já build_table(unsigned limite) foi declarado que é void. Qual a diferença?

Link para o comentário
Compartilhar em outros sites

15 minutos atrás, MUrisCuri disse:

Porque você criou método Tabela() sem mencionar se retorna ou não algo? Já build_table(unsigned limite) foi declarado que é void. Qual a diferença?


A diferença é que Tabela() é um construtor. Sempre retorna o mesmo algo: uma instância da classe. Você pode ter vários construtores (polimorfismo) mas todos retornam a mesma coisa.

 

16 minutos atrás, MUrisCuri disse:

1)

Tabela tab; //Cria uma instância ("tab" é um objeto) para a classe Tabela  
 tab.show_table(); //Chama o método através do objeto "tab"


na nomenclatura mais comum de C++ não é bem assim:

tab é uma instância de Tabela. Tabela é dita uma classe.

tab.show_table() chama o método show_table() da classe tabela a partir da instância tab. Então vai ter acesso aos dados dessa particular instância. É essencial entender isso: a classe tem métodos e propriedades encapsulados em cada instância.

 

17 minutos atrás, MUrisCuri disse:

2)

//Definição do método Tabela() o qual pertence à classe Tabela
Tabela::Tabela() 

 

Tabela::Tabela() é um construtor de classe. É um método muito especial, já que retorna uma instância da classe, por definição. Como não tem parâmetros é o construtor padrão. O construtor que é chamado quando declara por exemplo
 

     Tabela tab[30];


Uma vez para cada uma das 30 instâncias.

 

18 minutos atrás, MUrisCuri disse:

3)

//Definição do método build_table que pertence à classe Tabela
void        Tabela::build_table(unsigned limite)

 

Não sei como chamam isso em português, mas '::' seria operador de resolução de escopo --- scope resolution operator --- e ele diz o simples: a qual classe o método se aplica. Várias classes podem ter um método build_table().

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

arfneto, tentei implementar a ordenação dentro do método buid_table, mas não funcionou. O problema seria o acesso para alteração sem permissão do argumento tabela[] que é private? 

void        Tabela::build_table(unsigned limite)
{
    short temp;
    bool troca;
    for ( unsigned ind = 0; ind<limite; ind+=1)
    {
        cout << "Digite o numero da posicao " << 1+ind <<
        " de " << tamanho << ": ";
        cin >> tabela[ind];
    };
    tamanho = limite;
    
    while  (!ind >= limite )
    {
        unsigned ind=0;
        ind+=1;
        if ( tabela[ind] > tabela[ind+1])
        {
            temp = tabela[ind];
            tabela[ind] = tabela[ind+1];
            tabela[ind+1] = temp;
            troca = 1;
        }
        else    
        {
            ind+=1;
        }
        while ( ind == limite )
        {
            if ( troca == 1 )
            {
                limite-=1;
                troca = 0;
                ind = 0;
            }
            else
            {
                break;
            }
        }
    }

Link para o comentário
Compartilhar em outros sites

39 minutos atrás, MUrisCuri disse:

arfneto, tentei implementar a ordenação dentro do método buid_table, mas não funcionou. O problema seria o acesso para alteração sem permissão do argumento tabela[] que é private

 

Poste o programa inteiro...

 

Não, o problema não é esse. build_table() é um método da classe. Tem acesso a tudo.

 

Quando diz que algo não funcionou, explique o que não funcionou e como reproduzir o problema

 

 

 

Link para o comentário
Compartilhar em outros sites

 

 

#include <iostream>
using namespace std;

class Tabela //Definição da classe Tabela
{
private:
    unsigned    tamanho;
    short       tabela[20];

public: 
    Tabela();

    void        build_table(unsigned);
    void        show_table();

};

int main(void)
{
    Tabela tab;  
    tab.show_table();
    // le outra tabela
    cout << "\n [2] Digite a quantidade (limite) de numeros que serao ordenados: ";
    unsigned limite = 0;   
    cin >> limite;
    cout << endl;
    if ( limite >= 20 ) limite = 20;
    tab.build_table( limite );
    tab.show_table();

    return 0;
};


Tabela::Tabela() 
{
    unsigned limite = 20;
    cout << "\n [1] Digite a quantidade (limite) de numeros que serao ordenados: ";
    cin >> limite;
    cout << endl;
    if ( limite < 20 ) tamanho = limite;
    build_table(limite);
};

void        Tabela::build_table(unsigned limite)
{
    short temp;
    bool troca;
    for ( unsigned ind = 0; ind<limite; ind+=1)
    {
        cout << "Digite o numero da posicao " << 1+ind <<
        " de " << tamanho << ": ";
        cin >> tabela[ind];
    }
    tamanho = limite;
    ind=0;
    while  ( ! ind >= limite )
    {
        ind+=1;
        if ( tabela[ind] > tabela[ind+1])
        {
            temp = tabela[ind];
            tabela[ind] = tabela[ind+1];
            tabela[ind+1] = temp;
            troca = 1;
        }
        else    
        {
            ind+=1;
        }
        while ( ind == limite )
        {
            if ( troca == 1 )
            {
                limite-=1;
                troca = 0;
                ind = 0;
            }
            else
            {
                break;
            }
        }
    }
    return;
}

void        Tabela::show_table()
{
    cout << "Os numeros digitados: ";
    for ( unsigned ind = 0; ind<tamanho; ind+=1)
        cout << tabela[ind] <<" ";
    cout << endl;
    return;
}

 

Erros: In member function 'void Tabela::build_table(unsigned int)':

           'ind' was not declared in this scope.

 

O "ind" declarado no for só é reconhecido dentro do for? Teria que declarar o ind dentro do while? Tentei isso, compilou , mas não ocorreu swap.

 

 

Link para o comentário
Compartilhar em outros sites

@MUrisCuri a variável existe dentro do bloco { } mais interno. Se declarar dentro do for, ou entre as chaves do for() será lá. Se declarar no while() será lá. Um par de chaves delimita build_table(), certo? Se a variável precisa ser conhecida dentro de toda a função --- scope é o nome disso --- então declare lá, assim como fez com temp e troca. 

Porque essas duas estão lá e ind não? 

 

De todo modo não precisa disso em seu código. Está implementando ao que parece um simples bubble sort para classificar um vetor. Usar dois while não é uma boa ideia. Só complica. Bastam dois for() porque tal algoritmo implica em comparações e incremento de índices, então for() que inclui os índices é o mais simples.

 

bubble e insertion são os algoritmos mais comuns e ingênuos. Não adianta tentar ser original com esses algoritmos, como o radix sort. Tem em toda parte e faz parte da cultura popular ;) muito antes dos computadores.

 

Eles acabam SEMPRE sendo implementados com a mesma sequência e instruções. Acho que nem a Apple tentaria chamar isso de Apple Sort :D e eles gostam de (tentar) tomar crédito por tudo que copiam.

 

Em por exemplo em GeeksForGeeks tem implementações bem simples em várias linguagens de todos esses algoritmos e todo mundo sabe isso, alunos, professores e autores.  E ao entender um desses algoritmos pode acabar programando igualzinho a eles, sem copiar.

 

A diferença é que para implementar na prática tem outras preocupações: não é só um vetor de 10 int, tem chaves, registros podem vir de bancos de dados, podem ser milhares ou milhões...

 

Eis o exemplo de lá, só a primeira função

 

// A function to implement bubble sort 
void bubbleSort(int arr[], int n) 
{ 
   int i, j; 
   for (i = 0; i < n-1; i++)       
  
       // Last i elements are already in place    
       for (j = 0; j < n-i-1; j++)  
           if (arr[j] > arr[j+1]) 
              swap(&arr[j], &arr[j+1]); 
} 
  
/* Function to print an array */
void printArray(int arr[], int size) 
{ 
    int i; 
    for (i=0; i < size; i++) 
        printf("%d ", arr[i]); 
    printf("\n"); 
}

 

A segunda funçÃO é a que você devia ter escrito primeiro: se está aprendendo ou testando a primeira coisa que deve escrever é a função que mostra os dados na tela, como essa printArray() acima, porque é óbvio que vai precisar disso, antes mesmo de ler os dados. Vai querer saber se leu o que acha que leu, e se classificou o que acha que leu... SEMPRE

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Declarei unsigned ind, o programa compilou, mas nada dentro do while acontece, há o return dos valores digitados, sem haver o swap. Segue em anexo os passos que usei p/ implementar o método da bolha, fiz um teste de mesa com êxito.  

fluxograma e programação estruturada-Knuth.pdf

Link para o comentário
Compartilhar em outros sites

Leu o que eu disse sobre usar dois while e sobre ind nao precisar estar global na funcao?

 

Poste o programa aqui como está agora.

um "teste de mesa" pode não ser assim importante para um algoritmo de dois loops e tão disponível em tantos livros e na internet.

escreveu afinal a função que mostra a tablea?

viu a tabela antes E depois?

Link para o comentário
Compartilhar em outros sites

@MUrisCuri Se leu tudo que eu escrevi até agora, considere também que o tal sort deveria ser outro método da classe e não precisa de parâmetros. C++ não é C. C não é C++.

 

Lembro que te mostrei uma solução com um método show_table() por exemplo. Use Tabela::bubble_sort()

 

 

Em 06/01/2021 às 13:31, arfneto disse:

Que conceito não entendeu? Aplique algum NESSE programa aqui. Vai te ajudar

 

Nunca respondeu sobre isso. 

 

Usando essa orientação a objetos, entenda que outra provável necessidade paraubbble_sort()  seria um método que classificasse a tabela e retorne outra, quando for interessante não destruir a tabela original..

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Respondendo ao seu questionamento acima , afirmo que entendi todos os conceitos q explicasses aqui. 

 

Ao  terminar um procedimento da classe, a tabela é destruída porquê?. Entao, para preservar a entrada e de dados, o metodo bubblesort deve passar os dados para um metodo fora da classe?

Link para o comentário
Compartilhar em outros sites

1 hora atrás, MUrisCuri disse:

Ao  terminar um procedimento da classe, a tabela é destruída porquê?. Entao, para preservar a entrada e de dados, o metodo bubblesort deve passar os dados para um metodo fora da classe?

Não. Não é o caso. A tabela não é propriamente "destruída". A ordem é destruída. Esses algoritmos de classificação na maioria trabalham in-place, classificam a própria tabela. Então dependendo do uso pode ser que um método da classe que trabalhe cm a única tabela que tem lá não resolva. Outro caso é uma falha: se o programa cancelar ou cair a força a tabela vai ficar num estado intermediário e muitas vezes não se pode aceitar isso.

 

Então você pode ter um método que classifica a tabela, e um outro que gera uma nova em ordem. Polimorfismo.

Link para o comentário
Compartilhar em outros sites

Olá arfneto. O objetivo do código abaixo seria fazer como você recomendou, ou seja criar um método para ordenar os números da tabela. Instanciei a classe Array como obj, mas ao compilar emite a seguinte mensagem de erro: In function 'int main()': [Error] expected primary-expression before 'unsigned'.

 

#include <iostream>
#include<stdlib.h>
using namespace std;

class Array {
  private:
    unsigned size;
    short array[20];

  public:
    Array();
    void build_array(unsigned);
    void build_array_sort_number(unsigned); 
    void show_array();
};

int main(void){
    unsigned choice;
        
    while (choice!=3){
        system("cls");
        cout << "\t\t\t Ascending order of numbers - Knuth method" << endl;
        cout << endl;
        cout << "\t 1 - Natural Order" << endl;
        cout << "\t 2 - Ascending Order" << endl;
        cout << "\t 3 - Sair";
        cout << endl;
        cout << endl;
        cout << endl;
        cout << "Choice: ";
        cin >> choice;
        
        switch(choice){
            case 1 : system("cls");
            cout << endl;
            cout << "\t 1 - Natural Order" << endl;
            cout << endl;
            Array obj;
            obj.build_array(unsigned bound);
            cout << "Press any key to continue!";
            break;
            
            case 2 : system ("cls");
            cout << endl;
            cout << "\t 2 - Ascending Order" << endl;
            cout << endl;
            obj.build_array_sort_number(unsigned bound);
            cout << "Press any key to continue!";
            break;
            
            case 3 : exit(1);
        }
    }
    obj.show_array();
    return 0;
}

Array::Array(){
    unsigned bound = 20;
    cout << " Write the amount of the numbers to sort: ";
    cin >> bound;
    cout << endl;
    if ( bound < 20 )
        size = bound;
        build_array(bound);
        build_array_sort_number(bound);
};

void Array::build_array(unsigned bound){
    size = bound;
    //lê tabela
    for ( unsigned ind=0; ind < bound; ind+=1 ){
        cout << "Write array[" << ind << "] - size = " << bound << ": ";
        cin >> array[ind];
    }
    size=bound;
    return;
}

void Array::build_array_sort_number(unsigned bound){
    short temp;
    bool swap=0;
    unsigned ind=0;
    
    //Ordena números de forma crescente
    ind=0;
    for (ind; ind <= bound; ind+=1){
        if ( ind>=bound-1 ){
            if ( swap == 1 ){
            size-=1;
            swap = 0;
            ind=0;
            }
            else{
            break;
        }
    }
        else{
            if ( array[ind] > array[ind+1] ){
            temp = array[ind];
            array[ind] = array[ind+1];
            array[ind+1] = temp;
            swap = 1;
            }
        }
    }
    size=bound;
    return;
}

void Array::show_array(){
    cout << "The numbers entered are: " << endl;
    for ( unsigned ind=0; ind<size; ind+=1 )
        cout << "Tabela[" << ind << "] = " << array[ind] << endl;
    return;
}

Link para o comentário
Compartilhar em outros sites

19 minutos atrás, MUrisCuri disse:

Instanciei a classe Array como obj

 

Talvez esteja confundindo linguagens e coisas de C#, java e C++.

 

Instanciar uma classe em C++ 'e trabalho do construtor de classe. Por exemplo

 

	Array instancia_de_Array[200];

 

Vai calmamente chamar o construtor padrão de Array 200 vezes e instâncias todo mundo, de instancia_de_Array[0] a  instancia_de_Array[199]

 

Construtores são polimórficos. Abuse disse em seus testes. Não perca seu tempo lendo valores num (único) construtor.

 

Use arquivos separados para a classe. É melhor para você e outros.

 

Use o exemplo que eu te mostrei. Leia ao menos. Tem as funções e o modo de uso.

 

 

Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...

Ola Arfneto. 

 

Pode me ajudar, corrigindo os erros? Já vi que é errado chamar método de uma classe derivada dentro do método especial Array(). Criei uma classe derivada. Está certo isso? Assim, poderá reutilizar o método para ordenar.

 

In constructor 'Array::Array()':
    [Error] cannot call member function 'void SortedArray::build_array_sort_number(unsigned int)' without object

 

#include <iostream>
using namespace std;

class Array //Definição da classe Array
{
private:
    unsigned size;
    short array[20];

public: 
    Array(); //Array() é um construtor

    void build_array(unsigned);
    void show_array();
    
};

class SortedArray : public Array{
    public:
        void build_array_sort_number(unsigned);
};

int main(void)
{
    Array obj;
    obj.show_array();
    SortedArray obj2;
    obj.show_array();
    return 0;
};

//Array::Array() é um construtor de classe. É um método muito especial, já que retorna uma instância da classe, por definição.
//Como não tem parâmetros é o construtor padrão.
Array::Array() 
{
    unsigned bound = 20;
    cout << "\n [1] Digite a quantidade (limite) de numeros que serao ordenados: ";
    cin >> bound;
    cout << endl;
    if ( bound < 20 ) size = bound;
    Array::build_array(bound);
    SortedArray::build_array_sort_number(bound);
    
    
};

//Definição do método build_array
void Array::build_array(unsigned bound){
    size = bound;
    //lê tabela
    for ( unsigned ind=0; ind < bound; ind+=1 ){
        cout << "Write array[" << ind << "] - size = " << bound << ": ";
        cin >> array[ind];
    }
    size=bound;
    return;
}

void Array::show_array(){
    cout << "The numbers entered are: " << endl;
    for ( unsigned ind=0; ind<size; ind+=1 )
        cout << "Tabela[" << ind << "] = " << array[ind] << endl;
    return;
}

void SortedArray::build_array_sort_number(unsigned bound){
short temp;
    bool swap=0;
    unsigned ind=0;
    size=bound;        
    //lê tabela
    for (ind; ind < bound; ind+=1){
        cout << "Write array[" << ind << "] - size = " << bound << ": ";
        cin >> array[ind];
    }
    //Ordena números de forma crescente
    for ( ind=0; ind<=bound-1; ind+=1 ){
        while ( ind >= bound-1 ) {
            if ( swap == 1 ){
            bound-=1;
            swap = 0;
            ind=0;
            }
            else{
            break;
            }
        }
    if ( array[ind] > array[ind+1] ){
            temp = array[ind];
            array[ind] = array[ind+1];
            array[ind+1] = temp;
            swap = 1;
            }    
    }
    return;    
}

Sem título.png

Link para o comentário
Compartilhar em outros sites

3 horas atrás, MUrisCuri disse:

Já vi que é errado chamar método de uma classe derivada dentro do método especial Array(). Criei uma classe derivada. Está certo isso?

 

Não, não está certo. Não existe esse conceito de "método especial". Usar uma classe derivada envolve algum tipo de especialização da classe, algo como aquele exemplo chato clássico da classe Animal dos livros, de onde o autor deriva Passaro e Peixe e tal.

 

Nada tem a ver com o seu caso. Não está criando nada. Derivação (herança) tem a ver com especialização.

 

Como eu te disse, se não vai mais precisar da ordem original você usa um método da própria classe, já que é o óbvio: cada instância tem sua tabela. Esses métodos simples de classificação sempre atuam sobre a própria tabela. in-place sort.

 

Mas se não pretende destruir o vetor original  o que você faz é simplesmente criar um método que te atenda: pode retornar um array classificado, pode retornar uma nova instância da classe, qualquer coisa que sirva para o que precisa fazer.

 

De volta ao seu programa

 

Sugiro evitar esse tipo de comentário:
 

class Array //Definição da classe Array

 

Dá pra imaginar que depois de class Array venha a definição da classe. E evite ao máximo acentos em comentários e em qualquer lugar. Só dá problema.

 

Array::Array()
{
    unsigned bound = 20;
    cout << "\n [1] Digite a quantidade (limite) de numeros que serao ordenados: ";
    cin >> bound;
    cout << endl;
    if (bound < 20) size = bound;
    Array::build_array(bound);
    SortedArray::build_array_sort_number(bound);
};

 

Um construtor interativo é uma coisa meio ingênua. Eu só coloquei assim no exemplo, mas não é boa ideia. O que você faz é usar um parâmetro no construtor com o tamanho da tabela, e ao instanciar (declarar) algo da classe você passa o tamanho... Algo assim:
 

	Array um_array(19);
	Array um_Outro_array(5);

 

é claro mais esperto.

 

Sobre isso:
 

    Array::build_array(bound);
    SortedArray::build_array_sort_number(bound);

 

Não é assim que funciona. Você tem o certo na linha de cima e o errado logo abaixo... Não precisa do prefixo na primeira linha já que só essa classe tem o método. Pode escrever
 

    build_array(bound);
    SortedArray::build_array_sort_number(bound);

 

porque naturalmente build_array() vai atuar no array relativo a essa instância que está construindo, certo?

 

Mas na linha de baixo não vai mesmo compilar porque está chamando um método de outra classe sem atribuir a qualquer instância e isso só funciona para métodos declarados static. Esqueça por enquanto.

 

//Definição do método build_array
void Array::build_array(unsigned bound) {

 

pela mesma razão, sugiro evitar esse tipo de comentário.

 

EXEMPLO

 

 

Usando polimorfismo pode declarar sua classe assim: 
 

class Array
{
public:
    Array(); // cria com 20 zerados
    Array(unsigned short); // o paramentro indica o tamanho

public:
    void    build_array(unsigned); // le do teclado
    void    show_array(string);
    Array   sort_array();
    void    sort_array(unsigned short);

private:
    unsigned short  size;
    short           array[20];

    void            bubble(short[], unsigned short);

};

 

Porque?

  • Assim tem o construtor padrão criando a classe com o vetor zerado
     
  • Se passar um número, como
     
    		Array teste(15);

    vai chamar o construtor que lê os 15 valores
     
  • se chamar sort_array() vai retornar um novo array com os valores na ordem
     
  • se chamar sort_array(n) vai classificar os n primeiros items do vetor. É óbvio que se passar n>=size vai classificar o vetor todo, porque é o que faz sentido.
     
  • bubble_sort() é private e assim pode usar nos dois casos...

 

Um teste: a saída
 

com o construtor sem parametros, zerado
Os 20 numeros:
0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

Digite a quantidade (limite) de numeros no novo vetor: 6

Entre valor 1 de 6 : -1
Entre valor 2 de 6 : -2
Entre valor 3 de 6 : -3
Entre valor 4 de 6 : -4
Entre valor 5 de 6 : -5
Entre valor 6 de 6 : -6

Vetor como digitado
Os 6 numeros:
-1  -2  -3  -4  -5  -6

Vetor novo classificado, criado a partir do original
Os 6 numeros:
-6  -5  -4  -3  -2  -1

o original (inalterado)
Os 6 numeros:
-1  -2  -3  -4  -5  -6


Agora classifica os primeiros 4 elementos do original


Vetor resultante
Os 6 numeros:
-4  -3  -2  -1  -5  -6


Agora classifica o vetor todo


Vetor resultante
Os 6 numeros:
-6  -5  -4  -3  -2  -1

 

Deste programa

 

int main(void)
{
    // (1)
    Array um; // cria com 20, zerados
    um.show_array("com o construtor sem parametros, zerado");

    // (2)
    unsigned short bound = 0;
    cout << "\nDigite a quantidade (limite) de numeros no novo vetor: ";
    cin >> bound;
    cout << endl;
    if (bound > 20) bound = 20;
    Array obj(bound);
    obj.show_array("Vetor como digitado");

    // (3)
    Array outro = obj.sort_array();
    outro.show_array("Vetor novo classificado, criado a partir do original");
    obj.show_array("o original (inalterado)");

    // (4)
    cout << "\n\nAgora classifica os primeiros 4 elementos do original\n\n";
    obj.sort_array(4);
    obj.show_array("Vetor resultante");

    // (5)
    cout << "\n\nAgora classifica o vetor todo\n\n";
    obj.sort_array(4'000);
    obj.show_array("Vetor resultante");
    return 0;
};

 

Acho que assim vai entender o mecanismo...

 

Eis o programa inteiro

 

Spoiler

#include <iostream>
using namespace std;

class Array
{
public:
    Array(); // cria com 20 zerados
    Array(unsigned short N); // cria o array com N

public:
    void    build_array(unsigned short); // le do teclado
    void    show_array(string);
    Array   sort_array();
    void    sort_array(unsigned short);

private:
    unsigned short  size;
    short           array[20];

    void            bubble(short[], unsigned short);

};

int main(void)
{
    // (1)
    Array um; // cria com 20, zerados
    um.show_array("com o construtor sem parametros, zerado");

    // (2)
    unsigned short bound = 0;
    cout << "\nDigite a quantidade (limite) de numeros no novo vetor: ";
    cin >> bound;
    cout << endl;
    if (bound > 20) bound = 20;
    Array obj(bound);
    obj.show_array("Vetor como digitado");

    // (3)
    Array outro = obj.sort_array();
    outro.show_array("Vetor novo classificado, criado a partir do original");
    obj.show_array("o original (inalterado)");

    // (4)
    cout << "\n\nAgora classifica os primeiros 4 elementos do original\n\n";
    obj.sort_array(4);
    obj.show_array("Vetor resultante");

    // (5)
    cout << "\n\nAgora classifica o vetor todo\n\n";
    obj.sort_array(4'000);
    obj.show_array("Vetor resultante");
    return 0;
};

Array::Array()
{
    size = 20;
    for (short i=0; i<20; i+=1)
        array[i] = 0;
};

Array::Array(unsigned short valor) : size(valor)
{
    build_array(valor); // le os valores
};

void        Array::bubble(short V[], unsigned short n)
{
    for (int i = 0; i < n - 1; i++)
        for (int j = 0; j < n - i - 1; j++)
            if (V[j] > V[j + 1])
                std::swap(V[j], V[j + 1]);
    return;
}

void        Array::build_array(unsigned short bound)
{
    size = bound;
    for (unsigned ind = 0; ind < bound; ind += 1)
    {
        cout << "Entre valor " << 1+ind <<
            " de " << bound << " : ";
        cin >> array[ind];
    }
    return;
}

void        Array::show_array(string msg)
{
    if (msg != "") cout << "\n" << msg << "\n";
    cout << "Os " << size << " numeros: " << endl;
    for (unsigned ind = 0; ind < size; ind += 1)
        cout << array[ind] << "  ";
    cout << endl;
    return;
}

void        Array::sort_array(unsigned short n)
{
    if (n > size) n = size; // melhor garantir
    bubble(array, n);
    return;
}

[[nodiscard]]
Array       Array::sort_array()
{
    Array novo;
    novo.size = size;
    for (unsigned short i = 0; i < size; i += 1) novo.array[i] = array[i];
    bubble(novo.array, novo.size);
    return novo;
}

 

 

Entenda que não faz sentido nenhum digitar a classe no mesmo arquivo de main() ou de outras classes: se você faz isso perde a maior vantagem disso tudo, que é poder usar a classe em vários programas...

 

Pergunte sobre o que não entender...

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...