Ir ao conteúdo

arfneto

Membro Pleno
  • Posts

    6.526
  • Cadastrado em

  • Última visita

Tudo que arfneto postou

  1. olá terminou o exercício?
  2. arfneto

    C++ Como herar da base

    Então... Veja suas classes: //HERANCA (CLASSE DERIVADA) class Pai: public Avo{ public: int Idade, Carros, Casas; public: Pai(int i, int car, int cas):Avo(i, car, cas){ }; }; class Filho: public Avo{ public: int Idade, Carros, Casas; public: Filho(int i, int car, int cas):Avo(i, car, cas){ }; }; E o exemplo que te mostrei class Tataravo { public: string nome; public: Tataravo() { nome = "bisavo, nome nao informado"; }; Tataravo(string n) { nome = n; cout << "Criando tataravo: nome=" << nome << endl; }; }; // end class class Bisavo : public Tataravo { public: string pai; public: Bisavo(){nome = "bisavo, nome nao informado";}; Bisavo(string n) : Tataravo(n) { cout << " Criando bisavo: nome=" << n << endl; }; void nome_do_pai(string n) { pai = n; //cout << "nome_do_pai(): pai de [" << nome << "]=[" << n << "]" << endl; }; }; // end class E o que expliquei sobre os construtores e a especialização na derivação de classes? E os construtores? Você continua redeclarando todas as variáveis. Se entendeu o que eu expliquei não entendo porque escreveu assim. Suas classes não estão acrescentando nada e ainda sumindo com o que já tinha. Avo já tinha casas e carros, aí Pai acrescenta outras casas e carros e Filho acrescenta outras casas e carros. Qual o propósito? Compare com o que eu expliquei: você tem a classe Tataravo. Deriva Bisavo e acrescenta public: string pai; void nome_do_pai(string); // setter para o nome do pai E a classe Neto class Neto : public Filho { public: Neto(){ nome = "neto, nome nao informado";}; Neto(string nome) : Filho(nome) { cout << " Criando neto: nome=" << nome << endl; }; }; // end class E esse trecho de programa Neto n("Neto"); n.nome_do_pai(f.nome); cout << "pai de " << n.nome << " = " << n.pai << endl; Que mostra isso Criando tataravo: nome=Neto Criando bisavo: nome=Neto Criando avo: nome=Neto Criando pai: nome=Neto Criando filho: nome=Neto Criando neto: nome=Neto pai de Neto = Pai do Neto Para o programa que eu postei também... Entenda que ao declarar Neto n("Neto"); n é um Neto mas também é tudo que veio antes. Ele já tem um nome, porque é um Tataravo e herdou nome. Ele tem um pai porque é também um Bisavo e herdou dessa classe. E tem um método nome_do_pai() que herdou de Bisavo também. Esse é o mecanismo de Herança. Atente para essas 3 linhas de código e a declaração de Neto
  3. Confiando no seu próprio código você podia ter escrito Lista* lista_imprime_e_copia( Lista* original, Lista* nova ) { Lista* p; int i = 0; for (p = original; p; p = p->prox) { printf("%3d ", p->info); nova = lista_insere(nova, p->info); if (i % 5 == 4) printf("\n"); i += 1; } printf("\n%d itens na lista\n", i); return nova; } Claro que não era pra imprimir mas assim você já vai testando enquanto escreve... Suas funções já funcionam porque criou a lista original e mostrou. Então o código copiado de lista_imprime() e o código que chama lista_insere() deve funcionar. E funciona Esse código // o que podia ser Lista* original = NULL; Lista* copia = NULL; for (int i=1; i<= 9; i++) { original = lista_insere(original, i); } printf("\n\n==> Lista Original:\n"); lista_imprime(original); printf("\n\n==> Mostra e Copia lista original:\n"); copia = lista_imprime_e_copia(original, copia); printf("\n\n==> Lista Copiada:\n"); lista_imprime(copia); lista_libera(original); lista_libera(copia); Usando o que você já escreveu mostra ==> Lista Original: 9 8 7 6 5 4 3 2 1 ==> Mostra e Copia lista original: 9 8 7 6 5 4 3 2 1 9 itens na lista ==> Lista Copiada: 1 2 3 4 5 6 7 8 9 Entenda que sua implementação de lista ainda está longe de seu útil.
  4. não entendi a dúvida. Inverta os números e compare usando um if Sobre o processo veja essa saída porque a gente desconfia... A 734 novoA 7 A 734 novoA 3 A 734 novoA 4 agora que deu certo... A 734 novoA 437 Desse programa #include "stdio.h" int main(int argc, char** argv) { int A; int novoA; A = 734; printf("porque a gente desconfia...\n"); novoA = A / 100; printf("A %d novoA %d\n", A, novoA); novoA = A % 100 / 10; printf("A %d novoA %d\n", A, novoA); novoA = A % 10; printf("A %d novoA %d\n", A, novoA); printf("agora que deu certo...\n"); novoA = (A % 10) * 100 + (A % 100 / 10) * 10 + A / 100; printf("A %d novoA %d\n", A, novoA); return 0; } adicionado 3 minutos depois Essa é a conta afinal
  5. acho que eu sugeri não perder tempo com o loop e a entrada... mas é por aí
  6. realloc() vai usar sempre o mesmo endereço do bloco, então cuide muito desse valor para não mexer com isso em lugar nenhum. Talvez devesse usar uma estrutura de dados mais favorável, como uma lista...
  7. Acho perfeitamente viável. Pode usar um gabinete antigo. Existem acessórios para prender discos de 3.5 nas baias de cima, de 5 1/4 para DVD. São simples espaçadores de metal. Existem também adaptadores de 3.5 para discos de 2,5 também. em geral na minitorre cabem 4 ou 5 discos de 3.5. Pelo consumo uma única fonte adicional estaria ok. Se usa isso em um computador só pode separar os fios de power-on dessa fonte e ligar em paralelo ao botao de power-on de seu computador assim liga e desliga tudo junto para conveniência Note que há muitos gabinetes assim para vender, usando interface USB ou Ethernet, vazios ou com discos Veja esse USB 3.0 em https://www.amazon.com/TerraMaster-D5-300C-Enclosure-Exclusive-Diskless/dp/B06ZY6DK8N?ref_=Oct_MWishedForC_160354011_0&pf_rd_r=830Y2CY9X6679R8YM42K&pf_rd_p=6616413b-1c60-55ef-a1ae-ef9578b5d282&pf_rd_s=merchandised-search-6&pf_rd_t=101&pf_rd_i=160354011&pf_rd_m=ATVPDKIKX0DER por exemplo São chamados de NAS server e uma busca assim https://www.amazon.com/s?k=NAS+server&i=electronics&ref=nb_sb_noss_2 pode te mostrar um grande número deles. É só ligar na rede e usar adicionado 7 minutos depois No manual da fonte tem os pinos certos mas achei esse diagrama online que dá na mesma Em resumo busque o cabo verde e ligue em paralelo no botão de força da outra fonte ou use um outro interruptor para ligar os dois
  8. Olá Acho que não deve perder seu tempo lendo os números ou testando para os 3. Não acrescenta nada. Resolva antes o problema em si. já tem alguns exemplos. Faça isso primeiro. Inverter os números é trivial: o primeiro dígito mais o segundo vezes 10 mais o terceiro vezes 100. Não precisa ler como números, pode ler um a um como letra mesmo. Mas se leu como número: int i = 734; // exemplo int digito1 = i/100; // 7 int digito2 = i%100 / 10; // 34 / 10 = 3 int digito3 = i % 10; // 4 // c = a % b faz c = resto da divisao de a por b (módulo) do ensino fundamental Exemplos para o testa já estão lá /* 734 893 221 231 839 237 */ Teste
  9. Olá! Talvez você não tenha entendido bem o que significa copiar uma lista para outra. E também não tenha definido exatamente o que pretende fazer... Lista* lista_copia (Lista *l, Lista* l2) { int j; Lista *p; Lista* novo = (Lista*) malloc(sizeof(Lista)); for (p = l; p; p = p->prox) { j = p->info; novo->info = j; novo->prox = l2; } return novo; } Um dos elementos da lista é o ponteiro ou os ponteiros para os itens antes ou depois. E tem os dados de cada nó. Sua função que copia a lista pretende copiar a lista toda ou apenas os endereços? Em muitos casos os elementos da lista são enormes, como grandes cadastros de coisas com muitas informações sendo acessadas. Então faz sentido às vezes copiar apenas a lista de ponteiros para, por exemplo, acessar numa ordem específica, como ler um cadastro pela ordem de CEP para programar entregas. Copiando a lista inteira Copiar a lista inteira como operação "atômica" não existe: você copia um por um e põe na lista, e aí poderia derivar direto de sua função que percorre a lista Em lista_imprime() da lista original chame lista_insere() da nova lista. Só isso. Não pode dar errado ou uma das duas já teria dado errado com a lista original... Apenas crie lista_copia(Lista* origem, Lista* destino) igualzinho a lista_imprime(Lista* original) e lá dentro chame lista_insere(Lista* destino).
  10. arfneto

    C++ Como herar da base

    Acho que não leu o que eu escrevi nem rodou o programa que eu mostrei
  11. arfneto

    C++ Como herar da base

    Pelo enunciado já se vê onde esse exemplo se encaixaria melhor: no curso de estruturas de dados. Onde tem vetores, listas e... árvores de toda sorte. Herança em programação orientada a objetos está associada à especialização de classes, não a relacionamentos. Mas pode ser feito, afinal é o enunciado. Tem uma inversão de papéis no título do tópico: Herdar da classe base não é causa e sim consequência. Ao derivar uma classe, como Pai, por exemplo, você torna a classe Pai a classe base para Filho. Note que são só nomes. Você pode derivar Pai de Filho igualmente. É essencial você entender que ao declarar uma classe numa hierarquia de classes derivadas o compilador vai gerar código para chamar TODOS os construtores até a classe base da hierarquia. Explícitos ou não. Variáveis e métodos das classes " acima" continuam disponíveis e você só declara outros quando for vantagem ou necessidade
  12. arfneto

    C++ Como herar da base

    herança múltipla seria o caso de uma classe ser derivada de mais de uma outra Multilevel eu não sei o que é, talvez você pudesse dar uma referência de onde leu isso Ponteiros não tem a ver com classes. Sua lógica vai determinar, quando for declarar uma variável de uma classe, se vai declarar um ponteiro para a classe ou alocar uma instância diretamente, como em Avo pai_da_Claudia; Avo* um_avo; Como sempre sugiro, não use menus e cout e campos diversos enquanto está resolvendo um exercício ou aprendendo um conceito: nada acrescenta ao caso o fato de um avo ter idade e carros. Depois que você entender você agrega essas coisas em minutos. Use um único atributo como int ID; // ou string nome; e implemente a s classes Herança: Quando uma classe é derivada de outra, herdada, herda todos os métodos e atributos.. Se você redeclara todos ela herda, mas não herda nada: some tudo. Você teria que usar artifícios para acessar a idade do pai por exemplo, porque você redefiniu idade para o filho... Pense nisso: herdar é para estender com novos métodos ou campos, ou redefinir métodos importantes. Em java se usa inclusive extends ao invés do ´: ´ que se usa em C++ Não mostrou a questão... Mas entenda que filho é outra relação.Teria que pensar em uma classe que expressasse isso. Esse exemplo de herdar a partir de Pai ou de Adulto ou de Descendente é muito comum nos livros, mas não é nada feliz. Seria melhor ficar com os exemplos de carro ou animal por exemplo Esses sim tem uma derivação que dá pra entender melhor. Minha opinião, de todo modo EXEMPLO Vou te mostrar um programa, cuja saída está abaixo, e que vai ilustrar melhor o que acontece, incluindo aí a chamada dos construtores das classes base. Sugiro ler a saída, ler as classes e talvez rodar o programa em seu micro e ir mudando coisas. É muito importante --- veja a classe Neto ---você entender que C++ vai invocar todos os construtores das classes herdadas, na sequência qualquer variável ou método redeclarado vai " esconder" o que estava na classe base. Eis a saída ----- Tataravo Criando tataravo: nome=Tataravo tataravo Tataravo ----- Bisavo Criando tataravo: nome=Bisavo Criando bisavo: nome=Bisavo Bisavo [Bisavo ] pai de [Bisavo] = [Tataravo] ----- Avo Criando tataravo: nome=Avo Criando bisavo: nome=Avo Criando avo: nome=Avo pai de Avo = Bisavo ----- Pai Criando tataravo: nome=Pai Criando bisavo: nome=Pai Criando avo: nome=Pai Criando pai: nome=Pai pai de Pai = Avo ----- Filho Criando tataravo: nome=Filho Criando bisavo: nome=Filho Criando avo: nome=Filho Criando pai: nome=Filho Criando filho: nome=Filho pai de Filho = Pai ----- Neto Criando tataravo: nome=Neto Criando bisavo: nome=Neto Criando avo: nome=Neto Criando pai: nome=Neto Criando filho: nome=Neto Criando neto: nome=Neto pai de Neto = Filho Agora a classe Tataravo class Tataravo { public: string nome; public: Tataravo() { nome = "bisavo, nome nao informado"; }; Tataravo(string n) { nome = n; cout << "Criando tataravo: nome=" << nome << endl; }; }; // end class ATENÇÃO para a classe Bisavo class Bisavo : public Tataravo { public: string pai; public: Bisavo(){nome = "bisavo, nome nao informado";}; Bisavo(string n) : Tataravo(n) { cout << " Criando bisavo: nome=" << n << endl; }; void nome_do_pai(string n) { pai = n; }; }; // end class NOTE A classe bisavô extende a classe base Tataravo, e acrescenta a variável pai e o método nome_do_pai() com sentido óbvio. Como o Tataravo é o início de tudo, faz sentido inserir essas coisas a partir da segunda geração, certo? e as outras classes? Essas não acrescentam nada no meu exemplo. É só um exemplo rápido afinal. E a ideia não é assim muito boa. Como usa isso? int main() { cout << "----- Tataravo" << endl; Tataravo t("Tataravo"); cout << "tataravo " << t.nome << endl; cout << "----- Bisavo" << endl; Bisavo b("Bisavo"); b.nome_do_pai(t.nome); cout << "Bisavo [" << b.nome << " ]" << endl; cout << "pai de [" << b.nome << "] = [" << b.pai << "]" << endl; cout << "----- Avo" << endl; Avo a("Avo"); a.nome_do_pai(b.nome); cout << "pai de " << a.nome << " = " << a.pai << endl; cout << "----- Pai" << endl; Pai p("Pai"); p.nome_do_pai(a.nome); cout << "pai de " << p.nome << " = " << p.pai << endl; cout << "----- Filho" << endl; Filho f("Filho"); f.nome_do_pai(p.nome); cout << "pai de " << f.nome << " = " << f.pai << endl; cout << "----- Neto" << endl; Neto n("Neto"); n.nome_do_pai(f.nome); cout << "pai de " << n.nome << " = " << n.pai << endl; } Apenas declarei um de cada e defini o nome do pai para ilustrar. Não é nada que faça sentido mas já dá pra você entender o mecanismo imagino. Eis o programa todo #pragma once #include <iostream> using namespace std; class Tataravo { public: string nome; public: Tataravo() { nome = "bisavo, nome nao informado"; }; Tataravo(string n) { nome = n; cout << "Criando tataravo: nome=" << nome << endl; }; }; // end class class Bisavo : public Tataravo { public: string pai; public: Bisavo(){nome = "bisavo, nome nao informado";}; Bisavo(string n) : Tataravo(n) { cout << " Criando bisavo: nome=" << n << endl; }; void nome_do_pai(string n) { pai = n; //cout << "nome_do_pai(): pai de [" << nome << "]=[" << n << "]" << endl; }; }; // end class class Avo : public Bisavo { public: Avo() { nome = "avo, nome nao informado"; }; Avo(string n) : Bisavo(n) { cout << " Criando avo: nome=" << n << endl; }; }; // end class class Pai : public Avo { public: Pai() { nome = "avo, nome nao informado"; }; Pai(string n) : Avo(n) { cout << " Criando pai: nome=" << nome << endl; }; }; // end class class Filho : public Pai { public: Filho() { nome = "filho, nome nao informado"; }; Filho(string nome) : Pai(nome) { cout << " Criando filho: nome=" << nome << endl; }; }; // end class class Neto : public Filho { public: Neto(){ nome = "neto, nome nao informado";}; Neto(string nome) : Filho(nome) { cout << " Criando neto: nome=" << nome << endl; }; }; // end class int main() { cout << "----- Tataravo" << endl; Tataravo t("Tataravo"); cout << "tataravo " << t.nome << endl; cout << "----- Bisavo" << endl; Bisavo b("Bisavo"); b.nome_do_pai(t.nome); cout << "Bisavo [" << b.nome << " ]" << endl; cout << "pai de [" << b.nome << "] = [" << b.pai << "]" << endl; cout << "----- Avo" << endl; Avo a("Avo"); a.nome_do_pai(b.nome); cout << "pai de " << a.nome << " = " << a.pai << endl; cout << "----- Pai" << endl; Pai p("Pai"); p.nome_do_pai(a.nome); cout << "pai de " << p.nome << " = " << p.pai << endl; cout << "----- Filho" << endl; Filho f("Filho"); f.nome_do_pai(p.nome); cout << "pai de " << f.nome << " = " << f.pai << endl; cout << "----- Neto" << endl; Neto n("Neto"); n.nome_do_pai(f.nome); cout << "pai de " << n.nome << " = " << n.pai << endl; } adicionado 5 minutos depois Um exemplo mínimo: cout << "----- Neto" << endl; Neto n("Neto"); n.nome_do_pai("Pai do Neto" ); cout << "pai de " << n.nome << " = " << n.pai << endl; Mostra ----- Neto Criando tataravo: nome=Neto Criando bisavo: nome=Neto Criando avo: nome=Neto Criando pai: nome=Neto Criando filho: nome=Neto Criando neto: nome=Neto pai de Neto = Pai do Neto
  13. Note que apesar de ser um raciocínio correto você não precisa converter nada. Segundo o enunciado são números e não devem estar duplicados na saída. Só isso. Não vai operar com eles. Só vai comparar pra ver se tem outro igual e para isso não precisa converter. Apenas garanta que são dígitos e compare como string. Não perca seu tempo.
  14. Sim, basta ter um computador com memória infinita.Esqueça isso.Seu problema não é esse. Entenda que vai ter que escolher entre C e C++. São linguagens totalmente diferentes. Veja que mostrou um exemplo onde os arquivos tem uns míseros 20 bytes cada um, mas tentou alocar 2 bilhões deles, mais 147 milhões e uns trocados. Não faz sentido. Esse não é por certo o objetivo de seu programa: testar limites da máquina.ou da memória ou os dois. Se for esse me desculpe... Eis o que acho que deve fazer: antes de tudo resolva se vai usar C ou C++ e poste aqui seu enunciado garante que não há duplicatas nos arquivo iniciais? Você precisa saber isso porque se ele não garante e na saída não pode ter você vai ter que programar isso também. Entende? vou imaginar que vai usar C pelo que li do seu código sobre um algoritmo: escolha um dos arquivos leia até o fim e grave em uma estrutura de dados na memória de sua máquina use uma estrutura que permita inserir já em ordem para facilitar buscar duplicatas, como uma lista encadeada ou algo como grupos de vetores feche o arquivo inicial já pode gravar tudo isso no arquivo de saída: o conteúdo do arquivo 1 sem duplicatas. abra o outro e vá lendo a cada número que encontrar verifique se não está já na estrutura que montou com os números do primeiro e se não for uma duplicata grave na saída e insira em sua estrutura Sobre os limites: Rode esse programa em sua máquina e ele vai dizer o tamanho do maior vetor que pode alocar num dado momento. Note que é só um brinquedo. Não serve para muito porque é uma coisa dinâmica e se alocar tudo isso ou perto seu micro vai praticamente parar porque o sistema precisa continuamente de memória pra rodar outras coisas E se seu programa for interrompido até salvar o contexto dele em disco vai levar uma eternidade. E se for um computador compartilhado vocè vai ser culpado por muitos problemas... #include "stdio.h" #include "stdlib.h" int main(int argc, char* argv) { const unsigned long k = 1024; const unsigned long megabyte = 1024 * k; const unsigned long gigabyte = 1024 * megabyte; unsigned long maior_valor = k; // inicia em 1k bytes unsigned long i; unsigned long maxGB = 0; unsigned long maxMB = 0; char* area; printf("Alocando Gigabytes\n"); for (maxGB = 1;; maxGB += 1) { area = (char*)malloc(maxGB*gigabyte); if (area == NULL) { printf("Erro para %ldGB\n", maxGB); maxGB -= 1; break; } else { free(area); } } printf("Sucesso com %d GigaBytes. Adicionando Megabytes\n", maxGB); for (i = 1023;; i -= 1) { int t = maxGB * gigabyte + i * megabyte; area = (char*)malloc(t); if (area == NULL) { continue; } else { free(area); maxMB = i; break; }; // end if }; // end for maior_valor = maxGB * gigabyte + maxMB * megabyte; printf("Sucesso com %d GigaBytes + %ld Megabytes = %ld bytes\n", maxGB, maxMB, maior_valor); printf("Tentando alocar de novo...\n"); area = (char*)malloc(maior_valor); if (area != NULL) { printf("Sucesso!\n"); free(area); } else { printf("ERRO!\n"); }; // end if return 0; } // end main()
  15. listas não tem a ver com programação, estruturada ou não. Que curso está fazendo? Normalmente isso é abordado em cursos de estruturas de dados e em alguns casos não se usam sequer programas, apenas algo tipo um pseudo-código com listas de instruções em linguagem comum. Postei um código completo em C para tratar listas encadeadas " simples" dias atrás. Talvez pudesse baixar esse programa e rodar em sua máquina e te ajude a entender o mecanismo. Em resumo, listas encadeadas são estruturas de dados onde cada elemento tem uma variável que aponta para o próximo, como uma fila em que cada cliente tivesse a sua senha e a senha do próximo. É só isso. Essa nomenclatura de lista simples não é muito feliz. A lista que não é essa " simples" tem um ponteiro para o elemento anterior além de ter um ponteiro para o próximo. Digamos que ela é simples mas de mão dupla. Um ponteiro pode ser simplesmente um índice em um vetor, ou por exemplo pensando no clássico roteiro de um carteiro, ele tem um roteiro de ruas e a cada entrega se preocupa somente com as próximas entregas: uma lista " simples". Essas estruturas tem grande aplicação prática, porque afinal descrevem um grande número de situações práticas.entre outras algoritmos de classificação. E faz sentido: se você está classificando um cadastro enorme por exemplo, pode estar em um dado momento classificando por CPF, em outro por nome, em outro por CEP, dependendo de seu interesse no momento. Então faria sentido por exemplo usar listas encadeadas criando o que você faria talvez num papel: uma lista com ponteiros para frente e para trás e você vai inserindo os valores na posição certa, e acaba com várias listas que apontam para o cadastro original, mas sem mexer no mesmo. O programa que eu postei, por exemplo, tem uma função que insere valores na ordem. Exemplo usado naquele programa: struct lista { Registro* r; struct lista* proximo; }; // Lista typedef struct lista Lista; Essas funções estão implementadas lá: int apaga_registro( int(*)(Registro*, Registro*), Registro*, Lista**); int da_um_fim_na_lista( Lista**); int insere_ao_final( Registro*, Lista**); int insere_na_ordem( int (*)(Registro*, Registro*), Registro*, Lista**); Registro* pesquisa_registro( int(*)(Registro*, Registro*), Registro*, Lista**); int remove_item( Lista*, Lista**); int remove_registro( int(*)(Registro*, Registro*), Registro*, Lista**); Aqui está o programa e tem um botão para download
  16. Confesso que não entendi. O que seria "depois de fechar o exec" ? aí não teria mais programa. Você quer dizer importar possíveis dados já existentes a cada execução?
  17. Entendeu o que escrevi sobre os vetores? Veja esse trecho do código: printf (" | 01 %c | 02%c | 03%c | 04 %c | 05%c | 06%c | 07 %c | 08%c | 09%c | 10%c |\n", vetorx[0] , vetorx[1], vetorx[2], vetorx [3], vetorx[4], vetorx[ 5], vetor x[6], vetorx[7] , vetorx[8], vetorx[9]); printf ("|--------------------------------------------------------------------- |\n"); printf ("| 11 %c | 12%c | 13%c | 14 %c | 15%c | 16%c | 17 %c | 18%c | 19%c | 20%c |\n", vetorx[10], vetorx[11], vetorx[12], vetorx[13], vetorx[14], vetorx[15], vetorx[16], vetorx[17] , vetorx[18], vetorx[19]); printf ("|--------------------------------------------------------------------- |\n"); printf ("| 21 %c | 22%c | 23%c | 24 %c | 25%c | 26%c | 27 %c | 28%c | 29%c | 30%c |\n", vetorx[20], vetorx[21], vetorx[22], vetorx[23], vetorx[24], vetorx[25], vetorx[26], vetorx[27] , vetorx[28], vetorx[29]); Toda a ideia de ter os índices está em usá-los afinal
  18. Deve ter algum caracter estranho fora das strings de seu programa. Só isso. Dependendo do compilador mesmo um único caracter acentuado deixado em u comentário pode ser problema int peca1_disp = 30, peca2_disp = 30, peca3_disp = 30, peca4_disp = 30, peca5_disp = 30, int valor50 = 50; int valor55 = 55; int peca1_disp = 30, peca2_disp = 30, peca3_disp = 30, peca4_disp = 30, peca5_disp = 30, peca6_disp = 30; peca6_disp = 30; int total_int = 0, total_meia = 0, total_gra = 0, total_pub = 0, pretotali = 0, pretotalm = 0, pretotalg = 0, pretotalp = 0; //Declaração dos vetores e seus valores char vetorx[30]; char vetora[30]; char vetorb[30]; char vetorc[30]; char vetord[30]; char vetore[30]; char vetorf[30]; Se você sabe que existem vetores e sabe usá-los, então talvez int peca_disp[6]; char vetor[7][30]; Tornassem seu programa muito mais simples de escrever. Pense nisso. E evite misturar os testes de seu programa e de sua lógica com coisas como menu, cursor, entrada de dados pelo teclado, cor, linha e coluna do cursor e tal. Tudo isso vai atrasar você. Use constantes, pequenas funções para preencher os dados e cosias assim e vai sempre ganhar tempo. Termine o problema e então coloque no menu com todos os artifícios que desejar ou precisar
  19. Como Flávio disse, tente algo assim Veja esse resultado [0][0][0][0][1][1][1][1][2][2][2][2][3] ACAO para a posicao 3 [3][3][3][4][4][4][4][5][5][5][5] Para esse ambicioso programa #include <iostream> using namespace std; void DoAction(int p) { cout << endl << "ACAO para a posicao " << p << endl; } int main() { int posições[] = { 0,0,0,0, 1,1,1,1, 2,2,2,2, 3,3,3,3, 4,4,4,4, 5,5,5,5 }; int aquela = 3; bool rodei = false; for (auto posicao : posições) { cout << "[" << posicao << "]" << flush; if (rodei) continue; if (posicao == aquela) { DoAction(posicao); rodei = true; }; }; return 0; }; // end main() Espero que ajude
  20. main retorna int, não Int. Só isso. Por engano o I está em maiúscula
  21. Quando eu comecei a programar, em um IBM/370-148 usando FORTRAN então não era mesmo época de muitos exemplos
  22. Esse é um forum para iniciantes. Então quando meu tempo admite e a questão também, procuro usar sempre o mesmo roteiro: uma introdução, com um algoritmo ou referências históricas um programa, inteiro, em C ou C++ --- não uso C# --- funcionando em geral com uma demonstração da saída do programa primeiro porque eu acho que faz diferença em relação a umas linhas desconexas de código no caso de quem está de fato com uma dúvida. um link para download do programa e às vezes com alguns arquivos de saída de outros testes quando o tempo admite e faz sentido, discuto ou mostro soluções alternativas às vezes discuto algum pormenor que acho que possa ser um aspecto interessante relacionado à dúvida original Porque? Acho que apenas porque era o que eu gostaria de ter tido a oportunidade de receber quando eu comecei a aprender essas coisas. Uma solução, uma justificativa, um exemplo ou um roteiro. E quem sabe tudo isso junto. E de graça? Nada mal teria sido. Continuo aprendendo e raramente recebo isso, no entanto
  23. Essa recomendação era para o autor do tópico, ou algum leitor eventual. Me desculpe por algo que eu possa ter escrito que te ofendeu @Mauro Britivaldo
  24. @Mauro Britivaldo Talvez não tenha notado o significado do título do tópico: Como fazer uma fila de prioridade Essa é a "lógica das bases" nesse caso, imagino, e daí vem o título do tópico. Isso (fila de prioridade) é um "estudo teórico", mas básico no estudo de estruturas de dados. E é o tópico em questão, como está descrito. Veja umas referências, como esse trabalho de Siang Wun Song para justamente um curso de estrutura de dados de uma escola em SP, aqui ou essa aula em português disponível aqui, aula 24 em português, falando sobre o uso dessas tais filas. É voltado a java mas explica bem o ponto em questão ou essa aula sobre como usar filas de prioridade para classificar dados --- sort --- e como usar isso para escrever o ultra rápido heap sort aqui, uma aula do MIT que está disponível online junto com todo o curso 6.006 de estruturas de dados. Em inglês, infelizmente. De volta ao tópico, @Dcosta7eis um resumo da lógica, como já te mostrei A cada dois clientes sem prioridade você deve atender um prioritário Pode não haver cliente prioritário Pode haver apenas clientes prioritários Pode não ter ninguém pra atender Ao começar o atendimento você marca todas as posições como VAGO. Quando alguém entra na fila é cadastrado na próxima posição livre no vetor, e o status normal ou prioritário. Isso é trivial porque é só preencher o índice do vetor correspondente à senha. Com o status correto. Quando vai haver um atendimento você vê pela ordem dos atendimentos se é hora de buscar alguém com status prioritário. Se tem atende esse e marca lá no vetor como atendido porque pode estar bem adiante na fila, claro. Se não tem ninguém para atender, não faz nada. Se estourou a fila para o atendimento até atender alguém. É a realidade Esse exemplo é um pouco besta, apesar de ser comum: essencialmente essas filas tem dois lados e tem UM PROGRAMA DE CADA LADO e não um menu com as funções para entrar na fila e atender, no mesmo menu. Os usuários chegam e pegam uma senha por exemplo num menu, mas o caixa chama os clientes pelo outro lado. São produtores e consumidores de um mesmo serviço. Escrevi um exemplo que você pode ler aqui São só 3 arquivos, um .h e um .c com as rotinas e um outro com um programa pra testar. Ou pode baixar para rodar em sua máquina. Como te disse antes, essa aproximação de ler dados a cada vez durante os testes é um inferno como já deve ter descoberto e demora demais para rodar até mesmo um único modesto ciclo de testes. Eis o que eu sugiro, e o que eu escrevi ontem: pense em seu menu no meio do caminho entre os caras que chegam e os caras que atendem: são só quatro funções: Entra alguém, com direito a atendimento prioritário Entra alguém, sem direito a atendimento prioritário Atende alguém, seguindo o critério estabelecido Lista a situação: caras na fila, últimas senhas chamadas e tal E para ficar dinâmico tem o tempo que passa. Então escrevi uma rotina que usa as letras NPLA para sinalizar as opções, e um modesto programa de teste que lê uma sequência dessas e executa, e permite que você digite essas sequências direto na linha de comando para não ter que ficar compilando o programa apenas para mudar os dados. Exemplo para o tal programa fila-1.exe (Windows) ou fila-1 (outras plataformas) fila1 LA mostra a situação da fila, que está vazia (L) , e tenta atender alguém com a fila vazia (A) fila1 NNNNPPPPLAAL NNNN mostra a chegada de quatro caras para atendimento normal PPPP quatro caras com atendimento prioritário L mostra o painel de status com a fila e as últimas senhas chamadas (nenhuma) A atende alguém. Lógico que o primeiro a ser atendido deve ser o da fila com atendimento prioritário, certo? Ou tente explicar pra ele que a regra não vale para o primeiro cliente A atende outro cliente, que deve ser o que pegou a primeira senha L mostra o painel depois do segundo atendimento, com duas senhas chamadas e presumimos seis caras na fila ao final do serviço o programa termina então está implicita a função de sair Acho que deu pra entender. Você escreve no terminal lista-1 NNNNPPPPLAAL E o programa roda como se você usse o menu e fizesse essas mesmas opções, gerando dados arrumadinhos conforme o caso. Você roda direto da linha de comando porque é claro como as coisas funcionam: você vai rodar o seu programa em algum lugar, não o seu ambiente de desenvolvimento. Claro, você tem as duas opções, não é obrigado a usar a linha de comando. Não vou dizer que esse modo de fazer é melhor ou pior ou mesmo bom, mas é uma maneira consagrada de desenvolver essas coisas, porque você começa a testar em 15 minutos e vai refinando os resultados Depois que está razoável você começa a empacotar a solução Eis as funções que eu usei aqui, com funções de acordo com os nomes: int ciclo(char servico); int inicia_trabalhos(); int lista(); int marca_senha_painel(int); int move_a_fila(int); int pega_senha(int); E os dados struct cadastro { char nome[50]; int senha; int posicao_na_fila; }; typedef struct cadastro Cadastro; Cadastro cad[CAPACIDADE]; // cada elemento e a fila char fila[CAPACIDADE]; // representa as filas int q_fila_normal; // na fila normal int q_fila_prioridade; // na fila prioridade int q_fila; // todo mundo que esta na fila int ja_atendidos; // ajuda a testar int ultimas_senhas[5]; // o painel superfluo tambem Bem simples como vê. Mas podia ser mais simples. Exemplo de uma execução para o segundo caso NNNNPPPPLAAL ***** iniciando expediente CAPACIDADE=20 CLIENTES ***** ***** Rotina=[LNNNNPPPPLAAL] Capacidade 20 ***** Total de acoes: 13 ---------- ---------- ---------- ---------- Painel Fila Vazia ---------- ---------- ---------- ---------- CADASTRADO 'Jose dos Santos de 2501 Jr.' com senha 501 na fila [Normal] pos=1 CADASTRADO 'Jose dos Santos de 2502 Jr.' com senha 502 na fila [Normal] pos=2 CADASTRADO 'Jose dos Santos de 2503 Jr.' com senha 503 na fila [Normal] pos=3 CADASTRADO 'Jose dos Santos de 2504 Jr.' com senha 504 na fila [Normal] pos=4 CADASTRADO 'Jose dos Santos de 2505 Jr.' com senha 505 na fila [Prioridade] pos=5 CADASTRADO 'Jose dos Santos de 2506 Jr.' com senha 506 na fila [Prioridade] pos=6 CADASTRADO 'Jose dos Santos de 2507 Jr.' com senha 507 na fila [Prioridade] pos=7 CADASTRADO 'Jose dos Santos de 2508 Jr.' com senha 508 na fila [Prioridade] pos=8 ---------- ---------- ---------- ---------- Painel Tamanho da fila:...... 8 Normal:............... 4 Prioritario: ......... 4 Fila (8 clientes): # 1: [Jose dos Santos de 2501 Jr.], Senha 501 [N] # 2: [Jose dos Santos de 2502 Jr.], Senha 502 [N] # 3: [Jose dos Santos de 2503 Jr.], Senha 503 [N] # 4: [Jose dos Santos de 2504 Jr.], Senha 504 [N] # 5: [Jose dos Santos de 2505 Jr.], Senha 505 [P] # 6: [Jose dos Santos de 2506 Jr.], Senha 506 [P] # 7: [Jose dos Santos de 2507 Jr.], Senha 507 [P] # 8: [Jose dos Santos de 2508 Jr.], Senha 508 [P] ---------- ---------- ---------- ---------- ATENDENDO [Jose dos Santos de 2505 Jr.] senha 505 [PRIORIDADE] ATENDENDO [Jose dos Santos de 2501 Jr.] senha 501 [NORMAL] ---------- ---------- ---------- ---------- Painel Tamanho da fila:...... 6 Normal:............... 3 Prioritario: ......... 3 Fila (6 clientes): # 1: [Jose dos Santos de 2502 Jr.], Senha 502 [N] # 2: [Jose dos Santos de 2503 Jr.], Senha 503 [N] # 3: [Jose dos Santos de 2504 Jr.], Senha 504 [N] # 4: [Jose dos Santos de 2506 Jr.], Senha 506 [P] # 5: [Jose dos Santos de 2507 Jr.], Senha 507 [P] # 6: [Jose dos Santos de 2508 Jr.], Senha 508 [P] Ja atendidos: 2. Ultimas 5 senhas chamadas: 501 505 Ultima: 501 ---------- ---------- ---------- ---------- Note que em inicia_trabalhos() e em pega_senha() um cadastro é preenchido com os clientes com nome certinho e senha e tal,, sem que seja preciso perder tempo com isso. main() como seria? int main(int argc, char** argv) { if (argc > 1) // veio algo na linha de comando { inicia_trabalhos(); testa_rotina(argv[1]); return 0; } // end if inicia_trabalhos(); char* rotina = "LNNNNPPPPLAAL"; testa_rotina(rotina); return 0; } // end main() Algo assim atende o caso da linha de comando mas permite que você use dentro do IDE para testar seguidamente atrás de algum problema: basta ir alterando a string rotina E essa testa_rotina? Essa simula o uso do menu e deixa tudo mais ágil int testa_rotina(char* servico) { printf("\n***** Rotina=[%s] Capacidade %d *****\n", servico, CAPACIDADE); int n = strlen(servico); printf("\nTotal de acoes: %d\n\n", n); for (int i = 0; i < n; i++) { ciclo(servico[i]); }; // end for return n; } // end testa_rotina() E a rotina ciclo() simula a passagem do tempo e roda as funções. Veja um trecho de código para um atendimento prioritário por exemplo: case PRIORIDADE: if (q_fila == CAPACIDADE) { printf(" SEM mais senhas. Por favor AGUARDE\n"); return -1; } // end if q_fila += 1; fila[q_fila] = PRIORIDADE; // entra no fim da fila pega_senha(q_fila); printf( " CADASTRADO '%s' com senha %03d na fila [Prioridade] pos=%d\n", cad[q_fila].nome, cad[q_fila].senha, cad[q_fila].posicao_na_fila ); q_fila_prioridade += 1; break; o atendimento é um pouco mais longo mas não tem nem 30 linhas se tirar os milhões de comentários. Estou usando esse programa para um outro propósito, ou mais do mesmo, com um outro pessoal Como exemplo esse trecho abaixo trata o caso de pegar um cara na fila de atendimento prioritário // o inicio da fila pode apontar para um cliente // prioritario que ja foi antendido na sequencia if (q_fila <= 0) { printf(" ATENDIMENTO: Fila Vazia\n"); return 0; } // end if a_atender = SEM_CLIENTE; if (sequencia % 3 == 0) { // vai procurar proximo cliente com prioridade for (int i = 1, pos = i; i <= q_fila;) { if (fila[pos] == PRIORIDADE) { a_atender = pos; // marca pra chamar esse break; // sai do loop: achou } else { if (fila[pos] == LIVRE) continue; // nao tem cliente i = i + 1; // tem cliente aqui } // end if pos = pos + 1; } // end for } // end if Não vou comentar o código todo. Se se interessou pode perguntar qualquer coisa. O programa está lá no link. Espero que ajude. E espero que entenda a diferença de escrever um programa com isso em mente: estrutura de dados, rotina de testes, geração de dados de amostra e tal. Demora muito menos. Não é minha ideia. E onde iria com isso para colocar o menu e os dados? Simples: o cliente vai criar uma entrada de cadastro usando o menu, você pega uma senha e conforme ele tenha ou não prioridade você chama ciclo() com a função certa. O cadastro ele já preencheu, a senha ele já pegou chamando a função pega_senha() e a fila anda com a chamada de um próximo ciclo(). Ele usou a opção listar? Ou atender? Basta colocar um N P L ou A no ciclo... Espero que ajude.
  25. Entendam que não vai dar problema simplesmente porque um é o inverso do outro, e o inverso do inverso é a identidade Ou em termos coloquiais o contrário do contrário dá do mesmo. No caso do exemplo acima podia se acrescentar a esses int minha_matriz [10]; scanf (" %d" , &minha_matriz [0]); /* É comum e difuso em livros e blogs */ scanf (" %d" , &*minha_matriz ); /* É ~comum, porém são a mesma coisa */ o simples: scanf (" %d" , minha_matriz ); /* o simples, lembrando que para o %d scanf() espera um endereco como argumento correspondente e entao o leitor tem que supor que minha_matriz seja algum tipo de ponteiro. Essa e a razao dos autores e profissionais escreverem muitas vezes &minha_matriz[0]: so para ficar mais claro. E esse uso pode impactar no tempo de execucao */ Autores e profissionais muitas vezes escrevem &minha_matriz[0] apenas para deixar claro o que é a variável, no caso minha_matriz, sem que o leitor tenha que ir até a declaração, que nem sempre está na linha de cima... Ao escrever &matriz[0] assim se entende que matriz é int[] e é uma boa coisa pra quem está lendo. Ao escrever só matriz fica algo vago e pode levar o leitor a ir até a declaração e perder um tempo. Escrever &* por outro lado é como escrever x*x/x ao invés de x. Veja esse resultado matriz[0]=27102019 [m = &*matriz] m=27102019 [m = &*matriz] m=27102019 [m = &matriz[0] m=27102019 [m = &*&*&*&*&*&*&*&*&*&*&*&*&*&*matriz] m=27102019 [m = &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*matriz] m=27102019 [m =[100 pares de &*] m=27102019 mostrado por esse programa #include <stdio.h> int main(int argc, char** argv) { int matriz[10]; matriz[0] = 27102019; printf("\nmatriz[0]=%d\n", matriz[0]); int* m = &*matriz; printf("\n[m = &*matriz] m=%d\n", *m); m = matriz; printf("\n[m = &*matriz] m=%d\n", *m); m = &matriz[0]; printf("\n[m = &matriz[0] m=%d\n", *m); m = &*&*&*&*&*&*&*&*&*&*&*&*&*&*matriz; printf("\n[m = &*&*&*&*&*&*&*&*&*&*&*&*&*&*matriz] m=%d\n", *m); m = &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*matriz; printf("\n[m = &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*matriz] m=%d\n", *m); m = &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*\ &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*\ &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*\ &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*\ &*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*\ matriz; printf("\n[m =[100 pares de &*] m=%d\n", *m); return 0; } Acho que deu pra entender. Não é uma maneira exótica de escrever, é só uma possibilidade sem razão. O inverso de & é * O inverso de * é & O inverso de * pode ser também / e muitos criticam C por essa ambiguidade. Assim nesse código int x = 22; printf("\nx=%d\n", x); x = x / x * x; printf("x=%d\n", x); x = x / x * x / x * x; printf("x=%d\n", x); x = x / x * x / x * x / x * x / x * x; printf("x=%d\n", x); Todos os printf() mostram 22. No caso de matriz vs. &matriz[0] faz diferença? Sim. Veja o código gerado por um compilador moderno com opções padrão de geração de código, nesse caso Microsoft Visual Studio 16.3.6, para essas linhas de exemplo E vai ver que o otimizador percebe os pares &* e descarta, mas para o caso de &matriz[0] ele gera o dobro de instruções, instruções similares, e assim vai levar o dobro de tempo para executar essas atribuições do exemplo Minha sugestão: em resumo, esqueça isso. Só é divertido.

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...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!