Ir ao conteúdo

arfneto

Membro Pleno
  • Posts

    6.526
  • Cadastrado em

  • Última visita

Tudo que arfneto postou

  1. Os princípios do que escrevi não são ideia minha mas sim práticas recomendadas --- ou determinadas--- por quem está pagando ou ensinando --- há décadas. Mas no geral levam a mais resultado em menos tempo. Evite usar funções que retornam void: em geral é no mínimo um desperdício e muitas vezes um erro mesmo. Em geral esses erros vem de você ter copiado código de outro editor. São caracteres de controle que estão no meio do texto. Edite antes com o bloco de notas no Windows por exemplo. E aí veja se aparece algo estranho. E para tirar dúvidas faça o simples: redigite uma linha e veja se o erro some.
  2. ? ama - r - elo ímpar
  3. Ex:para a string ovo → o programa deve imprimir a letra v Ex: para a string andré → o programa deve imprimir a letra d Ex: para a string jose → o programa deve imprimir as letras os Ex: para a string amarelo → o programa deve imprimir as letras ar Talvez deva rever seu exemplo no caso "amarelo"... Pode usar um trecho assim, usando substr() que retorna uma substring de comprimento L a partir da posição P na string original: string substr (size_t P, size_t L) const; size_t é um inteiro positivo. Mas pode usar int. E escrever string str = "teste"; int inicio = 0; int total = 0; if (str.size() == 0) return 0; if (str.size() % 2 == 1) { inicio = str.length() / 2; total = 1; // impar } else { inicio = str.length() / 2 - 1; total = 2; // par }; cout << "String: '" << str << "'\tTamanho: " << str.length() << "\tMeio: '" << str.substr(inicio, total) << "'\n"; Que iria mostrar String: 'teste' Tamanho: 5 Meio: 's' Talvez não possa usar outras funções, já que fica um pouco sem propósito usar substr() e esse seria o equivalente string saida = ""; int len = str.length(); if (len > 0) { if (len % 2 == 1) saida += str[len/2]; else { saida += str[(len / 2) - 1]; saida += str[(len / 2)]; }; cout << "String: '" << str << "'\tTamanho: " << len << "\tMeio: '" << saida << "'\n"; }; // if return 0; Do modo C++ de ser, pode considerar pegar a classe string e criar uma função meio() --- historicamente se chama método em C++ ao invés de função --- e escrever algo assim class StringNova : public std::string { public: string meio() { if (size() == 0) return ""; if (size() % 2 == 1) return substr(size() / 2, 1); else return substr((size() / 2) - 1, 2); }; StringNova() : string(""){}; StringNova(const char* s) : string(s){}; }; Isso se chama estender a classe string, e StringNova é dita derivada de string. E aí pode escrever só StringNova valor{ "teste" }; cout << "String: '" << valor << "' \tTamanho: " << valor.length() << "\tMeio: '" << valor.meio() << "'\n"; Porque valor já tem o método meio() então é só chamar valor.meio() Um teste com as 3 opções Que ia mostrar 3x a mesma coisa String: 'teste' Tamanho: 5 Meio: 's' String: 'teste' Tamanho: 5 Meio: 's' String: 'teste' Tamanho: 5 Meio: 's' @devair1010 veja nos exemplos que quando a string de entrada tem comprimento par você tem que retorna DUAS letras.
  4. int letra(int k) { int letra [27]; int j = 65; for(in ...... Porque acha que o problema é no return? Você declarou letra como char[27]. Só que também é int(), já que é o nome da função. Como o compilador vai tratar isso?
  5. Talvez você pudesse postar um código compilável e uma descrição mais precisa do erro
  6. Em geral um menu oferece umas opções ao usuário, lê um valor de resposta e devolve para a aplicação tratar. Muitos sistemas tem isso integrado. O Windows pode ter um menu associado a qualquer janela. E o menu pode ter teclas associadas a certas funções, atalhos. O DOS tinha um menu de erro integrado clássico: mostrava uma mensagem e as opções: Abort, Retry, Ignore? Então você pode usar uma função, na mesma linha do post anterior. Pode ser algo simples ou complexo. Muitas vezes, por flexibilidade, o menu é lido do disco. Ou de um arquivo especial, como XML ou .ini como nos anos 90. A ideia é evitar que seja preciso compilar o programa só porque mudou o menu, por exemplo. O menu clássico para os programas de estudo em C é algo como vou mostrar abaixo, mas também pode ser uma tabela de funções que associa direto a opção do menu com a resposta, eliminando o processo de seleção que geralmente é uma série de if ou um switch Eis uma função dessas, com o código do seu programa: int menu() { int ch = 0; // para ler a linha toda int op = -1; int invalida = 1; // so 0 eh falso system("cls"); while( invalida ) { printf("\n\nMenu:\n\n"); printf("1 - Inserir um Novo Cadastro\n"); printf("2 - Mostrar todos os cadastros\n"); printf("0 - Encerrar\n"); printf("\nDigite a opção desejada: "); scanf(" %d", &op); while (((ch = fgetc(stdin)) != '\n') && (!feof(stdin))); invalida = (op < 0) || (op > 2); // 0 1 2 validos //if(invalida){}; // opcao invalida } while (invalida); return op; } A lógica resolve o que você queria: a função retorna um int que é a opção digitada o loop é até conseguir uma opção válida. Mostra "todo" o menu de novo porque não achei relevante tratar só a leitura. É só um exemplo afinal. Depois da leitura, se a opção não for válida, tem um if() onde você pode inserir o código para tratar o caso de opção inválida, e está comentado. o loop while (((ch = fgetc(stdin)) != '\n') && (!feof(stdin))); serve para ler todos os caracteres até o fim da linha, para evitar que interfiram na sequência do programa. É uma maneira portável e mais segura que fflush(stdin) que como eu expliquei não é definida para arquivos de entrada.E sua finalidade é outra. De volta ao programa, copiei seu código para essas funções int inserir_livro(Livro*, Acervo*); Livro le_um_livro(); int menu(); int mostra_obras(Acervo*); E isso torna a vida bem mais simples. mostra_obras(Acervo*); Nesse caso se pode passar apenas o endereço da variável que tem o acervo, de modo que fica fácil por exemplo usar várias coleções de livros no mesmo programa, e dentro do acervo já tem o total de livros. E se precisar mudar o formato dos livros ou do layout na tela não precisa mudar nada nos argumentos. Isso é ago como o conceito de encapsulamento, presente em outras linguagens como java e C++ int inserir_livro(Livro*, Acervo*); Nesse caso tem o sentido usual, inserir um livro no acervo. A vantagem é passar o endereço de um Livro de de um Acervo, assim funciona sem ter que mudar nada se mudar o layout da estrutura de livro ou do acervo, para coisas como mudar o acervo para usar alocação dinâmica ou incluir novos campos no livro, como o código ISBN por exemplo Veja uma implementação como pode ser simples: int inserir_livro(Livro* livro, Acervo* ficha) { // ficha.N tem a primeira posicao livre printf("Acervo com %d de %d obras\n\n", ficha->N + 1, _TAM_); if (ficha->N == _TAM_) return -1; // acervo lotado ficha->obra[ficha->N] = *livro; ficha->N += 1; return 0; }; // inserir_livro(); Assim é muito mais seguro e flexível do que ler todos os livros dentro do loop em main() com os campos e os printf() todos misturados à lógica do programa. E assim se isola a lógica e dados, um modelo comum de programação e que leva a menos erros e mais flexibilidade na manutenção. E como a estrutura já tem dentro dela o total de livros em uso e o vetor de Livro, e a capacidade é nesse exemplo uma constante global, falta só o livro mesmo. E ele vem como parâmetro então é o que basta. Livro le_um_livro() Para que isso? A razão é separar inserir_livro() de ler um livro a partir do teclado, porque assim fica mais fácil de testar o programa e terminar tudo. Na prática não se usaria assim: le_um_livro() iria alocar memória e cria uma estrutura Livro e retornar o endereço. E na hora de inserir no acervo essa memória seria liberada. Mas não quero complicar isso agora. Apenas quero mostrar a maneira de escrever o código de modo iterativo e seguro Exemplo: criando uns Livro: Livro exemplo = { 0, "Autor exemplo", "Titulo exemplo", "Editora exemplo" }; for (int i = 0; i < _TAM_ - 2; i += 1) { // insere uns livros exemplo.codigo = 1000 + i; inserir_livro(&exemplo, &loja); }; // for() Esse trecho de programa criar livros no acervo, deixando apenas 2 livres para testar o programa. Colocando isso no início do programa já dá pra testar com o cadastro quase cheio. Sem digitar nada. Um loop de teste Com o seu código, ligeiramente alterado while ( (op = menu()) != _op_sair_) { switch (op) { case _op_insere_: um_livro = le_um_livro(); inserir_livro(&um_livro, &loja); break; case _op_mostra_: mostra_obras(&loja); break; default: break; }; } // while() return (0); O que mudou? o loop chama o menu e pega a opção digitada, em op. O switch() trata a opção. Ao receber a opção sair o programa termina. Nada mais. Só que lendo o código assim já dá pra entender o que faz. E se precisar mudar algo muda só nas funções, que podem estar em outros arquivos ou a cargo de outros caras. E não precisa mudar nada em main(). O mesmo vale para se precisar mudar o menu. Se acrescentar opções apenas se inclui aí a opção nova. Totalmente redundante mas usei uns #define #define _op_insere_ 1 #define _op_mostra_ 2 #define _op_sair_ 0 para as opções porque assim não é preciso criar uma tabela mental que p0$$@ de comando é 1 ou 2 ou opção 8 ou sei lá Veja o código para inserir como é simples: um_livro = le_um_livro(); inserir_livro(&um_livro, &loja); Lê um livro do teclado e insere em seguida. Se resolver ler os livros de outro jeito já tem um ponto exato onde alterar as cosias. É mais produtivo assim. O programa de exemplo co,mpleto Não é um modelo de nada. É só um exemplo de como pode resolver esse tipo de problema de um modo mecânico e seguro.
  7. A console do windows também pode ser acessada em pixel, e você pode "desenhar" qualquer fonte nela. Usando a janela no modo texto não. Pode mudar a fonte dinamicamente, acho que já postei isso, mas afeta todos os caracteres. Eles não ficam em bytes. O que está gravado lá --- CONSOLE_SCREEN_BUFFER_INFOEX e não o que está em CONSOLE_FONT_INFOEX --- são os caracteres e seus atributos, em vetores separados. Por padrão tem 9001 linhas de buffer. Mas não são os bytes que formam os caracteres. São a representação deles, o código. O que vai ser mostrado é a fonte e fica em outro lugar. Pode acessar a partir de HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts no registro eu acho. Você pode acessar a memória diretamente. apenas o acesso é controlado, de modo a garantir a segurança dos processos e a estabilidade do sistema. Em geral você não tem acesso a espaço de endereçamento de outros processos. Não. Trata-se da mesma coisa. Um vetor em seu processo é só isso: uma área de memória a partir de um endereço.
  8. Nem tão velho para aprender Tem razão. Escreva seu programa sempre em torno dos dados. Isso vai te levar a entender melhor o programa, antes mesmo de começar a escrever código. Entenda que os exercícios típicos para iniciantes e os problemas típicos para profissionais não são assim muito variados. São abstrações de problemas práticos e não tem muito o que mudar. Um relatório pode ser sintético ou analítico, envolver dinheiro ou genes e será um relatório. Um balanço é um balanço. Dados são assim, informação e estrutura. De volta ao seu programa: Você tem essa estrutura typedef struct { int codigo; char autor[20]; char titulo[20]; char editora[20]; } Livro; Eu diminui os tamanhos em relação ao seu programa original por uma razão que vai ficar clara a seguir: vou te mostrar uma alteração no seu código como exemplo do que eu estou te falando. Mas pode esquecer em seguida se não achar importante, claro. Como está começando agora com essas coisas deve ser uma boa hora para ver isso, antes de contrair as manias típicas dos autores e professores. Entenda que seus dados não são exatamente o Livro. Usei uma convenção como vê acima, um typedef que é uma definição de tipo em que você dá um nome para a estrutura e depois pode declarar coisas como Livro um; Livro loja[10]; Livro* ponteiro_para_livro; E assim fica mais fácil de ler. E não precisa repetir o tal struct a toda hora. Mas entenda que você trabalha com uma coleção de livros. E tem que saber quantos tem. E tem um máximo de livros. Então algo assim typedef struct { int N; Livro obra[_TAM_]; } Acervo; Seria bem representativo de seu problema: um acervo é o seu material de trabalho nesse enunciado. Na prática se usaria algo assim typedef struct { int capacidade; int total; Livro** obras; } Acervo; E teria tudo aí dentro: o MAX de Livro, o total atualizado e um ponteiro para um vetor de obras. No futuro vai usar assim porque aí fica mais flexível: pode ter um número qualquer de obras alocadas dinamicamente. Para esse programa não é importante. Escreva funções A essa altura já deve ter aprendido que você pode pegar blocos de código e dar um nome e passar uns argumentos e isso é uma função. Uma função em C sempre retorna algo e você deve usar isso. Em geral é um desperdício e muitas vezes um erro não retornar nada. Existe um tipo, void, que é para sinalizar esse "nada". Evite usar. Escreva vários programas Ninguém vai te culpar por escrever seu programa aos poucos. Em especial se ele ficar pronto em 30 minutos. Mas se você escrever um grande programa de 3.000 linhas e que funciona bem ainda assim vão te culpar se levou a semana toda pra fazer. Ou o mês todo. Use dados de teste e não leia nada do teclado Não use menus ou leia do teclado antes de ter a lógica pronta e testada. Só vai perder seu tempo. Exemplo Você está tratando os tais livros. Acho que já entendeu que é mais simples tratar a coleção de livros. Isso se chama container em C++ ou coleção em java, mas a ídéia é a mesma: juntar as coisas embaixo de um nome só, com propriedades e código se possível. Em C é muito fácil declarar e inicializar estruturas: Esse exemplo typedef struct { int codigo; char autor[20]; char titulo[20]; char editora[20]; } Livro; typedef struct { int N; Livro obra[_TAM_]; } Acervo; Declarando e preenchendo uma estrutura com 5 livros Acervo loja = { .N = 5, // teste com 5 livros .obra[0] = { 1, "Autor 1", "Titulo34343 4", "Editora 34"}, .obra[1] = { .codigo = 324, .autor = "autor 324", .titulo = "titulo 434434", .editora = "editora para 324" }, .obra[2] = { 1002, "Autor 1002", "Titulo34343 4", "Editora 34"}, .obra[3] = { 1003, "Autor 1003", "Titulo34343 4", "Editora 34"}, .obra[4] = { 1004, "Autor 1004", "Titulo34343 4", "Editora 34"} }; Acho que aqui já entendeu como é mais produtivo. Você pode colocar os valores na sequência em que foi declarado, ou colocar valores nos campos pelo nome, mesmo que seja um vetor, como é o caso dos N livros aqui. E não precisa nem preencher todos. A função mostra() A primeira função que você escreve para TODOS esses programas de cadastros e listas e estruturas de dados é a que mostra os dados na tela um a um. Algo assim int mostra_obras(Acervo* ficha) { system("cls"); printf("\n\nAcervo com %d de %d obras\n\n", ficha->N, _TAM_); printf("%10s %20s %20s %20s\n\n", "Codigo", "Autor", "Titulo", "Editora"); for (int i = 0; i < ficha->N; i++) printf("%10d %20s %20s %20s\n\n", ficha->obra[i].codigo, ficha->obra[i].autor, ficha->obra[i].titulo, ficha->obra[i].editora); printf("\nTecle ENTER para retornar "); fgetc(stdin); return 0; }; // mostra_obras() A função recebe um ponteiro para um Acervo, onde tem N Livro, e mostra um a um na tela. Então já pode escrever um programa que junta a declaração e essa função. Como mostrar os dados sem perder tempo Usando o próprio editor do IDE você digita um gabarito: codigo autor titulo editora 0123456789 01234567890123456789 01234567890123456789 01234567890123456789 0123456789 01234567890123456789 01234567890123456789 01234567890123456789 0123456789 01234567890123456789 01234567890123456789 01234567890123456789 0123456789 01234567890123456789 01234567890123456789 01234567890123456789 E aí copia direto para o código". Veja esses comandos printf("%10s %20s %20s %20s\n\n", "Codigo", "Autor", "Titulo", "Editora"); for (int i = 0; i < ficha->N; i++) printf("%10d %20s %20s %20s\n\n", E já sabe que vai sair tudo alinhado. Eis o "programa" int main() { Acervo loja = { .N = 5, // teste com 5 livros .obra[0] = { 1, "Autor 1", "Titulo34343 4", "Editora 34"}, .obra[1] = { .codigo = 324, .autor = "autor 324", .titulo = "titulo 434434", .editora = "editora para 324" }, .obra[2] = { 1002, "Autor 1002", "Titulo34343 4", "Editora 34"}, .obra[3] = { 1003, "Autor 1003", "Titulo34343 4", "Editora 34"}, .obra[4] = { 1004, "Autor 1004", "Titulo34343 4", "Editora 34"} }; mostra_obras(&loja); return (0); }; // main() Só tem uma linha. Veja o que sai na tela: De volta ao seu programa Seu programa não está muito bom. Em especial já deve ter revisto e entendido que: faltam os índices quando você tenta acessar ficha em seu programa o programa está muito longo e difícil de ler pela falta de funções a leitura tem problemas pelo uso de scanf() para ler do teclado. Em alguns casos ficam letras a serem consumidas do teclado e interferem na leitura dos próximos campos fflush() de stdin não está definido e não devia ser usado. fflush() só se aplica a arquivos de saída. scanf() retorna um valor, um int. E você não está tratando. Só que esse int diz quantos valores foram lidos e você às vezes queria ler um e não lê nenhum. Como não testa seu programa segue adiante... E aí já era. Confirme se entendeu e eu posto o resto do seu programa, reorganizado. @devair1010 Escrever as letras em 5x5 com um vetor assim talvez seja muito trabalhoso para o resultado. Voltando aos anos 80 e às impressoras matriciais e com um olho no Windows veja essa tela Está usando caracteres monospace, claro, todos com a mesma largura. A fonte Courier New é dessa época das impressoras matriciais. Veja na tela do Windows que as letras tem 10x18 pixels. Muitas das impressoras tinham 9 agulhas e imprimiam as letras em 7x9 pontos. Talvez tivesse melhor resultado imitando isso. que é do tempo em que conio.h era novidade. E pode usar um alfabeto menor e desenhar menos símbolos, como apenas os dígitos e as maiúsculas e alguma pontuação. E gravar o alfabeto todo em um vetor já inicializado com o próprio código da letra, mais uma vez imitando o que se fazia nos '80: as impressoras é que tinham as letras. Você só mandava o código. Teve uma discussão aqui sobre como embutir código assim em variáveis semanas atrás. E fica muito rápido.No fundo é um vetor em que cada posição é um vetor de "agulhas" que mostra os pontos que vão estar "acesos" para desenhar a letra. E o código da letra é o índice no vetor. Era como a gente fazia nas impressoras. No firmware.
  9. É como está escrito. Somando o que está acima e o que está abaixo virtual std::string EmitirSom()=0; virtual std::string ExecutarAcao()=0; uma classe abstrata é como um protótipo, uma base para criação de outras classes. Se você declara métodos como pure virtual então não faria sentido declarar instâncias dessa classe. Como o compilador iria tratar Animal::EmitirSom() afinal? No entanto struct Descendente : public Animal { public: virtual std::string EmitirSom() {}; virtual std::string ExecutarAcao() {}; }; int main(void) { Descendente todosAnimais[10]; return 0; }; Vai rodar sem problemas. E faz sentido.
  10. Isso pode sair errado. As configurações do IDE. Não pensei no mais simples.
  11. O programa não parece ter nenhum problema, mas só traça uma linha. Vermelha, como previsto. Ainda não entendo o que podem ser executáveis que somem. O que você mudou? E a função SetPixel() tem só 2 comandos. O que pode sair errado?
  12. ? Isso não acontece. Poste um código desses.
  13. typedef struct no { Cliente info; struct no* prox; } Lista; Uma lista não é um nó. Declarar uma como tal só vai complicar o programa. No entanto parece que é o comum. Veja uma alternativa comum --- ou como eu acho que devia ser comum --- de uma implementação de lista, com os protótipos a seguir: struct no { void* item; struct no* proxima; struct no* anterior; }; // no typedef struct no Node; struct a_propria_lista { char* nome; unsigned quantos; unsigned maximo; Node* inicio; Node* fim; }; typedef struct a_propria_lista Lista; Lista* apagar(Lista*); Lista* criar(const char*); int define_maximo(Lista* l, const unsigned); Lista* inserir_na_ordem(void*, Lista*, int(*)(void*, void*)); Lista* inserir_no_inicio(void*, Lista*); Lista* inserir_no_final(void*, Lista*); int listar(Lista*); int listar_do_seu_jeito(Lista*, int(*)(void*)); int maximo(Lista*); Node* primeiro(Lista*); Lista* remover(void*, Lista*); int tamanho(Lista*); Node* ultimo(Lista*); int vazia(Lista*); Comparando: - a estrutura Lista tem uma série de Nodes. Mas também tem uns contadores e até um nome. Então quando você declara algo como Lista* lista = criar("Minha primeira lista"); você tem já os ponteiros pro início e fim, mais um limite pro número de nodes, um contador do total atual e tal. Já pode chamar funções como tamanho(), vazia(), ultimo() e listar() e tudo anda. - Como a Lista é de Nodes o único ponteiro que você usa fora da Lista no programa todo é para a Lista. Tudo fica mais fácil. - Como o Node tem apenas um void* item; a sua Lista funciona para qualquer coisa. Não precisa sequer compilar lista.c para usar a lista. Pode só deixar compilado e ir usando até achar um erro um dia. De volta ao seu programa Talvez devesse usar Lista* nos parâmetros e não Lista** e retornar os endereços, como no exemplo acima. Mas como fez vai funcionar também. A primeira função que deve escrever é a que lista os elementos, na tela. Uma função de teste. Antes mesmo de escrever a lista. Precisar ter uma referência pra testar afinal void Listar(Lista** lista); Depois declare a função void Apagar(Cliente cliente, Lista** lista); E copie a implementação dela da implementação de Listar() porque é a mesma. Para apagar você tem que navegar pela lista e achar o Node correto. A mesma coisa que faz ao listar os elementos. Só que quando acha o elemento a apagar você acerta os ponteiros: antes dele pode ter alguém, depois dele pode ter alguém. Então você corrige os ponteiros: o que vem antes dele passa a apontar para o que vem depois. E o que vem depois passa a apontar para o que vinha antes. E aí você apaga o cara e libera a memória correspondente. E cuida dos casos particulares de não ter sucessor ou não predecessor ou não ter nenhum dos dois.
  14. Isso quer dizer que você não tem acesso ao programa fonte do loader e não foi você que escreveu?
  15. Ainda não deu certo... Você precisa mostrar os 15 caras ao final para provar que guardou os valores direito... adicionado 7 minutos depois Fica pouco claro escrever assim if( i ){ if(numeros[i] > numeros[i-1]) crescente++; else if(numeros[i] < numeros[i-1]) decrescente++; } É um efeito colateral de só poder comparar a partir do segundo. Fica mais claro ler o primeiro antes e iterar a partir do segundo explicitamente. E você pode declarar o indexador dentro do próprio for.
  16. @devair1010 pode ser que o autor tenha abreviado o enunciado, mas só o que tem lá é isso: ordenado ou não. Nada diz sobre estar em ordem decrescente. if( crescente && ! decrescente ) printf("O Vetor eh , Crescente !"); else if( decrescente && ! crescente ) printf("O Vetor eh , Decrescente !"); else if( ! crescente && ! decrescente ) Está certo de que isso faz sentido? As duas condições são irreversíveis. E o fato de serem eventualmente todos iguais é irrelevante. Ex: 31 2 3 2 3 4 5 6 7 8 9 10 11 11 11 Depois de 3 números já se sabe que não estão nem ordem crescente nem decrescente. E o contrário do contrário é a identidade... Não dá pra ser os dois então A e NOT A não devem ser possíveis... Não precisa somar em crescente E decrescente: basta mudar o valor uma única vez.
  17. Ao que parece você deve ler altura e sexo de 5 pessoas e calcular esses valores aí acima. maior altura e menor altura por sexo total de mulheres alguma media? Não está no código alturaM, alturaH? Não está no código Verifique o enunciado e crie uma simples classe, Conjunto, e na criação leia os valores e calcule tudo.
  18. Não há assim um "algoritmo" propriamente aqui. São dois objetivos: salvar os 15 números em um vetor, e o algoritmo é usar um contador para colocar um depois do outro nas posições do vetor. "imprimir uma mensagem informando se os números estão em ordem crescente ou não" nada tem a ver com o vetor: é uma coisa transiente: se o vetor está em ordem crescente quer dizer que em nenhum momento durante a leitura apareceu um cara menor que o anterior. Só isso. Então não precisa classificar o vetor ou de loops ou técnicas sofisticadas: a partir do segundo cara --- porque precisa de dois para comparar --- você vai comparando o anterior com o número que acaba de ler. Se o número novo for menor que o anterior já tem sua resposta e ela não vai mudar. Se o segundo número for menor que o primeiro é o que basta: não estão em ordem crescente. então você simplesmente marca em algum lugar, uma variável: int menor = 0; por exemplo. E se encontrar um elemento maior que anterior você faz menor = 1; só isso. Ao final da leitura os 15 elementos estão no vetor, então você mostra os 15 para provar que guardou. E se menor for zero quer dizer que estão em ordem crescente. Nada mais
  19. Não, não resolveu. Isso é basicamente fazer o que faria com a string. Mas sem usar string. Digitando os números um a um ao invés de separar os dígitos na string usando o índice. É muito apelativo fazer com que o usuário entre com um dígito por vez... Ler como string é mais simples e intuitivo. E sempre inverte e reverte ok. E tem um outro problema: Se f(x) é inversível então f( f(x) ) = x para todo x. Escrevendo isso em C Se sua função é int inverte_r(int); Então (inverte_r(inverte_r(i)) == i) // para todo i. De todo modo essa acho que é a solução comum do modo como quer fazer: int inverte_d(int in) { int out = 0; while (in > 0) { out = 10 * out + in % 10; in = in / 10; }; return out; } E essa é a mais cult: int inverte_r(int v) { static int i = 0; if (v <= 0) { v = i; i = 0; return v; }; // if() i = (10 * i) + (v % 10); return inverte_r(v / 10); }; Para qualquer i. Tanto faz ter 3 dígitos. Considerando o fato de só ter 3 dígitos pode escrever o óbvio: int inverte_3(int in) { if (in > 99) return (in / 100) + ((in % 100) / 10) * 10 + (in % 10) * 100; if (in > 9) return (in % 10 * 10) + (in /10); return in; }; E as 3 funcionam igual Mas apesar de inverter não vai ser mesmo reversível para esses números: [010 001] [020 002] [030 003] [040 004] [050 005] [060 006] [070 007] [080 008] [090 009] [100 001] [110 011] [120 021] [130 031] [140 041] [150 051] [160 061] [170 071] [180 081] [190 091] [200 002] [210 012] [220 022] [230 032] [240 042] [250 052] [260 062] [270 072] [280 082] [290 092] [300 003] [310 013] [320 023] [330 033] [340 043] [350 053] [360 063] [370 073] [380 083] [390 093] [400 004] [410 014] [420 024] [430 034] [440 044] [450 054] [460 064] [470 074] [480 084] [490 094] [500 005] [510 015] [520 025] [530 035] [540 045] [550 055] [560 065] [570 075] [580 085] [590 095] [600 006] [610 016] [620 026] [630 036] [640 046] [650 056] [660 066] [670 076] [680 086] [690 096] [700 007] [710 017] [720 027] [730 037] [740 047] [750 057] [760 067] [770 077] [780 087] [790 097] [800 008] [810 018] [820 028] [830 038] [840 048] [850 058] [860 068] [870 078] [880 088] [890 098] [900 009] [910 019] [920 029] [930 039] [940 049] [950 059] [960 069] [970 079] [980 089] [990 099] Porque no sistema posicional tem o elemento neutro então onde tem um zero à esquerda vai falhar. 820 vira 28 mas 28 vira 82... Um programa de teste em C que mostra os valores que não são inversíveis e compara os resultados das 3 funções:
  20. coisas da semana passada? Não sei se entendi Eis o que eu particularmente sugeri lá: O programa não está ok. Mas não muito bom de ler, rodar ou jogar. Do ponto de vista da interface, é muito chato digitar linha e coluna se só tem 9 casinhas na tela. Podia por exemplo mostrar apenas algo como | X | O | X | | 4 | 5 | 6 | | 7 | O | 9 | E o cara digita o número da célula que quer. Linha e Coluna é exagero. O programa está difícil de ler com aquela matriz de duas dimensões e aqueles IF gigantes. Se só são dois jogadores porque não usar uma matriz para cada um? Fica mais fácil de identificar vitoria e pode ficar mais fácil de ler o programa... E quando um ganha o outro perde afinal. E pouco eficiente: só existem essas 8 combinações decisivas, as 3 linhas e as 3 colunas e as duas diagonais. Então pode usar constantes já na compilação e comparar com valores fixos.
  21. Isso foi discutido nesse forum na semana passada. Acho que tem várias sugestões lá. Por exemplo em
  22. Poste o enunciado. Fica mais fácil de te ajudar adicionado 57 minutos depois Veja essa função de exemplo int mostra(int vet[], int n) { int col = 0; printf("\n vetor - - - - - - - - - - \n"); printf("\n %d elementos:\n\n", n); for (int i = 0; i < n; i += 1) { printf("%5d", vet[i]); col += 1; if (col % 10 == 0) printf("\n"); }; // for() if (col % 10 != 0) printf("\n"); printf("\n - - - - - - - - - - fim \n"); printf("\n"); // pula linha em branco no fim return 0; }; // mostra() Ela imprime um vetor de inteiros. Só isso. Comece por isso. Seus dados. Veja como chamar em main() int main(void) { int vetor[10] = { 1,2,3,4,5,6,7,8,9,9 }; int outro[10] = { 2,3,4,5,6,5,4,3,2,2 }; int cem[100]; for (int i = 0; i <100; i += 1) cem[i] = 100 - i; mostra(vetor, 10); mostra(outro, 5); mostra(cem, 100); mostra(cem, 1); }; // main() Tem 3 vetores. Mais que o necessário para testar seus 3 algoritmos. Veja o terceiro, o vetor 100: os números estão em ordem decrescente, só pra dar uma canseira nos sort depois que funcionar com os dois primeiros. 10 minutos, sem menu, sem opções, sem interação com o usuário. Comece assim. Repare que você pode chamar mostra() com 1 só mesmo que o vetor tenha 500.000 itens. Muitos programas de sort falham quando o vetor só tem 1, então teste Veja o que sai na tela vetor - - - - - - - - - - 10 elementos: 1 2 3 4 5 6 7 8 9 9 - - - - - - - - - - fim vetor - - - - - - - - - - 5 elementos: 2 3 4 5 6 - - - - - - - - - - fim vetor - - - - - - - - - - 100 elementos: 100 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 - - - - - - - - - - fim vetor - - - - - - - - - - 1 elementos: 100 - - - - - - - - - - fim Sobre suas funções de sort void bubble_sort(int[],int); void insertionSortC(int[],int); void insertionSortD(int[],int); int mostra(int[], int); void selecao(int[],int); Não é esperto usar duas funções só porque mudou a ordem de comparação... Passe um parâmetro apenas, que nesse caso bem simples pode ser só 'C' ou 'D' pra não mudar nada. void insertionSort(int[],int,char); Entenda (e rode) esse programa #include <stdlib.h> #include <stdio.h> int mostra(int[],int); void bubble_sort(int[],int); void insertionSortC(int[],int); void insertionSortD(int[],int); int mostra(int[], int); void selecao(int[],int); int main(void) { int vetor[10] = { 1,2,3,4,5,6,7,8,9,9 }; int outro[10] = { 2,3,4,5,6,5,4,3,2,2 }; int cem[100]; for (int i = 0; i <100; i += 1) cem[i] = 100 - i; mostra(vetor, 10); mostra(outro, 5); mostra(cem, 100); mostra(cem, 1); }; // main() void bubble_sort(int vet[], int max) {}; void insertionSortC(int array[], int tamanho) {}; void insertionSortD(int array[], int tamanho) {}; int mostra(int vet[], int n) { int col = 0; printf("\n vetor - - - - - - - - - - \n"); printf("\n %d elementos:\n\n", n); for (int i = 0; i < n; i += 1) { printf("%5d", vet[i]); col += 1; if (col % 10 == 0) printf("\n"); }; // for() if (col % 10 != 0) printf("\n"); printf("\n - - - - - - - - - - fim \n"); printf("\n"); // pula linha em branco no fim return 0; }; // mostra() void selecao(int vet[], int n) {}; // https://www.clubedohardware.com.br/forums/topic/ // 1477816-algoritmos-de-ordena%C3%A7%C3%A3o-em-c/?tab=comments#comment-7908237 Entenda que o programa já tem até as funções de sort. Vazias, mas estão lá. Isso quer dizer que pode ir testando JÁ escrevendo os códigos de cada uma e chamando em main. E usando um vetor para cada função porque ele volta em ordem. Usando RECORTAR e COLAR e testando tudo já int main(void) { int vetor1[10] = { 1,2,3,4,5,6,7,8,9,9 }; int vetor2[10] = { 1,2,3,4,5,6,7,8,9,9 }; int vetor3[10] = { 1,2,3,4,5,6,7,8,9,9 }; mostra(vetor1, 10); bubble_sort(vetor1, 10); mostra(vetor1, 10); mostra(vetor2, 10); insertionSortC(vetor2, 10); mostra(vetor2, 10); mostra(vetor3, 10); selecao(vetor3, 10); mostra(vetor3, 10); }; // main() Você tem 3 vetores. Vai ver antes e depois de classificado. É todo o seu problema. DEPOIS você cria um menu, um switch()... Isso não acrescenta nada ao problema. Só ao tempo que demora pra escrever. Não tem sentido você ler do teclado os vetores a cada teste. Entende como é diferente?
  23. Seu programa está incrivelmente complicado. Não há razão para tal. Vai levar uma vida pra arrumar isso e não creio que compense. Considere: NUNCA faça um programa desses interativo, com menus e leituras no meio do processamento. Só vai perder tempo. Não tem o menor sentido ler os valores do vetor do teclado. Você não postou o enunciado, mas a menos que tal enunciado exija não faça isso nem depois que o programa estiver rodando certo. Ou você lê de um arquivo, facinho porque você digita no IDE com control C e control V, ou usa números aleatórios ou põe já em ordem mesmo com um loop. Você não é obrigado a fazer um programa só. Ninguém vai saber se forem vários. Sistemas modernos tem facilmente centenas de programas. Faça um programa que apenas crie e preencha um vetor de um certo tamanho. Só isso. Está usando um vetor de inteiros então pode ser algo muito simples crie uma função que mostra o vetor, com uns 10 caras por linha pra ficar fácil. Você vai precisar de uma função assim pra testar afinal. escreva as funções que classificam o vetor, uma a uma e teste com a sua função que mostra o vetor antes e depois E aí escreva esse menu e termine isso em meia hora a mais. Escreva seu programa em torno dos dados. Não escreva nada a toa. Comece pelos dados. Acha que sabe começar assim?
  24. foi mal. São 3 parâmetros. Tem um boolean TRUE se a informação pedida é para a maior janela possível ou para o tamanho da janela atual. Isso porque a fonte tem um tamanho fixo e a janela pode mudar durante o uso do programa. Muita gente por exemplo tem a mania infeliz de maximizar a janela do programa. Qualquer programa. Window ao invés de Windows, mesmo que a janela seja só uma calculadora. E o programa muitas vezes precisa saber se a janela mudou de tamanho... adicionado 1 minuto depois posso te ajudar. Provavelmente é o que importa. adicionado 2 minutos depois Então ensine ao destinatário o que fazer com um programa. Onde rodar um programa de console. E não é no IDE por certo.
  25. Fiquei confuso agora. O programa em geral não é compilado por outra pessoa. A "outra pessoa" paga pelo programa e o recebe. Recebe o programa. Quando uma pessoa escreve um enunciado descrevendo o programa esperado e o recebe uns arquivos aí é escola. Em geral na máquina em que roda o programa não tem compiladores, IDE, linker, essas coisas. Programas são arquivos executáveis. São executados. Se dão erro o autor fica sabendo. Pode ser multado, perder um contrato, um emprego, ficar sem nota, ficar sem aquele ponto extra O que estou tentado explicar é que um programa de console precisa levantar o ambiente em que está rodando, no início, e se garantir de que não vá usar um recurso que não tem na máquina em que ele está rodando, tipo Unicode ou uma fonte especial para escrever em grego. E na saída precisa deixar tudo como achou porque não "está em sua casa". Se a pessoa que vai receber o programa só sabe rodar o programa a partir de um IDE ou de um compilador aí temos uma inversão de papéis mesmo: nunca achei que as escolas poderiam gerar pessoas que só sabem rodar um programa compilando o código de novo. Não, não é. Achou complicado identificar a fonte da console mesmo eu tento te mostrado o código, que é um simples formulário, e que é apenas colocar dados em uma estrutura padrão cujos campos o windows já te mostra certinho e depois chamar uma função de dois parâmetros, o endereço da janela e a própria estrutura? E que retorna zero se deu certo?

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!