-
Posts
6.526 -
Cadastrado em
-
Última visita
Tipo de conteúdo
Artigos
Selos
Livros
Cursos
Análises
Fórum
Tudo que arfneto postou
-
Ah tá! E onde entra a soma dos 3 parâmetros ser diferente de 2? while (a+b+c != 2){} E não há qualquer referência aos números primos pra colocar no formulário... Não entendo mesmo. E o valor de i nunca é incrementado, mas sim o de c que é um dos parâmetros e cuja soma deve ser diferente de 2 para encerrar o tal loop...
-
Sim. Basta isso. Só que é a única maneira. Na declaração da classe declare a classe base. Não. Não existem. E se existir não é essa por certo. @Mauro Britivaldo e @TomJohn espero que tenham paciência em ler o que vou escrever , incluindo os exemplos. Estou com tempo hoje e acho que essa é uma dúvida comum e esse é o propósito do forum afinal Atenção para o exemplo acima: não é assim que funciona. this simplesmente contem o endereço do objeto que contém a variável ou método. É especialmente importante para eliminar ambiguidades quando um método ou variável é redefinido, como você havia feito, @TomJohn, em todas as classes do seu exemplo. Nesse programa que @Mauro Britivaldo escreveu não há qualquer redefinição e os valores são herdados da (nova) classe base Caracteristica. Todos. E não há qualquer ambiguidade. Nesse caso as classes não são herdadas como provavelmente o enunciado esperava, nível após nível, mas apenas a partir de uma classe Tataravo que por sua vez tem uma nova classe base. Repito: this nesse exemplo acima é totalmente inócuo. Apague e verão. Só existe uma variável de cada atributo, boolean. E como C++ vai chamar todos os construtores até a classe base os atributos estarão atribuídos na ordem de construção. Vou mostrar mais uma vez um exemplo disso, com a saída para tentar de novo explicar isso. É um conceito essencial para entender essa e outras linguagens orientadas a objeto, como java. Considerem o exemplo das classes derivadas a partir de Tataravo até o Neto. Vamos usar uma variável geração, que numera a geração a partir do Tataravo = 1 até o Neto = 6 então. Como eu expliquei mais de uma vez, e vocês viram no exemplo inicial, ao redefinir uma variável com o mesmo nome a cada subclasse gerada, desaparece a variável ou método da classe acima. Como temos 5 gerações acima do Neto, todas elas desaparecem, como desapareceram os carros e casas em seu programa, @TomJohn Não desapareceram, não sei como ensinam isso em português, mas ficam ofuscadas ou sombreadas. shadowing é a expressão comum na documentação. Mas como a cada derivação é construída uma classe desde a classe base, e eu mostrei isso pra vocês, as outras gerações ainda estão lá. Apenas não se pode vê-las. EXEMPLO Considerando as classes do exemplo anterior, apenas acrescentei uma variável int geração; e no construtor da classe numerei as gerações a partir do Tataravo Tataravo geração 1 Bisavo geração 2 Avo geração 3 Pai geração 4 Filho geração 5 Neto geração 6 E vou explicar como acessar essas gerações todas --- desculpem o trocadilho Para explicar a necessidade real de this, vou acrescentar uma ambiguidade real criando um novo construtor para Neto, que permite passar uma geração como parametro, e usando o MESMO nome, geração. As outras variáveis com o mesmo nome, que nesse caso existem mesmo, não geram ambiguidade: isso foi idealizado assim pelos construtores dessas linguagens. Herança tem a ver com especialização e quando você cria um método ou variável com o mesmo nome se imagina que você fez isso DE PROPÓSITO. Em java se usa até uma anotação @override na frente de um método para indicar que você sabe o que está fazendo e não se enganou apenas. Não gera ambiguidade porque redefine o método ou valor. Eis a classe Neto, que deriva de Pai que deriva de Avo... e tal class Neto : public Filho { public: int geração; public: Neto() { nome = "neto, nome nao informado"; }; // construtor com nome Neto(string nome) : Filho(nome) { cout << " Criando neto: nome=" << nome << endl; geração = 6; }; // construtor com nome e geração Neto(string nome, int geração) : Filho(nome) { cout << " Criando neto: nome=" << nome << " geração=" << geração << endl; cout << "geração, o parametro=" << geração << endl; Tataravo* tataravo = this; geração = tataravo->geração; cout << "Todo Tataravo tem geração=1 definida no construtor da classe" << endl; cout << "geração, o parametro copiado do tataravo dessa instancia=" << geração << endl; this->geração = geração; cout << "geração, na classe=" << this->geração << endl; }; }; // end class E considerem esse programa cout << "\n----- Criando Neto (usando a geração)" << endl; Neto n("Neto", 2000); n.nome_do_pai("Pai do Neto"); cout << "Em main() a geração do Neto ='" << n.geração << "'" << endl; cout << "\n----- Criando Neto so com o nome" << endl; Neto outro("Outro Neto"); outro.nome_do_pai("Pai do Outro Neto"); cout << "Em main() a geração do Outro Neto ='" << outro.geração << "'" << endl; Ao declarar dois Neto usando os diferentes construtores acho que vão entender quando e porque se usa this e, ao mesmo tempo, como usar o próprio endereço do objeto --- this --- para ressuscitar a geração do Tataravô que tinha sumido ao ser redefinida pelas classes derivadas. Atentem para o trecho Tataravo* tataravo = this; geração = tataravo->geração; cout << "Todo Tataravo tem geração=1 definida no construtor da classe" << endl; cout << "geração, o parametro copiado do tataravo dessa instancia=" << geração << endl; this->geração = geração; no construtor, e para o RESULTADO do PROGRAMA ----- Criando Neto (usando a geração) Criando tataravo: nome=Neto Criando bisavo: nome=Neto Criando avo: nome=Neto Criando pai: nome=Neto Criando filho: nome=Neto Criando neto: nome=Neto geração=2000 geração, o parametro=2000 Todo Tataravo tem geração=1 definida no construtor da classe geração, o parametro copiado do tataravo dessa instancia=1 geração, na classe=1 Em main() a geração do Neto ='1' ----- Criando Neto so com o nome Criando tataravo: nome=Outro Neto Criando bisavo: nome=Outro Neto Criando avo: nome=Outro Neto Criando pai: nome=Outro Neto Criando filho: nome=Outro Neto Criando neto: nome=Outro Neto Em main() a geração do Outro Neto ='6' Vejam que no primeiro caso o que ficou valendo para a geração foi o valor que estava oculto na classe base Como acessar os valores ofuscados nas classes base então? Assim int main() { cout << "\n----- Criando Neto" << endl; Neto n("Neto"); n.nome_do_pai("Pai do Neto"); cout << "pai de " << n.nome << " = " << n.pai << endl; cout << "\nUsando a mesma variavel, da classe '" << typeid(n).name() << "'" << endl; cout << "Neto: " << n.geração << endl; cout << "Filho: " << ((Filho)(n)).geração << endl; cout << "Pai: " << ((Pai)(n)).geração << endl; cout << "Avo: " << ((Avo)(n)).geração << endl; cout << "Bisavo: " << ((Bisavo)(n)).geração << endl; cout << "Tataravo: " << ((Tataravo)(n)).geração << endl; } // end main() Que mostra os desaparecidos e você pode testar em seu exemplo inicial, @TomJohn Notem que typeid(n).name() mostra o valor da classe da variável n e vai mostrar class Neto como esperado. Isso é um comando do C++ ----- Criando 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 Usando a mesma variavel, da classe 'class Neto' Neto: 6 Filho: 5 Pai: 4 Avo: 3 Bisavo: 2 Tataravo: 1 Entendam: tudo isso está contido --- encapsulado --- dentro da mesma variável n, do tipo Neto, mas que também é um Pai, Avo e tal.... Todos os valores de casas e carros por exemplo, para todas as classes intermediárias, @TomJohn podem ser acessados assim. é o que se chama cast e permite recuperar então esses valores, mostrando o valor de geração ao ver n como um Bisavo, que tem geração = 2.
-
Não entendi de fato seu programa ainda. Não entendi o que é o while (a+b+c != 2){} por exemplo. O que pretende com esse loop? E os primos? Nesse problema a ideia é replicar o que está feito naquele desenho, o que aprendemos no ensino fundamental para calcular o MMC. Igualzinho está lá. Eu te mostrei uma saída para os 3 casos do enunciado por exemplo para 10,5,6 Isso é o resultado da execução daquela função entende? calcula_mmc(10,5,6) 10; 5; 6 | 2 5; 5; 3 | 3 5; 5; 1 | 5 1; 1; 1 | --------------------|------- | mmc(10;5;6) = 1x2x3x5 = 30 O exercício aqui não se trata simplesmente de calcular o MMC, porque aí podíamos usar qualquer método, por exemplo multiplicar a*b*c que seria naturalmente um múltiplo comum. E ir simplificando até ele ficar mínimo, o que pode dar na mesma se eles forem primos entre si como mmc(3,5,7) por exemplo. Acho que seria o mais comum a se fazer. Aqui é para replicar aquele método do papel e lápis da escola fundamental. Você deve pensar mais a respeito e criar algo parecido. Eu fiz uns no papel antes de escrever o programa e deu certo. Sobre onde colocar a função, vou te mostrar algo. Vou incluir as funções no seu programa e chamar as funções e aí ele vai mostrar o resultado de que precisa e vai te dar uma luz imagino. #include "math.h" #include "stdio.h" int retorna_um_se_primo(unsigned int n) { if (n < 2) return 0; if (n == 2) return(1); if (n % 2 == 0) return(0); unsigned int maior = (unsigned int)sqrt((double)n); unsigned int fator = 3; while (fator <= maior) { if (n % fator == 0) return 0; fator += 2; } // end while return 1; } // end retorna_zero_se_primo() unsigned int proximo_primo(unsigned int n) { static int iniciado = 0; static int proximo = 0; if (n == 0) // inicia a serie { iniciado = 1; proximo = 2; return 1; } // end if if (iniciado == 0) return 0; // erro: tem que chamar com 0 antes if (proximo == 2) { proximo = 1; return 2; } // end if // normal: a a partir daqui retorna o proximo primo for (int i = proximo + 2;; i += 2) if (retorna_um_se_primo(i)) { proximo = i; return proximo; } // end if } // end proximo_primo() unsigned int calcula_mmc(int a, int b, int c) { char produtos[256]; // para montar o resultado int mmc = 1; // o proprio MMC int n; int primo = proximo_primo(0); // inicia o gerador sprintf(produtos, " mmc(%d;%d;%d) = 1", a, b, c); primo = proximo_primo(1); // pega o 2 printf("\n\n%5d; %5d; %5d |", a, b, c); // comeca o esquema do { n = 0; if (a % primo == 0) n += 1, a = a / primo; // a = multiplo if (b % primo == 0) n += 1, b = b / primo; // b = multiplo if (c % primo == 0) n += 1, c = c / primo; // c = multiplo if (n == 0) primo = proximo_primo(1);// nem a nem b nem c e multiplo desse else { sprintf(produtos, "%sx%u", produtos, primo); // acrescenta fator ou vai perder printf(" %5d\n%5d; %5d; %5d |", primo, a, b, c);// nova linha mmc = mmc * primo; // atualiza MMC } // end if if (a > 1 || b > 1 || c > 1) continue; // ainda tem ao menos 1 break; } while (1); // vai sair apenas com 1;1;1 printf( "\n--------------------|-------\n |%s = %d\n", produtos, mmc); return mmc; } // end calcula_mmc() int main() { int a, b, c, mmc, i; i = 2; calcula_mmc(10, 5, 6); if (i == 2) return 0; scanf("%d %d %d", &a, &b, &c); mmc = 1; if (a == 0 || b == 0 || c == 0) { return 0; } while (a + b + c != 2) { if (a % i == 0 || b % i == 0) { mmc += i; if (a % i == 0) { a /= i; } if (b % i == 0) { b /= i; } if (c % i == 0) { c /= i; } } else { c += 1; } } // while() printf("MMC= %d", mmc); } Esse é o seu programa com as funções que te mostrei coladas no início. i = 2; calcula_mmc(10, 5, 6); if (i == 2) return 0; Eu só incluí as 3 funções que te mostrei. Logo no início assim você vai ter um programa completo para servir de base. E essas 3 linhas aí em cima chamam a função que eu escrevi e vão te dar uma ideia de uma maneira de resolver o problema. Eu já tinha postado isso mesmo. Achei que já teria talvez escrito isso. Ao escrever a sua solução tire essa linha que chama calcula_mmc() e pronto. Claro, apague as funções que inseri. Vou deixar uma cópia do programa anexa. Rode esse programa TextFile2.txt
-
E se unsigned int proximo_primo(unsigned int); int retorna_um_se_primo(unsigned int); Funcionam então se pode escrever unsigned int calcula_mmc(int a, int b, int c); Simplesmente replicando o que se faria numa folha de papel, porque proximo_primo() a cada vez que é chamada retorna o próximo primo e é o que falta pra por lá do lado direito do gabarito. E calcula_mmc() poderia retornar algo bem parecido com o que se faz no papel, ou no enunciado calcula_mmc(4, 6, 8); calcula_mmc(10, 5, 6); calcula_mmc(3, 5, 7); Mostrando 4; 6; 8 | 2 2; 3; 4 | 2 1; 3; 2 | 2 1; 3; 1 | 3 1; 1; 1 | --------------------|------- | mmc(4;6;8) = 1x2x2x2x3 = 24 10; 5; 6 | 2 5; 5; 3 | 3 5; 5; 1 | 5 1; 1; 1 | --------------------|------- | mmc(10;5;6) = 1x2x3x5 = 30 3; 5; 7 | 3 1; 5; 7 | 5 1; 1; 7 | 7 1; 1; 1 | --------------------|------- | mmc(3;5;7) = 1x3x5x7 = 105 Eis um código possível, com comentários e menos de 30 linhas: unsigned int calcula_mmc(int a, int b, int c) { char produtos[256]; // para montar o resultado int mmc = 1; // o proprio MMC int n; int primo = proximo_primo(0); // inicia o gerador sprintf(produtos," mmc(%d;%d;%d) = 1", a, b, c); primo = proximo_primo(1); // pega o 2 printf("\n\n%5d; %5d; %5d |", a, b, c); // comeca o esquema do { n = 0; if (a % primo == 0) n += 1, a = a / primo; // a = multiplo if (b % primo == 0) n += 1, b = b / primo; // b = multiplo if (c % primo == 0) n += 1, c = c / primo; // c = multiplo if (n == 0) primo = proximo_primo(1); // nem a nem b nem c e multiplo desse else { sprintf(produtos, "%sx%u", produtos, primo); // acrescenta fator ou vai perder printf(" %5d\n%5d; %5d; %5d |", primo, a, b, c); // nova linha mmc = mmc * primo; // atualiza MMC } // end if if (a > 1 || b > 1 || c > 1) continue; // ainda tem ao menos 1 break; } while (1); // vai sair apenas com 1;1;1 printf("\n--------------------|-------\n |%s = %d\n", produtos, mmc); return mmc; } // end calcula_mmc()
-
Essa é uma possibilidade para a primeira função int retorna_um_se_primo(unsigned int n) { if (n < 2) return 0; if (n == 2) return(1); if (n % 2 == 0) return(0); unsigned int maior = (unsigned int)sqrt((double)n); unsigned int fator = 3; while (fator <= maior) { if (n % fator == 0) return 0; fator += 2; } // end while return 1; } // end retorna_zero_se_primo() E essa funciona então a segunda pode ser unsigned int proximo_primo(unsigned int n) { static int iniciado = 0; static int proximo = 0; if (n == 0) // inicia a serie { iniciado = 1; proximo = 2; return 1; } // end if if(iniciado == 0) return 0; // erro: tem que chamar com 0 antes if (proximo == 2) { proximo = 1; return 2; } // end if // normal: a a partir daqui retorna o proximo primo for (int i = proximo+2;;i += 2) if (retorna_um_se_primo(i)) { proximo = i; return proximo; } // end if } // end proximo_primo() E também funciona Teve sucesso com o código?
-
Pois é: o programa que eu te mostrei mostra o que é herdado e eu até expliquei de novo. E também expliquei o que seu programa não fez. Espero que esse sites não tenham dito nada diferente porque eles estariam errados. Entenda que como eu disse antes, herança é melhor vista como especialização de classes. As coisas funcionam até como você imaginava, até o momento em que você declara novas variáveis nas subclasses com os mesmos nomes que nas classes base. E como você redeclarou todas não herdou nada na prática. Atente para o programa que te mostrei: Tataravo é a única classe que tem nome no meu exemplo. E o Bisavô é a única que tem pai e acrescenta o método nome_do_pai(), que foi herdado por todas subclasses e inclusive usado no meu exemplo, por uma variável da classe Neto... Quando você redeclara uma variável dessas ocorre o que na literatura se chama de shadowing eu creio, e as variáveis com os mesmos nomes nas classes base ficam como fora de escopo. Entenda que um Neto é também um Tataravo, e um Pai e tudo que tem no caminho....
-
Se você tem lá naquele programa uma função int retorna_um_se_primo(unsigned int n); e ela funciona, então essa outra aqui unsigned int proximo_primo(unsigned int n) { static int iniciado = 0; static int proximo = 0; if (n == 0) // inicia a serie { iniciado = 1; proximo = 2; return 1; } // end if if(iniciado == 0) return 0; // erro: tem que chamar com 0 antes if (proximo == 2) { proximo = 1; return 2; } // end if // normal: a a partir daqui retorna o proximo primo for (int i = proximo+2;;i += 2) if (retorna_um_se_primo(i)) { proximo = i; return proximo; } // end if } // end proximo_primo() Chama retorna_um_se_primo() retorna a cada vez o próximo primo pra você usar direto na solução do seu programa... Bem conveniente. Esse código por exemplo int total_de_primos = 8; printf("proximo_primo(0) retornou %d\n", proximo_primo(0)); for (int i = 0; i < total_de_primos; i++) { printf("proximo_primo(1) retornou %d\n", proximo_primo(1)); } Mostra proximo_primo(0) retornou 1 proximo_primo(1) retornou 2 proximo_primo(1) retornou 3 proximo_primo(1) retornou 5 proximo_primo(1) retornou 7 proximo_primo(1) retornou 11 proximo_primo(1) retornou 13 proximo_primo(1) retornou 17 proximo_primo(1) retornou 19 A ideia é simples: você chama ela com 0 para iniciar a sequência e a partir daí ela vai retornando os primos um a um. Nada mais. Basta chamar com qualquer coisa diferente de zero. A partir daí fica fácil calcular o mmc porque só precisa de um loop
-
C Porque não printar com letra colorida no windows?
arfneto respondeu ao tópico de Reberth Siqueira em C/C#/C++
Postei um programa um dia desses aqui que simulava uma rodada de bingo com algumas cartelas até alguém ganhar. Como era preciso mudar a cor para os números que iam sendo sorteados nas cartelas e mudar o cursor para endereçar as colunas deve servir como exemplo para windows. E pode escrever uma rotina intermediária para que fique portável, sem ter que se preocupar em aprender a usar alguma biblioteca, que é meio chato. Não me lembro agora do tópico mas deve ser fácil pesquisar... Vou ver. Mas estão como eu disse convergindo e a console do Windows 10 desde 2018 tem como responder aos comandos do vt100. Deixei referências em outro post adicionado 4 minutos depois Esse é o post. Tem um programa completo lá que faz o sorteio e fica mostrando os números e os sorteios em verde eu acho... Por certo faz o que você precisa -
Olá! Eu escrevi isso e uma outra rotina que usava o crivo de eratóstenes --- que a gente aprende no ensino fundamental --- e usei um método para conferir o outro e calcular os primos até um certo número. Um milhão eu acho
-
acho que eu postei algo assim semanas atrás. Vou ver até
-
Mas nem é importante. Basta uma função que retorne o próximo primo e um loop até retornar 1 1 1, replicando o enunciado
-
Mais sobre os desenhos das peças Esse programa --- abaixo --- roda até ter uma colisão, colocando peças [ ] [ ] [ ] [ ] [ ] alternadamente na horizontal e vertical até ter uma colisão. Eis a última tela de um teste. @Irwing Seiji Ato Se sabe que houve colisão com uma certa peça em uma certa posição e temos o ID da peça em questão. Dependendo das "regras" é trivial ir até a estrutura da peça em questão e pegar o nome e mais informações para por exemplo apagar as duas simular uma explosão juntar as duas Peca 'vertical 5' id=10 Largura 1, Altura 5, 5 blocos origem para a peca=(7,7) COLISAO: peca com id=7 ja ocupa a posicao (7,9) Grade: X 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 0 * * * * * 2 * * * * * * * * * * * * * * 0 1 * * * * * 2 * * * * * * * * * * * * * * 1 2 * * * * * 2 * * * * * * * * * * * * * * 2 3 * * * * * 2 * * * * * * * * * * * * * * 3 4 * * * * * 2 * * * * * * * * * * * * * * 4 5 * * * * * * * * * * * * * * * * * * * * 5 6 * * * * * * * * * * * * * * * * * * * * 6 7 * * * * * * * * * * * * * * * * * * * * 7 8 * * * * * * * * * * * * * * * * * * 6 * 8 9 * * * * * * * 7 7 7 7 7 * * * * * * 6 * 9 10 * * 8 * * * * * * * * * * * * * * * 6 * 10 11 * * 8 3 3 3 3 3 * * * * * * * * * * 6 * 11 12 * * 8 * * * 9 9 9 9 9 5 5 5 5 5 * * 6 * 12 13 * * 8 * * * * 4 * * * * * * * * * * * * 13 14 * * 8 * * * * 4 * * * * * * * * * * * * 14 15 * * * * * * * 4 * * * * * * * * * * * * 15 16 * * * * * * * 4 * 1 1 1 1 1 * * * * * * 16 17 * * * * * * * 4 * * * * * * * * * * * * 17 18 * * * * * * * * * * * * * * * * * * * * 18 19 * * * * * * * * * * * * * * * * * * * * 19 X 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Teste: encerra na primeira colisao Esse código int main(int argc, char** argv) { char* coluna_h = "horizontal 5"; char* coluna_v = "vertical 5"; int ciclo = 0; int i; Grade grid; inicia_grade(&grid); printf("Grade:\n"); mostra_grade(&grid); do { if (ciclo%2) { // peca 1x5 cria_1_5(&grid, coluna_v); i = posiciona_pecas(&grid); ciclo += 1; } else { // peca 5x1 cria_5_1(&grid, coluna_h); i = posiciona_pecas(&grid); ciclo += 1; } printf("Grade:\n"); mostra_grade(&grid); } while (i>=0); printf("Teste: encerra na primeira colisao\n"); return 0; }; // end main() Simples: alterna usando o valor de ciclo e mostra a grade até posiciona_pecas() reportar uma colisão. É só um teste para as estruturas afinal. Não, eu não queria escrever na tela. O interesse é só no mecanismo. Como cada peça tem dentro de si as coordenadas de cada ponto dela, ao identificar onde ela vai ficar na tela fica trivial identificar se tem uma colisão: Esse é um trecho possível de código para quando ela vai ficar em uma posição aleatória Peca* p = g->mapa->peca[pos]; // simplifica uint8_t outra = 0; // em quem bateu Ponto colisao; // a peca tem suas coordenadas ja armazenadas a partir do canto // superior esquerdo. a partir da largura maxima e altura maxima // e ja esta gravado na descricao da peca // calcula onde ela pode ficar na tela mostra_peca(p); uint8_t x = rand() % (MAX_X - p->W); uint8_t y = rand() % (MAX_Y - p->H); printf("origem para a peca=(%d,%d)\n", x, y); /* a nova peca tem n_blocos e a origem (x,y). Para ver se ela pode ser colocada na grade basta um loop, mapeando os blocos na peca a partir da origem (x,y) e ve se esta marcado como livre na grade */ uint8_t blocos = p->n_blocos; int ok = 1; // livre na tela for (int i = 0; i < blocos; i += 1) { // vamos definir X,Y como a posicao na grade para esse bloco uint8_t X = x + p->pino[i].X; uint8_t Y = y + p->pino[i].Y; if ( g->grade[X][Y] == 0) continue; ok = 0; outra = (uint8_t)g->grade[X][Y]; colisao.X = X; colisao.Y = Y; break; } adicionado 17 minutos depois [][][] Uma peça assim teria então 11 "pinos" como [] descrito na estrutura de Peça [][][] [] claro, cada par [] significa um ponto [][][] podia ser um pixel ou dois caracteres ou qualquer outra representação Uma peça em formato de E ficaria assim então no código int main(int argc, char** argv) { char* nome = "em formato de E"; int ciclo = 0; int i; Grade grid; inicia_grade(&grid); printf("Grade:\n"); mostra_grade(&grid); Peca* p = (Peca*)malloc(sizeof(Peca)); if (p == NULL) return NULL; /* peca em formato de 'E' */ p->H = 5; p->n_blocos = 11; p->nome = nome; p->W = 3; p->pino[0].X = 0; p->pino[0].Y = 0; // linha 0 p->pino[1].X = 1; p->pino[1].Y = 0; p->pino[2].X = 2; p->pino[2].Y = 0; p->pino[3].X = 0; p->pino[3].Y = 1; // linha 1 p->pino[4].X = 0; p->pino[4].Y = 2; // linha 2 p->pino[5].X = 1; p->pino[5].Y = 2; p->pino[6].X = 2; p->pino[6].Y = 2; p->pino[7].X = 0; p->pino[7].Y = 3; // linha 3 p->pino[8].X = 0; p->pino[8].Y = 4; // linha 4 p->pino[9].X = 1; p->pino[9].Y = 4; p->pino[10].X = 2; p->pino[10].Y = 4; // preenchido. Falta so o id pra garantir que nao duplique fabrica_de_pecas(&grid, p); i = posiciona_pecas(&grid); printf("Grade depois:\n"); mostra_grade(&grid); printf("Teste: posiciona uma unica peca\n"); return 0; }; // end main() E mostraria por exemplo Aí você pensa que já tem como compilar as peças e se cada uma tivesse nxn pixels e aí tem as regras e podia... ok parei.
-
Esse número 5 resolve mesmo. Só que não entendi
-
Olá fiquei curioso por esse algoritmo e pensei em algo mínimo que desse pra testar rápido. Tive sucesso com uma estrutura assim --- sem preocupação com performance: #define MAX_PINOS 10 #define MAX_X 20 #define MAX_Y 20 #define _LIVRE '*' #define _PONTO 'O' struct ponto { uint8_t X; uint8_t Y; }; typedef struct ponto Ponto; struct peca { uint8_t id; uint8_t H; uint8_t n_blocos; char* nome; Ponto pino[MAX_PINOS]; uint8_t W; }; typedef struct peca Peca; struct mapa { short total; Peca* peca[30]; Ponto* posicao[30]; short status[30]; }; typedef struct mapa Mapa; struct grade { uint8_t grade[MAX_X][MAX_Y]; Mapa* mapa; }; typedef struct grade Grade; Bem simples. A grade é o tabuleiro ou sei o nome. struct grade { uint8_t grade[MAX_X][MAX_Y]; Mapa* mapa; }; typedef struct grade Grade; tem um mapa associado à grade com as peças struct mapa { short total; Peca* peca[30]; Ponto* posicao[30]; short status[30]; }; typedef struct mapa Mapa; confesso uma certa preguiça ou ansiedade pra testar... o mapa tem uma lista de peças. As com status 0 terão posição definida na tela. as outras já tem. Os significados aqui são os óbvios: no mapa de total peças elas tem um vetor de posições e um de status as pecas tem um id único gerado na criação e um nome que pode ser repetido struct peca { uint8_t id; uint8_t H; uint8_t n_blocos; char* nome; Ponto pino[MAX_PINOS]; uint8_t W; }; typedef struct peca Peca; as peças tem um número máximo de pontos, definido em tempo de compilação uma pequena matriz na struct tem as coordenadas dos pontos todos, em relação ao ponto mais a esquerda e acima da peça cada peça tem uma largura e altura especificadas assim se pode posicionar aleatoriamente na tela cada ponto tem as coordenadas struct ponto { uint8_t X; uint8_t Y; }; typedef struct ponto Ponto; E é isso... Eis o header todo #pragma once #define _CRT_SECURE_NO_WARNINGS #define MAX_PINOS 10 #define MAX_X 20 #define MAX_Y 20 #define _LIVRE '*' #define _PONTO 'O' #include "stdint.h" #include "stdio.h" struct ponto { uint8_t X; uint8_t Y; }; typedef struct ponto Ponto; struct peca { uint8_t id; uint8_t H; uint8_t n_blocos; char* nome; Ponto pino[MAX_PINOS]; uint8_t W; }; typedef struct peca Peca; struct mapa { short total; Peca* peca[30]; Ponto* posicao[30]; short status[30]; }; typedef struct mapa Mapa; struct grade { uint8_t grade[MAX_X][MAX_Y]; Mapa* mapa; }; typedef struct grade Grade; Peca* cria_1_5(Grade*, char*); Peca* cria_5_1(Grade*, char*); Peca* fabrica_de_pecas(Grade*, Peca*); int inicia_grade(Grade*); int mostra_grade(Grade*); int mostra_peca(Peca*); int posiciona_pecas(Grade*); int posiciona_um(Grade*,uint8_t); Eis um exemplo para uma coluna de 1x5 pontos vertical { // horizontal Peca* p = (Peca*)malloc(sizeof(Peca)); if (p == NULL) return NULL; p->H = 5; p->n_blocos = 5; p->nome = nome; p->W = 1; p->pino[0].X = 0; p->pino[1].X = 0; p->pino[2].X = 0; p->pino[3].X = 0; p->pino[4].X = 0; p->pino[0].Y = 0; p->pino[1].Y = 1; p->pino[2].Y = 2; p->pino[3].Y = 3; p->pino[4].Y = 4; // preenchido. Falta so o id pra garantir que nao duplique return fabrica_de_pecas(g, p); } Assim quando se encontra a posição em que ela vai ficar é só aplicar as coordenadas da estrutura a partir da posição final na tela e verificar se há colisão...
-
C Porque não printar com letra colorida no windows?
arfneto respondeu ao tópico de Reberth Siqueira em C/C#/C++
Esses comandos, ESCAPE [ coisas --- ESCAPE = 0x1b = 27 ou octal 033 --- vem direto do terminal VT-100 da Digital depois Compaq hoje HP e é o terminal simulado pelo terminal do Unix, e Linux e derivados, como MAC OS Windows usa outro caminho mas estão convergindo nos últimos anos. Postei algo sobre isso tempos atrás com muitas referências. No Windows 10 isso está quase concluído --- a convergência. Uma razão pra se investir tanto tempo e dinheiro nisso nos últimos anos é que muitos pacotes de controle e monitoramento de rede e servidores Linux acabam sendo acessados por acesso remoto a partir de máquinas Windows e a tela é então controlada por esses comandos que o Windows até outro dia não tratava. E a aplicação fica confusa ou impossível de usar. Isso porque muitas vezes esses grandes computadores não tem interface gráfica afinal. Há um blog e um grupo de trabalho sobre isso na Microsoft. Se se interessar procure aquele tópico aqui no forum e terá muitas referências históricas e imagens. Com laptops de $500 vindo com telas 4K escrever em cores na console do Windows pode não justificar algum trabalho, bem como endereçar cursor e acertar cores para a console. Criar uma janela e mostrar os dados é, digamos, a razão de se ter uma interface gráfica afinal Se quer mesmo fazer isso e não quer perder muito tempo, crie uma rotina intermediária pra acessar a tela conforme o sistema que está rodando e use os comandos vt100 ou os da console do windows dentro da sua rotina conforme o caso, ou foque no Windows 10 pra frente e use as novas facilidades. Nos tempos pre-interface gráfica se usava uma biblioteca chamada curses, que depois evoluiu para ncurses sugerida por @KXSY e está até hoje disponível. É relativamente sofisticada e programas muito complexos tem sido escritos com isso. Com essas rotinas você pode controlar janelas, atributos, menus e cores e tal. Escrevi um editor de arquivos em hexa com isso nos anos 90. Mas hoje usaria uma interface gráfica, como todo mundo. Algumas são até portáveis como GTK+, Qt e wsWidgets... -
C Lista de Exercicio da faculdade - Dificuldade
arfneto respondeu ao tópico de Fabrizzio Farias Montanes em C/C#/C++
talvez deva perguntar cada coisa confusa especificamente... -
C Lista de Exercicio da faculdade - Dificuldade
arfneto respondeu ao tópico de Fabrizzio Farias Montanes em C/C#/C++
Bem, é quase isso, mas considere que não deve usar %d para imprimir a media, certo? %g ou %f para ponto flutuante. %d é para inteiro. Mas é isso. Compare com esse programa abaixo, que mostra .......... .......... .......... .......... ......... Depois de 49 parcelas: soma=3.49921, media=0.0714124 Esse #include "stdio.h" double funcao(int n){ return (double) 1. / (double)n; } int main(int argc, char** argv) { int itens = 0; double media = 0; for (int i = 2; i <= 50; i += 1) { itens += 1; media += funcao(i); printf("."); if (itens % 10 == 0) printf("\n"); }; // end for printf("\n"); printf("Depois de %d parcelas: soma=%g, media=%g\n\n", itens, media, (media/(double)itens) ); return 0; } -
C Lista de Exercicio da faculdade - Dificuldade
arfneto respondeu ao tópico de Fabrizzio Farias Montanes em C/C#/C++
@Fabrizzio Farias Montanes É só um loop, uma somatória -
Acontece que esse operador não era para isso: originalmente era o left-bit-shift, e desloca bits então é associativo à esquerda porque é onde está a base: Ex: int i = 32; int j; printf("%d<<2=%d\n", i, i << 2); j = i << 2 << 2; printf("%d << 2 << 2 =%d\n", i, j); j = (i << 2) << 2; printf("(%d << 2) << 2= %d\n", i, j); j = i << (2 << 2); printf("%d << (2 << 2)=%d\n", i, j); Mostra 32<<2=128 32 << 2 << 2 =512 (32 << 2) << 2= 512 32 << (2 << 2)=8192 Entendeu? Associativo à ESQUERDA. Sem parenteses executa primeiro o da esquerda E foi redefinido para tratar streams em C++, mas ele nasceu com essa outra personalidade, junto com o >> Até
-
C Realocamento interferindo em outras partes da memória (?)
arfneto respondeu ao tópico de milhodasilva em C/C#/C++
Porque nada garante que por exemplo a área apontada a partir de pc possa ser estendida por quando você tenha pedido. Por essa razão realloc() devolve um ponteiro para uma nova área, que tem o tamanho que você precisa. E isso pode ter implicado em copiar todo o bloco previamente alocado a partir de pc para o novo endereço, que a função vai te devolver. Se você não salvar, já era. Alocado foi. Acessível não é. Devia dar erro mas não dá. E se continuar usando o mesmo endereço base de antes, pc, como fazia, mais cedo ou mais tarde seu programa vai abortar por tentar acessar além do que tinha sido previamente alocado. E como eu disse, manipular esse valor --- pc++ por exemplo --- quase sempre vai cancelar seu programa ou mesmo seu sistema. Imagine quando você for liberar essa região: vai chamar free(0 usando qual endereço, já que perdeu esse? Sugiro de novo: não use isso. Use estruturas de dados mais sofisticadas, como listas, árvores, vetores de ponteiros e tal. realloc() tem esses efeitos colaterais. -
Talvez seja mais simples do que você pensou! Leia o programa que te mostrei. Atente para a execução dos construtores um a um até a classe base. Entenda que os métodos e variáveis vão passando adiante. É uma ideia genial eu acho. E o conceito chave é especialização não herança, eu acho. A classe derivada tem tudo que a classe base tinha. Pode estender algo, invalidar o que tinha ou redefinir o que tinha.
-
acho que eu já te mostrei um exemplo disso semanas atrás. E o programa que eu postei mostrava exatamente isso, além de redefinir mais uns 10 operadores como exemplo -- + - = == << e outros. Talvez deva dar uma olhada nesse programa. "Se ela não for não terá acesso ao conteúdo da classe" eu me referia claro a "Se ela não for declarada como friend não terá acesso ao conteúdo da classe". Só isso. A questão de não poder estar dentro da classe eu expliquei: esse operador << left bit shift é associativo à esquerda. Se colocar na classe só vai poder usar na situacão que mostrei no tópico anterior... Certo? Mas porque isso é importante? ----- Vou deixar uma copia do programa aqui pra você não ter que pesquisar conjunto.txt
-
Acho que pode usar teoria de conjuntos mesmo: uma peça é um conjunto de partes e tem então um conjunto de pontos. Elas colidem quando ao menos um desses pontos é compartilhado. Só isso. Escolha uma estrutura de dados e implemente assim. C++ ou java tem classes de conjuntos mesmo. Em C por exemplo usando listas e vetores estaria coberto. Sugestão: Pense assim: cada peça é um conjunto de pontos, pixels, bloco, o diabo. Defina um máximo de coordenadas para uma peça na matriz, como sua peça do exemplo tem cinco. Cada peça terá então um vetor desse tamanho com pares (x,y) Seu universo terá um número finito de peças, representadas cada uma por um vetor desses. Então sua matriz terá num dado momento um certo número de peças, correspondendo cada uma a um vetor desses. Defina a posição de cada peça como sendo por exemplo a coordenada com o menor (x,y) Crie uma função de comparação que vai definir a colisão Note que isso funcionam mesmo que as peças tenham "buracos" Só isso
-
Olá Acho que já discutimos isso aqui e eu até postei um pequeno programa que redefinia uns 10 operadores. Não tenho o endereço agora. Não é verdade. Não é obrigatório declarar a função de overload como amiga. Só conveniente. Se ela não for não terá acesso ao conteúdo da classe e você terá que usar getters. Só isso. Esse operador << é associativo à esquerda então para declarar dentro da classe fica quase inútil. Funcionaria para MinhaClasse a,b; e poderia escrever a << b; dependendo de como declarou tudo. Mas em geral o que se quer com << é redefinir para quando o operador à esquerda é... stream. Claro, você quer escrever cout << a porque é prático. E aí cai nessa situação que já discutimos Quando você escreve cout << a << b << endl; é avaliado assim (cout << a) << b << endl; primeiro. Os parenteses são ilustrativos. Não tente usar. cout << a retorna stream, stream<<b retorna stream, stream<<endl; retorna stream e aí sai na tela.
-
Não entendi o que significa
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