Ir ao conteúdo

arfneto

Membro Pleno
  • Posts

    6.526
  • Cadastrado em

  • Última visita

Tudo que arfneto postou

  1. Sim. Apenas isso desde os anos 80 Você incluiu windows.h?....
  2. Eu me lembrei de uma discussão sobre algo assim aqui meses atrás e na ocasião eu postei um programa que implementa uma fila de prioridade e alimenta um painel de atendimento de uma clínica médica, onde mostra as tais últimas 5 senhas e a senha sendo atendida e simula a fila com prioridade para os idosos numa clínica. É esse seu caso e basta acrescentar mais umas prioridades e funções. Só que as funções são dadas por uma letra e as letras são tratadas num switch que já está lá. E a engine do programa é baseada numa função chamada ciclo() que pode ou não ser alimentada por um menu... Acho que deu pra entender: deve ser muito simples usar para sua simulação. Sugiro ler o programa que está em https://github.com/ARFNeto-CH/ch-191026-filapq e tem lá um botão de download do projeto pronto. São 3 arquivos só eu acho. Pense em seu programa e veja main() desse outro como é similar: int main(int argc, char** argv) { // // opcao: rodar com 'fila rotina' // por exemplo 'fila NNNNPPPPLA' // sao NPLA para // N - entra cliente normal // P - entra cliente com prioridade de atendimento // L - lista a situacao // A - tenta atender alguem // // cad letra indica uma acao para nao ter que ficar usando o menu // if( argc > 1 ) // veio algo na linha de comando { inicia_trabalhos(); testa_rotina(argv[1]); return 0; } // end if inicia_trabalhos(); //char* rotina = "LNNNNNNNLAAAAAAALPPPAAAL"; //char* rotina = "LNNNPAALALAL"; //char* rotina = "LNNNNPPPPLAAAAAAAL"; char* rotina = "LNNNNPPPPLAAAAAAAPPPPLAAALAL"; //char* rotina = "A"; testa_rotina(rotina); return 0; } // end main() E veja sua tabela de eventos E a rotina ciclo() no programa: int ciclo(char servico) { switch (servico) { case ATENDE: break; case NORMAL: break; case PRIORIDADE: break; case LISTA: break; case LIVRE: default: break; } // end switch return 0; } // end ciclo() Se você acrescenta suas funções no menu basta colocar no switch() e o ciclo() faz acontecer. O engine é baseado numa sequência de serviços que entram em uma simples string e podem vir do menu ou de qualquer lugar. O programa até aceita as rotinas de teste direto na linha de comando. E o programa tem até um gerador de dados que você pode adaptar para gerar eventos de todos os tipos que precisa, no automático. 5 ou 500 ou 50.000. Em relação ao menu postei um programa para ajudar alguém dias atrás e ele lê e grava arquivos em disco, e tem um menu. Só que o menu também vem do disco então é muito rápido de implementar, porque na verdade já está pronto: basta digitar o texto do menu num editor e colocar as opções no switch(). Nada mais. Está em https://github.com/ARFNeto-CH/chc-200402play Estive pensando e juntando isso é praticamente seu programa. A saída é até parecida já. Apenas coloque seus eventos. Veja uma sequência de atendimento no programa inicial ***** iniciando expediente CAPACIDADE=6 CLIENTES ***** ***** Rotina=[LNNNNPPPPLAAAAAAAPPPPLAAALAL] ***** Total de acoes: 28 ---------- ---------- ---------- ---------- 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 SEM mais senhas. Por favor AGUARDE SEM mais senhas. Por favor AGUARDE ---------- ---------- ---------- ---------- Painel Tamanho da fila:...... 6 Normal:............... 4 Prioritario: ......... 2 Fila (6 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] ---------- ---------- ---------- ---------- ATENDENDO [Jose dos Santos de 2505 Jr.] senha 505 [PRIORIDADE] ATENDENDO [Jose dos Santos de 2501 Jr.] senha 501 [NORMAL] ATENDENDO [Jose dos Santos de 2502 Jr.] senha 502 [NORMAL] ATENDENDO [Jose dos Santos de 2506 Jr.] senha 506 [PRIORIDADE] ATENDENDO [Jose dos Santos de 2503 Jr.] senha 503 [NORMAL] ATENDENDO [Jose dos Santos de 2504 Jr.] senha 504 [NORMAL] ATENDIMENTO: Fila Vazia CADASTRADO 'Jose dos Santos de 2507 Jr.' com senha 507 na fila [Prioridade] pos=1 CADASTRADO 'Jose dos Santos de 2508 Jr.' com senha 508 na fila [Prioridade] pos=2 CADASTRADO 'Jose dos Santos de 2509 Jr.' com senha 509 na fila [Prioridade] pos=3 CADASTRADO 'Jose dos Santos de 2510 Jr.' com senha 510 na fila [Prioridade] pos=4 ---------- ---------- ---------- ---------- Painel Tamanho da fila:...... 4 Normal:............... 0 Prioritario: ......... 4 Fila (4 clientes): # 1: [Jose dos Santos de 2507 Jr.], Senha 507 [P] # 2: [Jose dos Santos de 2508 Jr.], Senha 508 [P] # 3: [Jose dos Santos de 2509 Jr.], Senha 509 [P] # 4: [Jose dos Santos de 2510 Jr.], Senha 510 [P] Ja atendidos: 6. Ultimas 5 senhas chamadas: 504 503 506 502 501 Ultima: 504 ---------- ---------- ---------- ---------- ATENDENDO [Jose dos Santos de 2507 Jr.] senha 507 [PRIORIDADE] ATENDENDO [Jose dos Santos de 2508 Jr.] senha 508 [PRIORIDADE] ATENDENDO [Jose dos Santos de 2509 Jr.] senha 509 [PRIORIDADE] ---------- ---------- ---------- ---------- Painel Tamanho da fila:...... 1 Normal:............... 0 Prioritario: ......... 1 Fila (1 clientes): # 1: [Jose dos Santos de 2510 Jr.], Senha 510 [P] Ja atendidos: 9. Ultimas 5 senhas chamadas: 509 508 507 504 503 Ultima: 509 ---------- ---------- ---------- ---------- ATENDENDO [Jose dos Santos de 2510 Jr.] senha 510 [PRIORIDADE] ---------- ---------- ---------- ---------- Painel Fila Vazia Ja atendidos: 10. Ultimas 5 senhas chamadas: 510 509 508 507 504 Ultima: 510 ---------- ---------- ---------- ---------- Parte de uma simples string com a rotina de serviço, que podia ser a sua, ou podia vir do menu porque dá na mesma char* rotina = "LNNNNPPPPLAAAAAAAPPPPLAAALAL"; ou da linha de comando mesmo. Se não entendeu ainda o paradigma eis um exemplo chegam 6 clientes com prioridade normal e 3 com alta prioridade lista a fila e vai ver os 9 atende 5. deve ver as senhas sendo chamadas e os caras com atendimento prioritário vão ser atendidos na ordem lista a fila e vai ver os 4 que sobraram atende os 4 lista a fila e vai estar vazia Para esse teste você poderia usar porque NNNPPPNNNLAAAAALAAAAL Direto na linha de comando se seu programa se chamasse p q . E poderia testar vários cenários sem voltar ao programa a menos que ache um erro... Se você colocar suas ações ao invés dessas seu simulador vai rodar facinho. E pode pegar o menu do outro programa que também roda normal, e EDITAR o texto. Sem printf() nem nada. Só ler as opções e implementar as ações.
  3. Filas de Prioridade não são exatamente filas. Se for buscar exemplos procure de acordo com o seu caso. Eu li o enunciado apesar de você ter postado um link apenas. O mais meigo do enunciado é o primeiro parágrafo: Onde basicamente diz que o conceito de fila é essencial para desenvolver aplicações que modelam... filas! E simula situações reais! Situações onde um atendimento é modelado. Faz sentido afinal é uma aplicação que modela uma fila Adorei Mas o enunciado me pareceu muito melhor formulado do que se costuma ver. Oferece exemplos e estruturas de dados e várias sugestões importantes. Muito bom exceto pelo divertido primeiro parágrafo. Você precisa de uma fila de prioridade estável --- stable Priority Queue --- e a estrutura mais parecida com isso é uma chamada Heap e não a lista ligada que se usa para implementar filas em geral. E é dita estável porque tem que preservar a ordem de entrada: transações com prioridades iguais tem que ser atendidas na ordem. Está no enunciado. Claro que se for usar uma fila comum implementada em listas apenas pode ter que usar um hack na fila para implementar a saída conforme a ordem E a prioridade.
  4. Essa é uma situação simplificável e gera o mesmo código. Entenda as duas condições: NOT ( A || B ) NOT A && NOT B Para avaliar a primeira você tem que avaliar A e B primeiro e depois inverter. Isso pode significar por exemplo chamar funções presentes em B, mas tem que ser feito porque é um OR e só depois vai invertido. Para avaliar a segunda você avalia a primeira e apenas se ela for falsa avalia a segunda e só vai avaliar B se A for verdadeiro.
  5. Muito bom que tem um livro texto. Pena que não conseguiu por as mãos nele. Em geral as universidades assinam serviços de biblioteca virtual, e os alunos recebem um código de acesso e podem ler livros no modo digital Sua escola não tem isso será? Você mesma pode assinar serviços como o Safari Books Online em https://www.oreilly.com/ que provavelmente é o maior do mundo
  6. Não. Não precisa. Eu te expliquei porque mais de uma vez. E com exemplos. E te mostrei um programa que lê e grava e disco suas estruturas. E um programa com menu. E te expliquei como desenvolver e testar isso, que já estava uns 80% pronto naqueles dias. Faça um programa para ler e gravar apenas um cara e vai ver o que está errado, se acha que tem que seguir esse caminho. Pode postar ele aqui se não funcionar.
  7. Wow No popular, entrega para amanhã. E são dez da noite. O que já fez? Esse é o primeiro trabalho? ED1-Trab01? Não pode postar aqui o troço para que a gente não tenha que fazer um download e abrir em outro programa para depois voltar aqui e tentar ajudar?
  8. até significa afinal: o número de euler elevado ao produto da taxa de crescimento multiplicada pelo tempo, e isso multiplicado pela população inicial. Mas não estava escrito completamente em português ou em matemática. Eu espero ter acertado a fórmula afinal. E agradeço aos caras do site que tem o trem online pra gente usar. Mas eis o que eu não entendo: se você vai calcular todas as 100 primeiras gerações a taxa de crescimento sendo constante não pode simplesmente multiplicar a cada geração? Entendo que rapidamente o valor vai convergir para a fórmula (na verdade o contrário), mas a fórmula existe para quando se quer calcular direto para a geração 822 por exemplo. Para calcular de 1 em 1 não faz sentido usar a fórmula. Para 10000 caras e uma taxa de 0.01 vamos ter para as primeiras 3 gerações 1 10000 2 10100 3 10201 4 10303 E a fórmula vai dar 1 10000 2 10100 3 10202 4 10304 Devido a arredondamento nas tabelas de logaritmos. De todo modo a fórmula em C++ pode ser escrita em uma linha só struct lib { static int populacao(int Nz, double r, int t) { return (int)(Nz * exp(r*t)); }; }; Algo assim já serviria. Mas uma função lambda seria mais legível até auto pop = [](int Nz, double r, int t) { return (int)(Nz * exp(r * t)); }; Sim. Só uma linha. E já que estamos usando computadores, seria legal comparar os valores da tabela, já que eu disse que eles provavelmente vão convergir logo, e programas são pra isso mesmo. Veja as primeiras gerações para uma população de 10.000 e uma taxa de 1% positiva e negativa e os resultados de um programa. Sim, o programa vem depois. 10.000 a 1% Numero de individuos: 10000 Taxa de crescimento: 0.01 Populacao Inicial: 10000 Taxa de Crescimento: 0.01 t = 0 N = 10000 t = 1 N = 10100 via Funcao: 10100 ou Lambda: 10100 t = 2 N = 10201 via Funcao: 10202 ou Lambda: 10202 t = 3 N = 10303 via Funcao: 10304 ou Lambda: 10304 t = 4 N = 10406 via Funcao: 10408 ou Lambda: 10408 t = 5 N = 10510 via Funcao: 10512 ou Lambda: 10512 t = 6 N = 10615 via Funcao: 10618 ou Lambda: 10618 t = 7 N = 10721 via Funcao: 10725 ou Lambda: 10725 t = 8 N = 10828 via Funcao: 10832 ou Lambda: 10832 t = 9 N = 10936 via Funcao: 10941 ou Lambda: 10941 t = 10 N = 11045 via Funcao: 11051 ou Lambda: 11051 t = 11 N = 11155 via Funcao: 11162 ou Lambda: 11162 t = 12 N = 11266 via Funcao: 11274 ou Lambda: 11274 t = 13 N = 11378 via Funcao: 11388 ou Lambda: 11388 t = 14 N = 11491 via Funcao: 11502 ou Lambda: 11502 t = 15 N = 11605 via Funcao: 11618 ou Lambda: 11618 t = 16 N = 11721 via Funcao: 11735 ou Lambda: 11735 t = 17 N = 11838 via Funcao: 11853 ou Lambda: 11853 t = 18 N = 11956 via Funcao: 11972 ou Lambda: 11972 t = 19 N = 12075 via Funcao: 12092 ou Lambda: 12092 10.000 a -1% Numero de individuos: 10000 Taxa de crescimento: -0.01 Populacao Inicial: 10000 Taxa de Crescimento: -0.01 t = 0 N = 10000 t = 1 N = 9900 via Funcao: 9900 ou Lambda: 9900 t = 2 N = 9801 via Funcao: 9801 ou Lambda: 9801 t = 3 N = 9703 via Funcao: 9704 ou Lambda: 9704 t = 4 N = 9606 via Funcao: 9607 ou Lambda: 9607 t = 5 N = 9510 via Funcao: 9512 ou Lambda: 9512 t = 6 N = 9415 via Funcao: 9417 ou Lambda: 9417 t = 7 N = 9321 via Funcao: 9323 ou Lambda: 9323 t = 8 N = 9228 via Funcao: 9231 ou Lambda: 9231 t = 9 N = 9136 via Funcao: 9139 ou Lambda: 9139 t = 10 N = 9045 via Funcao: 9048 ou Lambda: 9048 t = 11 N = 8955 via Funcao: 8958 ou Lambda: 8958 t = 12 N = 8866 via Funcao: 8869 ou Lambda: 8869 t = 13 N = 8778 via Funcao: 8780 ou Lambda: 8780 t = 14 N = 8691 via Funcao: 8693 ou Lambda: 8693 t = 15 N = 8605 via Funcao: 8607 ou Lambda: 8607 t = 16 N = 8519 via Funcao: 8521 ou Lambda: 8521 t = 17 N = 8434 via Funcao: 8436 ou Lambda: 8436 t = 18 N = 8350 via Funcao: 8352 ou Lambda: 8352 t = 19 N = 8267 via Funcao: 8269 ou Lambda: 8269 E o programa #include <iomanip> #include <iostream> #include <math.h> using namespace std; struct lib { static int populacao(int Nz, double r, int t) { return (int)(Nz * exp(r*t)); }; }; auto pop = [](int Nz, double r, int t) { return (int)(Nz * exp(r * t)); }; int main() { double r; int Nzero = 0; cout << "Numero de individuos: " << flush; cin >> Nzero; cout << "Taxa de crescimento: " << flush; cin >> r; cout << "Populacao Inicial: " << Nzero << endl; cout << "Taxa de Crescimento: " << r << endl; int t = 0; // tempo inicial int v = Nzero; // populacao inicial cout << "t = " << t << " N = " << (int)v << endl; for (t = 1; t < 20; t += 1) { v = v + (int)(v * r); cout << "t = " << setw(4) << t << "\tN = " << setw(8) << (int)v << " via Funcao: " << setw(8) << lib::populacao(Nzero, r, t) << " ou Lambda: " << setw(8) << pop(Nzero, r, t) << endl; }; // for() return 0; } Note que isso vai dar overflow rapidinho para taxas grandes... Convém testar a progressão. Está usando int Use exp() não pow() assim vai conseguir uma precisão muito maior. Se for um trabalho de escola então... use mesmo adicionado 11 minutos depois Se alguém ficou curioso, a fórmula em MathML <!DOCTYPE html> <html lang="en"> <head> </head> <body> <p> <math xmlns="http://www.w3.org/1998/Math/MathML"> <mi>N</mi> <mo>=</mo> <msub> <mi>N</mi> <mn>0</mn> </msub> <msup> <mi>e</mi> <mn>rt</mn> </msup> </math> <BR><BR> onde <BR><BR> <mi>N</mi> <mo>= </mo> <mtext>população atual</mtext> <BR> <math xmlns="http://www.w3.org/1998/Math/MathML"> <msub> <mi>N</mi> <mn>0</mn> </msub> <mo>=</mo> <mtext>população inicial</mtext> </math> <BR> <math xmlns="http://www.w3.org/1998/Math/MathML"> <mi>e</mi> </msub> <mo>=</mo> <mtext>número de Euler</mtext> </math> <BR> <math xmlns="http://www.w3.org/1998/Math/MathML"> <mi>r</mi> <mo>=</mo> <mtext>taxa de crescimento</mtext> </math> <BR> <math xmlns="http://www.w3.org/1998/Math/MathML"> <mi>t</mi> <mo>=</mo> <mtext>tempo em alguma unidade</mtext> </math> </p> </body> </html> Pode salvar como html e abrir em qualquer navegador adicionado 20 minutos depois O Edge é mais exigente: precisaria ter colocado o encoding Como sofrem os caras que escrevem para web ...
  9. Você poderia ter escrito algo assim: onde 'e' é o numero de Euler. Ele é conhecido assim vou revisar a fórmula Acertei afinal?
  10. A notação para uma constante char em C é 'c' e não "c" que indicaria uma coisa do tipo const char* e seria um endereço na memória onde estariam um 'c' e um 0, um depois do outro. Mas seu problema é de lógica. A condição (a OU b) é verdade se a ou b forem verdade. Você está testando se algo é diferente de 'm' OU diferente de 'f'. Pense bem: Sempre vai ser verdade. Pode avaliar como descrito aqui O mais eficiente no entanto é escrever while ( (c != 'm') && (c != 'f') ) A razão é que testar por igual ou diferente dá na mesma em termos de custo. É uma instrução só. Mas usando ! (NOT) você sempre vai fazer uma inversão, depois de fazer um ou dois testes. No segundo caso você faz apenas 1 ou dois testes
  11. Em tempo, eis uma possibilidade usando uma implementação muito mínima de pilha, apenas para mostrar a ideia de inversão de sentido que é o que acontece quando a gente pega uma pilha de coisas e troca de lugar uma a uma... O programa mostra Entrada: Qualquer Coisa Entrada: 'Qualquer Coisa' Coloca na pilha letra a letra Tira da pilha e poe na string de saida Saida: 'asioC reuqlauQ' Eis o código #include <stdio.h> #include <stdlib.h> #include "string.h" #define _P_LIMITE 256 const int p_limite = _P_LIMITE; int p_topo = 0; char p_pilha[_P_LIMITE]; int p_pop(); // tira da pilha int p_push(char); // poe na pilha int main() { char entrada[32]; char saida[31]; printf("\nEntrada: "); fgets(entrada, 30, stdin); char limite = (char) strlen(entrada) - 1; entrada[limite] = 0; printf("\nEntrada: '%s'\n", entrada); printf("Coloca na pilha letra a letra\n"); // coloca na pilha os valores for (int i = 0; i < limite; i += 1) p_push(entrada[i]); char c = 0; // agora tira da pilha e poe na saida // e eles vão estar invertidos printf("\nTira da pilha e poe na string de saida\n"); saida[limite] = 0; // termina a string de saida no mesmo tamanho char indice_saida = 0; while ((c = p_pop()) > 0) { saida[indice_saida] = c; indice_saida += 1; }; printf("Saida: '%s'\n", saida); return 0; }; // main() int p_pop() { if (p_topo <= 0) return -1; char v = p_pilha[p_topo - 1]; p_topo = p_topo - 1; return v; }; // p_pop() int p_push(char v) { if (p_topo > p_limite) return -1; p_pilha[p_topo] = v; p_topo = p_topo + 1; return p_topo; }; // p_push() usando os nomes clássicos push() e pop() para colocar e retirar da tal pilha
  12. Faz sentido já que morreu todo mundo A notação não ficou muito boa no enunciado poderia ser Se eu entendi direito. Em https://www.tutorialspoint.com/online_mathml_editor.php tem um editor de MathML online onde você pode digitar as coisas e copiar o resultado, enquanto o editor do forum aqui não chega a esse nível. É divertido. Seu programa deve ser uma função com um único loop... Vou te mostrar um exemplo adicionado 3 minutos depois Entendo. Não use pow num loop ou vai variar justamente na potência. Apenas multiplique pela base a cada loop. E quando e se morrer todo mundo continue mostrando zero... Acho que a fórmula é n * (r^t) e não como eu escrevi quando estava brincando de MathML adicionado 4 minutos depois Algo assim
  13. Faz sentido. Mas eu não consegui entender isso do enunciado. Ainda não consigo. Não vejo onde está sequer sugerido que a string deva ser a mesma. Não está escrito que a "string invertida deva ser a mesma". Esse é um exercício muito comum para iniciantes e o objetivo normal é se tentar avaliar a capacidade do cara de usar um índice para a esquerda e um para a direita ao mesmo tempo. Ou de usar uma pilha quando no contexto de estrutura de dados. Vai encontrar esse exercício quase certamente em uma apostila de exercícios sobre pilhas por exemplo. Mas aí dizendo claramente: "use uma estrutura de pilha para inverter...." Parece que não leu o que que escrevi no mesmo parágrafo, aquela parte onde está escrito "Se fossem 2 funções"... Eu não escrevi sobre as funções para criticar o que você disse: só mostrei, com exemplos e citando na da menos que a biblioteca padrão, porque não retornar void e espero que entenda como tal. Você também entendeu que era para escrever 2 programas e foi você citou inicialmente "retornar void". Tem razão. Mas o que retornar é uma questão de formar um hábito, porque escrever funções não é algo que se faz pouco em C. E quando o cara está começando existe a tendência dos instrutores de usar void e não explicar esses efeitos que eu expliquei. Espero que tenha entendido a questão de expressões e lvalues... A questão que @Simon Viegas está levantando é que ele entendeu que a string deve ser invertida in-place, na mesma área. Entendeu? Não como você ou eu sugerimos. Deve retornar a mesma única string. Operando na mesma área de memória.
  14. O problema começa aqui... singular ou plural? decida: declarou tlivro e é uma struct então devia usar struct tlivro dados[tamanho]; pode parecer java mas eu prefiro declarar #define tamanho 5 //Estrutura da livro struct tlivro { int codigo; char nome[50]; char autor[50]; }; typedef struct tlivro Livro; //Estrutura da Pilha struct tpilha { Livro dados[tamanho]; int ini; int fim; }; typedef struct tltpilha Pilha; Pilha pilha; int op; //Protipação void pilha_entrar(); void pilha_sair(); void pilha_mostrar(); void menu_mostrar(); Acho que pretendia escrever "prototipação" que é uma palavra estranha mesmo Mais um palpite não solicitado: nunca use variáveis globais. São um pesadelo. Outro: junte protótipos e as declarações das estruturas globais num header
  15. Esse enunciado não é assim o máximo em objetividade, já que o item 2 começa falando em algoritmo e depois em programa, mas fica definido que são dois programas, afinal está escrito lá. Se fossem 2 funções provavelmente no mundo C a gente declararia char* inverte(char* origem, char* saida); char* troca(char c, char* origem); contrariando a ideia de @Simon Viegas porque usar void não acrescenta nada, mas retornar o endereço da string resultante permite usar o valor em expressões. É o que faz a maioria das funções em stdlib por exemplo. Retornando char* eu posso escrever printf("a string [%s] invertida: [%s]\n", entrada, inverte(entrada,saida)); Em termos mais próximos de C++: é preferível um rvalue e não um lvalue porque um lvalue não pode aparecer em uma expressão e assim fica limitante. veja fgets() por exemplo: char *fgets(char *str, int n, FILE *stream) Não estou recomendando, mas assim se pode escrever char saida[40]; char *p = saida; printf("a string [%s] invertida: [%s]\n", entrada, inverte(fgets(entrada,30,stdin),saida)); Que lê a string, inverte e coloca o resultado na saída e o programa continua. De volta a o tópico: Veja a saída do programa que claro vou deixar aqui embaixo. As mensagens talvez já digam o suficiente: Entrada: 'Roma' string[0] = 'R' string[1] = 'o' string[2] = 'm' string[3] = 'a' E string[4] = 0 o numero, zero E a string invertida vai ter o mesmo tamanho E terminar com o mesmo zero Mas vai comecar onde a primeira terminou Entrada foi de entrada[0] ate entrada[3] E invertida vai comecar em entrada[3] e terminar em entrada[0] Nada mais: um unico loop, mas DOIS indices Saida: 'amoR' saida[0] = 'a' saida[1] = 'm' saida[2] = 'o' saida[3] = 'R' E saida[4] = 0 o numero, zero O que esse exercício quer é mostrar ou avaliar uma entre duas coisas: o uso de dois índices para criar um valor o uso de uma estrutura de dados para inverter uma série Como o exercício é muito simples, os valores já vem na string arrumadinhos um depois do outro com um zero no final, então apenas o caso um vale a pena. Depois do vou mostrar o outro lado, o que usaríamos se fosse por exemplo o resultado de analisar algo como um texto e ir guardando certas ocorrências para depois mostrar. Aqui não se justifica. Os dois índices: Então, pensando na string 'Roma' que vai "de 'R' até 'a', de 0 a 3: o valor invertido vai ter o mesmo tamanho, e vai de 'a' a 'R', de 3 a 0. Os mesmos valores, uma única vez cada um. Então o simples é um loop com os dois índices, e uma maneira linear de escrever seria saida[limite] = 0; // vai ter o mesmo tamanho for ( int indice_entrada = limite - 1, indice_saida = 0; indice_entrada >= 0; indice_entrada = indice_entrada - 1, indice_saida = indice_saida + 1) { saida[indice_saida] = entrada[indice_entrada]; }; // for() Onde as variáveis tem os óbvios usos: limite é o fim da string, igual nas duas indice_entrada e indice_saida são isso entrada e saida são o óbvio O programa de teste #include<stdio.h> #include<stdlib.h> int main() { char entrada[32]; char saida[31]; printf("\nEntrada: "); fgets(entrada, 30, stdin); char limite = strlen(entrada) - 1; entrada[limite] = 0; printf("\nEntrada: '%s'\n", entrada); for (int i = 0; i < limite; i += 1) { printf("string[%d] = '%c'\n", i, entrada[i]); }; // for() printf("\nE string[%d] = %d o numero, zero\n", limite, entrada[limite]); printf("E a string invertida vai ter o mesmo tamanho\n"); printf("E terminar com o mesmo zero\n"); printf("Mas vai comecar onde a primeira terminou\n"); printf("Entrada foi de entrada[%d] ate entrada[%d]\n", 0, limite - 1); printf("E invertida vai comecar em entrada[%d] e terminar em entrada[%d]\n", limite - 1, 0); printf("Nada mais: um unico loop, mas DOIS indices\n"); // entao saida[limite] = 0; // vai ter o mesmo tamanho for ( int indice_entrada = limite - 1, indice_saida = 0; indice_entrada >= 0; indice_entrada = indice_entrada - 1, indice_saida = indice_saida + 1) { saida[indice_saida] = entrada[indice_entrada]; }; // for() printf("\nSaida: '%s'\n", saida); for (int i = 0; i < limite; i += 1) { printf("saida[%d] = '%c'\n", i, saida[i]); }; // for() printf("E saida[%d] = %d o numero, zero\n", limite, saida[limite]); return 0; } E um pouco mais simples de ler que o exemplo clássico usando while while (i < j) { temp = str[i]; str[i] = str[j]; str[j] = temp; i++; j--; } de @herbertbahia
  16. switch() é um comando. Você passa uma valor e as alternativas de código para cada valor. incluindo uma chamada default para quando não achar o valor certo. Imagine um char e você querer fazer coisas dependendo do valor. Pode escrever char Letra = '? '; switch( letra ) { case 'a': case 'b': // era 'a'ou 'b' // coisas break; // continua depois da } case 'd': break; case 'e': // e assim por diante break; default: // vem aqui se for outro valor break; } Algo assim. É um comando de seleção e em muitos casos fica mais legível que uma série de if()
  17. O código que eu te mostrei é o simples, de acordo com a documentação. int cls() { // limpa a tela no windows, do jeito oficial CONSOLE_SCREEN_BUFFER_INFO info; HANDLE H = GetStdHandle(STD_OUTPUT_HANDLE); COORD origem = { 0,0 }; int total; if (H == INVALID_HANDLE_VALUE) return -1; GetConsoleScreenBufferInfo(H, &info); int r = FillConsoleOutputCharacter(H, (TCHAR)' ', info.dwSize.X * info.dwSize.Y, origem, &total); int s = FillConsoleOutputAttribute( H, info.wAttributes, info.dwSize.X * info.dwSize.Y, origem, &total); SetConsoleCursorPosition(H, origem); return 0; }; // end cls() E tem até o mesmo nome. Não serve para seu caso? Essa é a maneira oficial: Chama GetConsoleScreenBufferInfo() para saber o tamanho atual da tela, que é variável. Chama FillConsoleOutputCharacter() e FillConsoleOutputAttribute() para limpar os caracteres E atributos porque são coisas separadas E põe o cursor em (0,)) adicionado 44 minutos depois você entendeu que basta colocar essa função cls() em seu programa em C? Se for C++ tem um jeito mais certo, mas assim também funciona. E esse é o jeito certo, de acordo com a Microsoft. Esse seu professor não pode recusar.
  18. Eu posso ajudar. Qual sua dúvida. E vai escrever em C ou C++?
  19. Usar system() para fazer algo em um programa não é de fato fazer algo. system() apenas pega uma string e envia para o interpretador de comandos. E não é um boa ideia. E não é nada ativo, apenas um intermediário. E é algo que você simplesmente não pode e não quer fazer em muitos ambientes, Se alguém injetar um executável com o nome de seu comando ou pior, o nome do seu script, imagine o que pode acontecer com seu computador, seu contrato ou seu emprego... Use as funções do sistema para fazer o que precisa. Usar system() é como explicar o caminho para alguém só que fazendo aquela cara de professor e indicando o Google Maps ou o Waze Um pouco de história em tempos de confinamento Limpar a tela na "console" do Linux Isso é algo controvertido: no Unix / Linux não existe console. E não há modo limpar a tela. E porque não? O terminal no Linux é um arquivo. Uma emulação de um terminal da Digital dos anos 70. VT-100 em geral. Algo que tinha uma tela, teclado e tomada. Olha um aqui: Esse aí na verdade. No manual dele estão todos os comandos ESC [ xx yy ; que são usados ainda hoje. E não havia esse conceito de limpar a tela porque os caracteres eram lidos e escritos um a um pelo sistema. Todos os terminais ficavam ligados ao sistema por um adaptador serial com uma porta para cada terminal. onde você ligava o cabo, até uns 50m. Mais longe? Usava um modem e uma linha telefônica. Esse era o terminal remoto. Uma maneira simples de limpar a tela então era identificar quantas linhas tinha a sua tela e enviar tantos \n quantas linhas tivesse lá, e aí o texto sumia, claro. Sério. E se aparecia tudo meio estranho eis o que a gente fazia: desligava o cara e ligava de novo. Ele não tinha memória do que estava na tela. A console era em geral o terminal 0, /dev/tty0, e só tinha valor porque quando tinha um problema maior talvez o sistema escrevesse algo lá além de acender umas luzes no painel de controle. De resto era um terminal como outro qualquer. Nos tempos pós 80 os terminais são emulados por programas, como xterm, que filtram o que vai para a "console". O mais perto de limpar a tela seria enviar um comando tput reset para o "terminal". Isso seria o equivalente a ligar o cara de novo se ele fosse de verdade. O que será enviado para o terminal está codificado num tipo de banco de dados chamado terminfo e que foi uma novidade muito legal quando apareceu... Direto do manual: E é exatamente isso: como os terminais eram ligados via porta serial, você podia enviar um comando para ele e esperar algum tipo de resposta dizendo que terminal está lá. A maioria deles respondia a um ESC qualquer coisa com a marca e modelo e alguns recursos. E era um inferno porque era preciso ficar questionando cada terminal, e se não viesse resposta já era. Um pesadelo. Com terminfo era só verificar um variável de ambiente e a partir daí pegar os comandos lá no terminfo. Claro que você pode acessar vários tty ao mesmo tempo. tty vem de teletype que é como os terminais era ANTES de serem emuladores e ANTES de terem telas. Veja um comum, o LA36: podia usar 132 colunas, tinha minúsculas! e podia até usar o modo gráfico! Ruim era por a cadeira na frente e acabar pisando no formulário... Limpar a tela na console do Windows Aí é uma outra história. O Windows tem uma imagem do que está na tela da console, e você pode ter mais de uma associada a um programa, embora eu nunca tenha visto alguém usar isso. enviar um certo número de newlines também serviria, mas veja o padrão de linhas da console do Windows: Sim. 9001 Linhas. O oficial para limpar a tela no Windows é simplesmente rodar as funções da console, bem documentadas em https://docs.microsoft.com/en-us/windows/console/console-reference. Ao menos eu acho que estão bem documentadas. Uma versão de cls() pelo oficial da console do Windows seria algo assim: int cls() { // limpa a tela no windows, do jeito oficial CONSOLE_SCREEN_BUFFER_INFO info; HANDLE H = GetStdHandle(STD_OUTPUT_HANDLE); COORD origem = { 0,0 }; int total; if (H == INVALID_HANDLE_VALUE) return -1; GetConsoleScreenBufferInfo(H, &info); int r = FillConsoleOutputCharacter(H, (TCHAR)' ', info.dwSize.X * info.dwSize.Y, origem, &total); int s = FillConsoleOutputAttribute( H, info.wAttributes, info.dwSize.X * info.dwSize.Y, origem, &total); SetConsoleCursorPosition(H, origem); return 0; }; // end cls() Bem claro: vê o tamanho da tela preenche tudo com brancos coloca o cursor lá no começo. No entanto isso não é mais recomendado: o certo hoje em dia em tempos de Microsfot Azure, Google Cloud e Amazon AWS em que os computadores estão todos indo para a nuvem inclusive os terminais dos alunos, o recomendado é usar o Terminal do Windows que usa aceleração por hardware e é compatível com o xterm... Como aparece no link em todas as consoles Windows desde 2017
  20. Talvez possa perguntar algo objetivo...
  21. char short int long tem a mesma codificação. Só muda o sizeof(). Exato. Mas...No caso são só 256 o que é nada. E é muito, mas muito mais rápido que usar funções. Pode ser centenas ou milhares de vezes mais rápido dependendo das operações que você faz. Acessar e manipular bytes em processadores é a coisa mais rápida e fundamental que se faz Não. Você inicializa absolutamente todas sempre ou vai dar m. Nesse caso aqui os valores são zero, 1 ou 2. É que (256 - 11) eram 0 e usei um memset() que é ultra-rápido. E atribui nos outros casos. É só um brinquedo. Se fosse um programa de produção você entraria com a tabela pronta em tempo de compilação para economizar ainda mais um tempinho... Algo assim, que eu copiei de um programa claro const char ref[256] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 }; Seria só trocar todos de acordo. Sei que já entendeu. E gente como nós faz um programa para gerar um trecho de código certinho e alinhado. Você já conhece a tabela então não vai esperar rodar o programa para atribuir o que você já sabe. E pode combinar condições usando os bits dentro da tabela. Veja o caso da tabela ASCII: a diferença entre maiúscula e minúscula é 32. A diferença de você apertar Control é zerar os primeiros 3 bits: control A é 1, control Z 26. Então letra = 'a'; letra_minuscula = letra | 0x20; control_letra = letra & 0x3F; coisas assim. Essa função C para Windows abaixo por exemplo nem vou dizer o que ela faz. Faz parte de um conjunto que eu escrevi para meu uso em último caso. Veja os bitmasks lá no meio... void mensagem_em_video_reverso(char* mensagem) { HANDLE H = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO info; GetConsoleScreenBufferInfo(H, &info); WORD foreground = info.wAttributes & 0xF; WORD background = info.wAttributes & 0xF0; text_color(background, foreground); printf("%s", mensagem); text_color(foreground, background); return; }
  22. if(sexo=='M') { B= (72.7*altura)-58; printf("O seu peso ideal é de: %f", B); } else { G= (62.1*altura)-44.7; if (sexo=='F') printf("O seu peso ideal é de: %f", G); } Você tem um livro? um manual ao menos? Veja o formato do comando if() no manual. C não tem essa noção de contexto da condição. Você precisa de outro if para testar a outra condição... Porque está fazendo os dois cálculos antes de saber o sexo? Só vai usar um. Coloque a conta dentro dos if()
  23. A resposta curta é sim. Está correto. Em C++ use a classe string e vector e tal. Conforme seus programas ficarem maiores vai achar mais simples e produtivo Veja esse resultado Sunday Monday Tuesday Wednesday Thursday Friday Saturday Com o indice 0 Sunday 1 Monday 2 Tuesday 3 Wednesday 4 Thursday 5 Friday 6 Saturday Desse programa #include <iostream> #include <vector> int main() { std::vector<std::string> dayWeek = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; for (auto day : dayWeek) std::cout << day << std::endl; std::cout << "\nCom o indice\n" << std::endl; for (auto i = 0; i<dayWeek.size(); i+=1) std::cout << i << " " << dayWeek[i] << std::endl; return 0; } Que faz duas vezes a mesma coisa só para mostrar o for com iteração automática e o vector faz muito mais coisas que o char*. --- --- --- Então @AdrianoSiqueira na verdade não era pra ser confuso. É uma técnica comum. A multiplicação por exemplo usa tabelas nos processadores. A tabela de referência na verdade é essa ref[] char ref[256]; memset(ref, 0, 256); ref['a'] = ref['e'] = ref['i'] = ref['o'] = ref['u'] = 1; ref['A'] = ref['E'] = ref['I'] = ref['O'] = ref['U'] = 1; ref[' '] = 2; E normalmente você teria os 256 na tabela e com os valores já arrumadinhos para a lógica. Só aqui são só 11 e aí bate uma preguiça de preencher a tabela toda... Na verdade o índice é a tabela. Nessa linha está o processamento todo: letra = ref[palavra[i]]; e em um char tem 256 posições então na tabela tem o resultado de cada possível conteúdo de letra... Entendeu que é melhor usar um char para guardar a letra do que fazer toda essa referência duas vezes não? Eu poderia ter colocado tipo ref[32] = 2 para o espaço, mas fica mais difícil de ler...
  24. Você não disse ainda qual versão de compilador está usando... Já resolveu? Esqueci de reforçar o lance de que se está usando o compilador da Microsoft deve chamar o Code a partir de um Developer Prompt para o sistema ajeitar o acesso aos diretórios de compilação. Claro que de qualquer forma você precisa de um compilador porque esse ambiente é como o Eclipse, o code::Blocks e outros. É um ambiente em volta de um ou mais compiladores. O da MS você instala ou instalando o Visual Studio ou o kit C++ Build Tools que inclui o compilador. Qualquer um dos dois vai te dar um atalho para abri o Developer Prompt. Está bem documentado aqui: https://code.visualstudio.com/docs/cpp/config-msvc Um exemplo para uma máquina que tem duas versões de gcc e o compilador da Microsoft. Em Terminal | Run Task aparece E você escolhe o que quer fazer no menu. Claro que com o programa aberto pode só clicar no > ou F5 e o programa repete o que você usou da última vez Essas ações estão em um único arquivo, o tal launch.json e você pode editar aí mesmo no editor claro. E configurar o que quiser, como rodar um makefile, compilar todos os cpp, chamar um carro do Uber ou pedir um lanche Eis o arquivo desse exemplo { "version": "2.0.0", "tasks": [ { "type": "shell", "label": "Microsoft C/C++ Build do programa ativo", "command": "cl.exe", "args": [ "/Zi", "/EHsc", "/Fe:", "${fileDirname}\\${fileBasenameNoExtension}.exe", "${file}" ] }, { "type": "shell", "label": "Microsoft C/C++: Não gera EXE mostra codigo assembler", "command": "cl.exe", "args": [ "/Zi", "/FA", "/c", "/EHsc", "/Fe:", "${fileDirname}\\${fileBasenameNoExtension}.exe", "${file}" ] }, { "type": "shell", "label": "(C++) Gera o programa ativo usando o gcc 5.1.0", "command": "C:\\Program Files (x86)\\CodeBlocks\\MinGW\\bin\\g++.exe", "args": [ "-g", "-v", "-std=c++17" "${file}", "-o", "${fileDirname}\\${fileBasenameNoExtension}.exe" ], "options": { "cwd": "C:\\Program Files (x86)\\CodeBlocks\\MinGW\\bin" }, "problemMatcher": [ "$gcc" ], "group": "build" }, { "type": "shell", "label": "(C++) Gera o programa ativo usando o gcc 8.2.0", "command": "C:\\MinGW\\bin\\g++.exe", "args": [ "-g", "-v", "-std=c++17" "${file}", "-o", "${fileDirname}\\${fileBasenameNoExtension}.exe" ], "options": { "cwd": "C:\\Program Files (x86)\\CodeBlocks\\MinGW\\bin" }, "problemMatcher": [ "$gcc" ], "group": "build" } { "type": "shell", "label": "(C) Gera o programa ativo usando o gcc 5.1.0", "command": "C:\\Program Files (x86)\\CodeBlocks\\MinGW\\bin\\g++.exe", "args": [ "-g", "-std=c11" "${file}", "-o", "${fileDirname}\\${fileBasenameNoExtension}.exe" ], "options": { "cwd": "C:\\Program Files (x86)\\CodeBlocks\\MinGW\\bin" }, "problemMatcher": [ "$gcc" ], "group": "build" } { "type": "shell", "label": "(C) Gera o programa ativo usando o gcc 8.2.0", "command": "C:\\Program Files (x86)\\CodeBlocks\\MinGW\\bin\\g++.exe", "args": [ "-g", "-std=c11" "${file}", "-o", "${fileDirname}\\${fileBasenameNoExtension}.exe" ], "options": { "cwd": "C:\\Program Files (x86)\\CodeBlocks\\MinGW\\bin" }, "problemMatcher": [ "$gcc" ], "group": "build" } ] } É só um formulário. E voce pode copiar para todas as pastas de seus programas o diretório .vscode que isso aí vai junto. Eu devia ter escrito isso da última vez.
  25. Você não está acompanhando quantas pessoas leu: entenda que pode não ter lido nenhum por exemplo. Precisa contar o número efetivos dos lidos para fazer do jeito que está tentando. Basta o cara digitar um nome e depois -1 e já era. Do jeito que escreveu só funcionaria (se o resto estivesse certo) para exatamente 10 valores. Você está guardando os valores num vetor. Tudo que você precisa saber é a posição do mais novo e mais velho que você viu. Só isso. Só dois números. Não há necessidade complicar as coisas. Declare por exemplo int posicao_do_mais_velho = -1; int posicao_do_mais_novo = -1; E conforme vai lendo mantenha atualizado. Só isso. Só um loop. O nome vai estar lá na posição, a idade vai estar lá na posição... E entenda que mesmo isso é desnecessário: Você não precisa sequer do vetor: basta guardar o nome do mais velho e a idade, e o mesmo para o mais novo. E manter atualizado. Tanto faz se vai ler 10 ou 500. Não precisa mostrar os caras na saída. Só o mais velho e o mais novo. Só isso já resolveria seu problema: int idade; char nome[20]; char nome_do_mais_velho[20]; char nome_do_mais_novo[20]; int posicao_do_mais_velho = -1; int posicao_do_mais_novo = -1; adicionado 0 minutos depois Isso eu não entendi

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!