Ir ao conteúdo
  • Cadastre-se

arfneto

Membro Pleno
  • Posts

    6.227
  • Cadastrado em

  • Última visita

Tudo que arfneto postou

  1. Olá! Espero que tenha corrigido os erros todos já. E esse erro de concordância na mensagem do total deveria sumir também, afinal total é singular. Assim é: menor não significa muito. Legibilidade em especial num projeto grande conta muito. Num programa de estudante também. Mas no fim eficiência em termos de uso de memória e em tempo de execução são as condições que decidem como implementar um programa real. Esse exemplo: Um caso como esse geralmente é mais eficiente resolver com uma tabela de referência. É assim que os compiladores fazem, os processadores e tal. Você cria uma tabela e não compara mais. Só pega o resultado na tabela. look-up table é o que costuma aparecer nos livros. Uma solução comum seria assim: #define _CRT_SECURE_NO_WARNINGS #include "memory.h" #include "stdio.h" int main(int argc, char** argv) { char ref[256]; memset(ref, 0, 256); int n_vogais = 0; int n_espacos = 0; ref['a'] = ref['e'] = ref['i'] = ref['o'] = ref['u'] = 1; ref['A'] = ref['E'] = ref['I'] = ref['O'] = ref['U'] = 1; ref[' '] = 2; char palavra[80]; printf("Digite uma string: "); fgets(palavra, 80, stdin); int len = strlen(palavra) - 1; palavra[len] = 0; printf("Palavra: [%s] tamanho: '%d'\n", palavra, len); for (int i = 0; i < (int)strlen(palavra); i += 1) if (ref[palavra[i]] == 1) n_vogais += 1; else if (ref[palavra[i]] == 2) n_espacos += 1; printf("Sao %d vogais e %d espacos\n", n_vogais, n_espacos); return 0; }; // o_comum Mas pode melhorar um pouco... está chamando strlen() duas vezes, e uma delas é no teste do for() então vai chamar isso para cada letra da string: for (int i = 0; i < (int)strlen(palavra); i += 1) E tem esse if() if (ref[palavra[i]] == 1) n_vogais += 1; else if (ref[palavra[i]] == 2) n_espacos += 1; onde está consultando a tabela duas vezes e calculando dois índices: primeiro palavra e depois ref[palavra] e é claro que não precisa. Pode ser que o compilador perceba e otimize isso mas pode ser que não. Algo bem melhor #define _CRT_SECURE_NO_WARNINGS #include "memory.h" #include "stdio.h" int main(int argc, char** argv) { 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; char palavra[80]; printf("Digite uma string: "); fgets(palavra, 80, stdin); int len = strlen(palavra) - 1; palavra[len] = 0; printf("Palavra: [%s] tamanho: '%d'\n", palavra, len); int n_vogais = 0; int n_espacos = 0; char letra = 0; for (int i = 0; i < len; i += 1) { letra = ref[palavra[i]]; if (letra == 1) n_vogais += 1; else if (letra == 2) n_espacos += 1; }; // for() printf("Sao %d vogais e %d espacos\n", n_vogais, n_espacos); return 0; }; // main() Muito melhor assim: declara uma variável letra fora do loop e dentro faz a conta uma vez só. E o for() tem um valor constante na condição de saída e não um strlen(). Mas estamos usando strings e usando int. Não é preciso e pode sair caro em termos de memória e tempo de pesquisa. Podemos usar apenas char. Algo melhor ainda #define _CRT_SECURE_NO_WARNINGS #include "memory.h" #include "stdio.h" int main(int argc, char** argv) { 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; char palavra[80]; printf("Digite uma string: "); fgets(palavra, 80, stdin); char len = strlen(palavra) - 1; palavra[len] = 0; printf("Palavra: [%s] tamanho: '%d'\n", palavra, len); char n_vogais = 0; char n_espacos = 0; char letra = 0; for (char i = 0; i < len; i += 1) { letra = ref[palavra[i]]; if (letra == 1) n_vogais += 1; else if (letra == 2) n_espacos += 1; }; // for() printf("Sao %d vogais e %d espacos\n", n_vogais, n_espacos); return 0; }; // outro() Assim usa um byte e não 4 como um int e as comparações ficam mais rápidas com tudo operando em bytes. Se precisasse rodar em um mínimo de tempo acho que seria essa a opção. Se precisa avaliar mais condições você apenas altera o if e a tabela. É comum usar valores em potência de 2 e são chamados bit masks na literatura. Isso porque assim você pode testar por várias condições no mesmo valor usando operadores lógicos and &, or &, xor ^^ , not ! ...
  2. entendo Uma nota: pal[i]; é a mesma coisa que escrever *(pal +i) então isso trocar os [ ] de acordo Em relação à matemática, você não precisa lembrar da fórmula do ensino fundamental ou procurar por ela na internet simplesmente. Ou mesmo deduzir: Você pode fazer um programa e calcular num for o tamanho da string de saída e aí colocar de volta em seu programa. Ninguém vai saber. Veja para os 30 que você usou: int limite = 30; for (int i = 0; i < limite; i += 1) soma = soma + i; printf("limite para %d foi %d\n", limite, soma ); e vai ver: limite para 30 foi 435 e você soma um pro 0 no final e pronto: 436. Você declarou palavra2[30] e não usou porque ia cancelar o programa mesmo adicionado 2 minutos depois Claro que é melhor lembrar do ensino médio e escrever (1+29)*29/2... Mas ninguém vai saber afinal
  3. @paulorx10 Não pode usar índices... p = pal[i]; E não está criando a string de saída direito. Não calculou o o tamanho. Conforme eu expliquei, com exemplos do ensino médio,para 30 caracteres na entrada a saída vai ter nada menos que 436. Seu programa vai cancelar no 29.
  4. Pode ser assim como eu postei. o tal caso2(). depois mostro o outro Espero que ajude Claro que não precisava de tudo que eu escrevi. Podia só resolver o problema. Mas é um programa para estudantes. adicionado 24 minutos depois Isso seria o simples: lê a string, calcula a nova, preenche, mostra e apaga: int caso2_std() { char palavra[80]; printf("Digite uma string: "); fgets(palavra, 80, stdin); char ultima_letra = palavra[strlen(palavra) - 1]; int ultimo = strlen(palavra) - 1; // na nova string nao tem o '\n' palavra[ultimo] = 0; // apaga o tal newline int limite = (1 + ultimo) * ultimo / 2; char* nova = (char*)malloc(limite + 1); // nova string int idx_s = 0; // indice da saida. o da entrada e idx_e claro for (int idx_e = 0; idx_e < ultimo; idx_e += 1) { *(nova + idx_s) = *(palavra + idx_e); // copia a letra idx_s += 1; int nReplicas = idx_e; for (int j = 0; j < nReplicas; j += 1, idx_s += 1) *(nova + idx_s) = *(palavra + idx_e); // replica }; // for() *(nova + idx_s) = 0; // termina a string de saida printf("Entrada:\t[%s]\n", palavra); printf("Saida: \t[%s]\n", nova); free(nova); }; // caso2_str()
  5. @Lucca Rodrigues Eis o que posso dizer sobre o enunciado e o programa que eu eu esperaria que fosse feito se eu o tivesse escrito (o enunciado) Não fosse o texto começar por "leia uma string" o mais simples seria algo parecido com o que você fez, usando um único loop e gerando um número crescente de réplicas na string de saída, apenas alocando um número pequeno de bytes na entrada e aumentando aos poucos até terminar. E não usando índices, claro. Estão excluídos por definição. Mas o texto começa por "ler uma string" e uma string é uma sequência de caracteres seguidas por um 0 então pode também ter espaços. Não vou considerar ler a string direto na linha de comando, algo como programa.exe a string vem aqui toda ou programa.exe "a string vem aqui toda" no windows por exemplo. Isso seria mais prático e fácil mas por algum mistério os professores ignoram a linha de comando e os alunos só usam o IDE... Talvez depois eu escreva isso para mostrar a diferença. É mais simples um pouco, já que o sistema traz as palavras separadas. Por isso eu vou deixar aqui o caso2() apenas De volta ao programa, do jeito ortodoxo Tradicionalmente se lê a string usando gets() ou fgets() e essas rotinas vão devolver a string com um '\n' no fim. É claro que você não vai repetir e n-uplicar esse infeliz no final da string então precisa considerar isso no final do loop Calcular o tamanho da string remete ao ensino fundamental: hora = hoorrraaaa 4 => 10, mas veja a => a ou 1 => 1 ab => abb 2 => 1 + 2 = 3 abc => abbccc ==> 3 => 1 + 2 + 3 = 6 abcd => abbcccddd ==> 4 => 1 + 2 + 3 + 4 = 10 e assim por diante. Há muitos anos sabemos que isso é uma progressão aritmética de razão 1 e a soma é a soma do primeiro com o ultimo multiplicada pelo tamanho da série e divido por 2 para 2 => ((1+2) * 2) / 2 = 6/2 = 3 para 3 => (1+3) * 3) / 2 = 12/2 = 6 para 4 => (1+4) * 4 / 2 = 20/2 = 10 para n => (1+n)*n) / 2 Sem mistério A string de saída vai ter então esse tamanho mas o 0, o tal null, '\0' do final para que ela seja de fato uma string. Se você leu a string em palavra, veja essas variáveis meio que auto-explicativas char ultima_letra = palavra[strlen(palavra) - 1]; // essa letra deve ser o '\n' int ultimo = strlen(palavra) - 1; // na nova string nao tem o '\n' // e o limite sera entao int limite = (1 + ultimo) * ultimo / 2; // e o tamanho a alocar onclui o 0 no fim char* nova = (char*)malloc(limite + 1); // e em nova vai estar a string // se idx_e for o indice da entrada e // ids_s for o da saida // esse loop faz o serviço for (int idx_e = 0; idx_e < ultimo; idx_e += 1) { *(nova + idx_s) = *(palavra + idx_e); // copia a letra // avanca a saida idx_s += 1; // a posicao indica o numero de replicas int nReplicas = idx_e; for (int j = 0; j < nReplicas; j += 1, idx_s += 1) *(nova + idx_s) = *(palavra + idx_e); // replica }; // for() *(nova + idx_s) = 0; // termina a string de saida Veja a saída de um programa com comentários e um gabarito na saída pra ajudar a contar as posições Digite uma string: hora - Lidas 5 pos. - O ultimo valor da frase deve ser o tal newline '\n' codigo 10. Valor = '10' - E termina mesmo com newline - A entrada tem 4 letras: a saida vai ter 10 mais o '\0' no fim 0 1 2 3 4 * 5 0 * 0 * 0 * 0 * 0 * 0 Entrada: [hora] Saida: [hoorrraaaa] Uma saida para uma letra só Digite uma string: a - Lidas 2 pos. - O ultimo valor da frase deve ser o tal newline '\n' codigo 10. Valor = '10' - E termina mesmo com newline - A entrada tem 1 letras: a saida vai ter 1 mais o '\0' no fim 0 1 2 3 4 * 5 0 * 0 * 0 * 0 * 0 * 0 Entrada: [a] Saida: [a] Ou para umas letras com espaço no meio Digite uma string: e aumenta - Lidas 10 pos. - O ultimo valor da frase deve ser o tal newline '\n' codigo 10. Valor = '10' - E termina mesmo com newline - A entrada tem 9 letras: a saida vai ter 45 mais o '\0' no fim 0 1 2 3 4 * 5 0 * 0 * 0 * 0 * 0 * 0 Entrada: [e aumenta] Saida: [e aaauuuummmmmeeeeeennnnnnnttttttttaaaaaaaaa] E um programa com muitos comentários e que gera essa saída #define _CRT_SECURE_NO_WARNINGS #include "memory.h" #include "stdio.h" #include "stdlib.h" #include "string.h" int caso2(); int main(int argc, char** argv) { caso2(); return 0; } int caso2() { char palavra[80]; printf("Digite uma string: "); fgets(palavra, 80, stdin); printf(" - Lidas %d pos.\n", strlen(palavra)); char ultima_letra = palavra[strlen(palavra) - 1]; printf(" - O ultimo valor da frase deve ser o \ tal newline '\\n' codigo 10. Valor = '%d'\n", ultima_letra); if (ultima_letra == '\n') { printf(" - E termina mesmo com newline\n"); } else { printf(" - Mas termina com outra coisa\n"); }; // if() int ultimo = strlen(palavra) - 1; // na nova string nao tem o '\n' palavra[ultimo] = 0; // apaga o tal newline // qual vai ser o tamanho da nova string? // para 1 letra vai ser igual // para 2 vai ser 1 2 2 // para 3 vai ser 1 2 2 3 3 3 int limite = (1 + ultimo) * ultimo / 2; printf(" - A entrada tem %d letras: a saida vai \ ter %d mais o '\\0' no fim\n\n\n", ultimo, limite); // cria a nova string char* nova = (char*)malloc(limite + 1); // idx_e = indice na entrada // idx_s = indice na saida int idx_s = 0; for (int idx_e = 0; idx_e < ultimo; idx_e += 1) { *(nova + idx_s) = *(palavra + idx_e); // copia a letra // avanca a saida idx_s += 1; // a posicao indica o numero de replicas int nReplicas = idx_e; for (int j = 0; j < nReplicas; j += 1, idx_s += 1) *(nova + idx_s) = *(palavra + idx_e); // replica }; // for() *(nova + idx_s) = 0; // termina a string de saida printf("\t\t 0 1 2 3 4 * 5\n"); printf("\t\t 0 * 0 * 0 * 0 * 0 * 0\n"); printf("Entrada:\t[%s]\n", palavra); printf("Saida: \t[%s]\n", nova); free(nova); }; // caso2()
  6. @paulorx10 char palavra[30], palavra2[30]; Faltam algumas coisas para você considerar. Não está de fato criando a string porque ela está já declarada aí. Provavelmente se espera que ela seja alocada esse tamanho não vai ser suficiente. está duplicando o newline que tem no fim ao invés de suprimir. testou com "hora"? não pode usar índices. Veja o enunciado palavra2[j] = palavra[i]; @Lucca Rodrigues Mas você usou índices e não ponteiros duplicou o '\n' do final ao invés de tirar não criou a string
  7. Sempre há. É como o Adriano escreveu. Mas o seu deu errado porque gravou nos dois na mesma posição que o original e sempre vão ficar buracos de um lado ou de outro. Não se esqueça de testar com todos pares e todos ímpares....
  8. não. precisa de uma variável para marcar quantos pares já gravou e outra para os ímpares, ou vai zoar os dois vetores... int pos_par = 0; int pos_impar = 0; E quando for gravar no vetor use o índice certo e incremente
  9. for(i=0;i<8;i++) { printf("%d - ",vpr[i]); // testando se os números digitados estão sendo armazenados no vetor } printf("\n"); for(i=0;i<8;i++) { if(vpr[i] % 2 == 0) { vpar[i] = vpr[i]; } else { vimp[i] = vpr[i]; } } Sua ideia de se assegurar de que tem algo lá foi boa e por incrível que pareça não é comum. Muitos programas de estudantes não mostram as variáveis lidas para dar uma segurança... Mesmo o cara sabendo que pode apagar depois quando estiver funcionando. E o outro caminho, que seria acompanhar os valores no debugger, não é comum entre estudantes, outro erro. eu acho, mas aí dos instrutores Agora o segundo loop, que faz o serviço de separar, não partiu de uma boa ideia: você está até separando os caras em dois vetores, mas colocando na mesma posição em que eles estavam no vetor original. E claro que não tem controle sobre o que está nas outras posições. Se os primeiros forem pares e os 4 últimos ímpares você vai ter os pares nas posições de 0 a 3 do vetor par e os ímpares nas posições de 4 a 7 do vetor de ímpares. Mas e o resto dos vetores? Você tem que usar um índie para cada vetor e ir contando os caras... @herbertbahia tem razão no diagnóstico e na solução falta só entender que não pode usar o mesmo índice para os 3 vetores porque vai deixar buracos nos vetores de saída
  10. e? você tem um comentário? Uma pergunta?
  11. double x = 234.345; double y = 45.698; printf("%.6f - %.6f\n",x,y);//3 printf("%.0f - %.0f\n",x,y);//4 Você pode compilar e rodar isso em C++. printf() e double vão rodar igual. Se quer por alguma razão usar streams em C++ essas coisas estão no header <iomanip>. E como são streams em C++ você pode escrever uma função que recebe e retorna ostream e manipular os valores como precisar. Se precisar pergunte de novo e escrevo algo pra você ver. Veja uma descrição aqui http://www.cplusplus.com/reference/iomanip/ ou no seu manual ou compilador Eis um exemplo com seus valores #include <iomanip> #include <iostream> #include "stdio.h" using namespace std; int main() { double x = 234.345; double y = 45.698; cout << "os valores: " << x << " e " << y << endl; printf("\n(C) %.6f - %.6f\n", x, y); cout << "\n(C++) " << std::fixed << setprecision(6) << x << " - " << std::fixed << setprecision(6) << y << endl; printf("\n(C) %.2f - %.2f\n", x, y); cout << "\n(C++) " << std::fixed << setprecision(2) << x << " - " << std::fixed << setprecision(2) << y << endl; } O significado de cada modificador em cout é bem simples e poderia estar na mesma linha. Deixei assim para ficar mais fácil de ver causa e efeito. Entenda que cout é uma stream --- fluxo, corrente --- e o texto vai passando por cout para a tela Eis o que sai na tela os valores: 234.345 e 45.698 (C) 234.345000 - 45.698000 (C++) 234.345000 - 45.698000 (C) 234.34 - 45.70 (C++) 234.34 - 45.70
  12. Você tem um livro-texto? Sua escola adota um? Você tem uma apostila? Que pretende com esse comando? Ponha seu programa inteiro no post usando o botão code lá em cima, basta selecionar seu programa inteiro no editor e colar aqui dentro do tal code ... Você declarou char a,e,i,o,u; e magino que gostaria que lá dentro elas tivessem esses valores, as vogais. Só que você não colocou nada lá. e esse comando while(vogais[nome] == a,e,i,o,u)... mostra grande esperança na capacidade de compreensão do compilador. Você declarou int vogais = 0; Então esse é um int que vai ser o contador das tais vogais. E nome era char[40] e lá vai estar a frase afinal. Então você quer comparar as letras em nome[] que podem ir de 0 até 38 na verdade, e ver quantas delas são iguais a uma vogal. Mas você não inicializou as vogais com as vogais. Desculpe o trocadilho. Tipo a = 'a', b= 'b' e tal Não considerou as possíveis vogais maiúsculas usou vogais[nome] ao invés de nome[algo] já que o índice não pode ser o próprio int vogais ou vai zoar tudo Está muito longe de funcionar. Muito mesmo. Corrija isso ao menos e leia um pouco sobre os comandos
  13. O trecho que eu te mostrei é o programa. Você leu ao menos? Entendeu a parte em que eu expliquei para simplesmente retornar assim que tem uma resposta? E a parte do else? Para que duas funções para resolver um problema assim linear? Linear no sentido em que você verifica as condições uma a uma e termina assim que conclui algo. Você tem um livro-texto na sua escola? Todo curso tem isso. Qual é? Tem uma apostila ao menos? Notas de aula descrevendo por exemplo o comando switch()? Ou como declarar uma função? Eu acho muito importante ter um livro. Muitas escolas tem bibliotecas virtuais. Serviços que elas assinam e permitem que os alunos consultem livros on-line por exemplo. Sem custo. A função double tipo(double val1, double val2, double val3) { switch (((val1 == val2) && (val1 == val3) && (val2 == val3)) && ((val1 == val2) || (val1 == val3) || (val2 == val3))) { case 1: std::cout << "Os numeros inseridos formam um equilatero" << std::endl; break; case 2: std::cout << "Os numeros inseridos formam um isosceles" << std::endl; break; case 3: std::cout << "Os numeros inseridos formam um escaleno" << std::endl; break; } }; De todo modo, ao declarar uma função que retorna um float você precisa retornar algo, um float. Foi o que você declarou. No entanto sua lógica não retorna nada. Só uma resposta: com as medidas dadas é possível criar um triângulo? Ele é equilátero? Ele é isósceles? Então ele é escaleno... Só isso. O switch() switch é um comando de seleção e você seleciona a partir de uma constante. Você colocou uma expressão lá dentro. Que pretende? Direto de https://www.tutorialspoint.com/cprogramming/switch_statement_in_c.htm um site que você pode usar porque tem todas as definições e em geral com exemplos. A sintaxe do switch() switch(expression) { case constant-expression : statement(s); break; /* optional */ case constant-expression : statement(s); break; /* optional */ /* you can have any number of case statements */ default : /* Optional */ statement(s); } Assim é
  14. Isto está na biblioteca desde os compiladores de 16 bits. É uma quantia positiva apenas. Integral type size. Mas deve ser como você está dizendo então... adicionado 4 minutos depois E você deve ter uma referência séria disso, imagino. O único motivo? Onde leu isso? Ou escreveu isso? Então nunca foi ter um tamanho positivo limitado a INT_MAX e que a gente pudesse usar nas nossas rotinas sem ter que criar um a cada programa? Eu tenho usado isso em incontáveis programas desde o inçio dos anos 80 para ler valores positivos. Ainda bem que o pessoal de alocação de memória tem mantido essa variável lá.
  15. Sua definição é que está errada. Dos dois lados. gets() não foi escrita para "pegar strings" e sim para ler uma linha. Ela lê uma linha da entrada padrão, o que vier até o new_line ou até o fim de arquivo (control Z). Não lê uma string. gets() cria uma: ela lê até o \n ou fim de arquivo coloca num vetor e depois ACRESCENTA o \0 criando assim uma string. scanf() por outro lado não foi escrita para "pegar strings" e o nome dela vem do propósito: scan formatted input. Esse é o objetivo. scanf() é uma rotina ativa, que consome a entrada baseada numa máscara, tipo printf() e essa máscara, a tal string de formato, controla totalmente o comportamento dela, que pode incluir ou ignorar espaços e ' \n' inclusive. Tem razão. Ken Thompson escreveu isso eu creio. Entre outras coisas como grep, ed, sed, a noção de pipes, streams e tal. Muitas dessas funções vieram do diretório da máquina dele na Bell Labs no final dos '60 quando ele escreveu boa parte do Unix. Entre outras milhares de coisas ele escreveu depois com outros Go, a linguagem, Unicode, UTF-8... No caso de scanf() o plano era scan formatted input
  16. essa discussão não está levando a nada. Você não parece ter uma duvida, o autor do tópico não se manifestou, e eu não tenho muito mais pra dizer. Preste atenção: size_t não tem nada a ver com tamanhos de memória. É apenas uma quantidade, um tamanho: um size. em memcpy é um contador: o total de bytes copiado. Mesmo caso de strftime() onde é o tamanho de bytes da string de retorno. E na verdade é o mesmo caso de malloc(): não faria sentido alocar um valor negativo de bytes. O parâmetro de malloc é o total de BYTES. Só isso. Se você tem um livro sobre isso, ou mesmo se escreveu algum, deve estar assim, como em https://docs.microsoft.com/pt-br/cpp/c-runtime-library/reference/malloc?view=vs-2019 Ou https://www.tutorialspoint.com/c_standard_library/c_function_malloc.htm Ou talvez http://www.cplusplus.com/reference/cstdlib/malloc/ E você vê que size_t é, como está escrito bem aqui acima, um tipo inteiro sem sinal, um size.
  17. Você só repetiu o que está escrito lá. No entanto não é porque malloc() recebe um parâmetro size_t. Esse header nada tem a ver com malloc(). Como sabe, inúmeras funções esperam ou retornam size_t, para simplificar o uso de um valor unsigned com o tamanho adequado. memcpy() recebe size_t, strftime() retorna size_t,por exemplo. Estendendo um pouco o código de vcruntime.h: e você vê que size_t é simplesmente uma constante unsigned do tamanho adequado e você pode usar sem pensar. Se fossem 128 bits size_t estaria lá definida de acordo... Ou 256 #ifdef _WIN256... Quem somos os "nós" de "queremos"? Apenas bibliotecas que tivessem necessidade de gerar instruções 64 bits seriam afetadas afinal.
  18. Veja na resposta julgada como melhor lá no artigo Ou seja: democracia é isso. Cada voto vale um e não sei como votaram nisso como a melhor resposta. E a gente tem essas surpresas nas eleições também, claro. Não me surpreende que você tenha ficado confuso. O sujeito não conseguiu se expressar de modo algum. Não é que não fosse recomendado? viável? necessário? Vírgulas fora de posição, "Certas ocasiões" é sacanagem. "Pode acabar trazendo problemas" mas são "causados por descuido do próprio programador" Sério? Esqueça Veja uma fonte mais séria no C FAQ que é uma compilação http://c-faq.com/malloc/cast.html e vai ler por exemplo On the other hand, some programmers prefer to make every conversion explicit, to record that they have considered each case and decided exactly what should happen (see also question 17.5). Also, the casts are typically seen in C code which for one reason or another is intended to be compatible with C++, where explicit casts from void * are required malloc() retorna void* e todos os ponteiros tem o mesmo tamanho então não faz diferença. Mas... Do mesmo C FAQ Eu postei ontem ou antes um código em C C++ e java para calcular os DV do CPF e você pode ver lá como é parecido. Eu peguei um exemplo em C que eu tinha postado aqui e copiei e colei no editor em java e C++ e mudei umas poucas linhas. Pode ver lá. malloc() pode ser usada ao invés de new em C++ e quando você está portando um programa grande vai gostar de não ter que se preocupar em alterar cada chamada a malloc(). E dificilmente vai trocar todos malloc() por new e tal. Assim parece que o cara que escreveu no FAQ tinha razão. Eu sempre uso por questão de disciplina, pra deixar explícito o que estou fazendo. E com o hábito você não precisa ficar pensando em que linguagem está programando apenas para ter que inserir uma coisa tão simples como um cast. Eu sempre uso então se o próximo programa for em C++ não preciso pensar nisso. Eu nunca penso nisso Na resposta longa lá no C FAQ Mark Brader, o autor, cita no item (b) a minha opinião: Não gosto de conversões implícitas. De nada implícito. Não uso em geral comandos com efeitos colaterais, como atribuições dentro de comandos como printf() ou while() por exemplo. Não gosto de misturar operadores em expressões, tipo || > e + sem parenteses contando com a prioridade dos operadores. Coisas assim eu acho que levam a uma vida mais tranquila. Mas é claro uma opinião apenas. Entendo. Mas isso não é garantido. Vai depender da implementação e até hoje não vi uma razão para contar com isso. Nem para saber um pouco mais, na verdade. Códigos fonte de malloc() estão disponíveis, mas nunca tentei ler, confesso. size_t é um unsigned int ou o que estiver lá no header. Nada tem a ver com o ponteiro diretamente. Se o ponteiro for do tamanho de um int size_T será um unsigned desse tamanho. Compilar para 64 bits é uma opção de compilação e eu uso se tiver uma razão objetiva para usar. Não sabia da campanha para "matar binários de 64 bits". Porque alguém se preocupa com isso?
  19. arfneto

    C++ Data e hora em C++

    Você tentou ler a documentação? Tem um livro? Qual é? Uma apostila ao menos? Isso é bem simples, não sei o que dizer. Se você sabe usar printf() sabe usar isso. Se não sabe usar printf() seu problema não é strftime(). Você pega a hora, põe na tabela, formata como quer e usa. strftime() é um printf() para hora Essa rotina pega uma hora e um formato e gera uma string. Só isso. Como um printf("%s\n", "16/04/20"); Que mostra você sabe o que. Só que para strftime() é preciso avisar qual a data que quer usar. Igualzinho ao printf(). Leu ao menos a declaração de strftime()? Aqui está size_t strftime( char *str, size_t maxsize, const char *format, const struct tm *timeptr); Como ler um trem desses? Você precisa saber a declaração de uma função... Não tem outro jeito. E é simples. Ela retorna algo do tipo size_t. um número sem sinal, uma quantia. Adivinha o que é... O tamanho da string que ele gerou, tipo para "12/01/2002" strftime() retorna 10 porque você precisa saber o tamanho para por na tela. OK, nem sempre. mas muitas vezes você precisa e é muito gentil a rotina devolver o número para você não ter que fazer o óbvio e chamar strlen() na linha de baixo. str Sem surpresas: você precisa dizer onde vai gravar sua string certo? É aí. char* claro, porque é uma string. maxsize Dá pra imaginar o que é: o tamanho máximo que pode usar em str. Porque dependendo do que você pedir o tamanho pode variar muito. Você pode querer so "11:35" para por um horário na tela, ou uma expressão grande com dia da semana, ano e hora com segundos... size_T claro porque é uma quantia positiva e algum maluco poderia chamar com -23 format Complicado? Claro que format é descrição do que você quer. Numa convenção igual a que está acostumado a usar com printf() e scanf(). É uma string. Simples como essa aqui: const char* f_dia_mes_ano = "%d de %B de %Y"; const char* para você poder usar por exemplo "%d/%B/%Y" direto na chamada sem ter que criar uma variável para isso timeptr Você já sabia que a data tinha que vir de algum lugar. É desse: você passa o endereço de uma estrutura dessas, onde está o tal tempo que você quer formatar. Nem sempre você quer a data e hora de agora mesmo certo? E o que tem nessa p$%%a? Dá pra imaginar, um horário. Mas não precisa imaginar porque vou te mostrar struct tm { int tm_sec; // seconds after the minute - [0, 60] including leap second int tm_min; // minutes after the hour - [0, 59] int tm_hour; // hours since midnight - [0, 23] int tm_mday; // day of the month - [1, 31] int tm_mon; // months since January - [0, 11] int tm_year; // years since 1900 int tm_wday; // days since Sunday - [0, 6] int tm_yday; // days since January 1 - [0, 365] int tm_isdst; // daylight savings time flag }; Bem óbvio, um horário. Completo. Em C você o tempo é contado a partir de jan 1970. Não foi ideia minha. E como preencher isso? Simples: você declara uma estrutura dessas e chama time() para preencher para você. Com que hora se você quiser agora mesmo? Algo assim: time_t agora_mesmo; agora_mesmo = time(&agora_mesmo); Aí você tem a hora que você quer. Precisa preencher aquela estrutura tm com essa hora. Claro que poderia ter feito na mesma linha mas isso aqui é pra explicar e não resumir Formulario_da_hora* tabela; tabela = localtime(&agora_mesmo); Complexo? Você vê a hora, preenche a estrutura e formata como você quer. Faz sentido. Porque localtime()? Porque tem que incorporar a noção de fuso horário no ... horário. Assim é com as horas. Veja uma tabela aqui https://www.tutorialspoint.com/c_standard_library/c_function_strftime.htm Claro, tem um resumo Pode ver mais no manual. Mas é o óbvio: formata as quantias que estão na tal tabela tm. Veja uns formatos const char* f_dia_mes_ano = "%d de %B de %Y"; const char* f_data_com_dia_da_semana = "%A, %d de %B de %Y"; const char* f_hhmmss = "%H:%M:%S"; const char* f_com_preguica = "%c"; Que mostram Dia, nome do mes, ano com 4 digitos '16 de April de 2020' Agora com o dia da semana 'Thursday, 16 de April de 2020' Depois do setlocale() 'quinta-feira, 16 de abril de 2020' Hora Minuto Segundo: '13:00:23' Com preguica, usando so %c: '16/04/2020 13:00:23' A segunda e a terceira linha estão aí para você ver que precisa usar setlocale() para cada usar os nomes adequados para a região onde vai rodar o seu programa. Não é complicado: é o mundo. Tem que traduzir os dias da semana se você quer que saia no idioma local. Um exemplo, esse exemplo: #define _CRT_SECURE_NO_WARNINGS #include "locale.h" #include "math.h" #include "stdio.h" #include "time.h" typedef struct tm Formulario_da_hora; int main(int argc, char** argv) { char texto[80]; char* pHoraFormatada = texto; const char* f_dia_mes_ano = "%d de %B de %Y"; const char* f_data_com_dia_da_semana = "%A, %d de %B de %Y"; const char* f_hhmmss = "%H:%M:%S"; const char* f_com_preguica = "%c"; time_t agora_mesmo; agora_mesmo = time(&agora_mesmo); Formulario_da_hora* tabela; tabela = localtime(&agora_mesmo); strftime(pHoraFormatada, 80, f_dia_mes_ano, tabela); printf("\nDia, nome do mes, ano com 4 digitos '%s'\n", texto); strftime(pHoraFormatada, 80, f_data_com_dia_da_semana, tabela); printf("\nAgora com o dia da semana '%s'\n", texto); setlocale(LC_ALL, "Portuguese"); strftime(pHoraFormatada, 80, f_data_com_dia_da_semana, tabela); printf("\nDepois do setlocale() '%s'\n", texto); strftime(pHoraFormatada, 80, f_hhmmss, tabela); printf("\nHora Minuto Segundo: '%s'\n", texto); strftime(pHoraFormatada, 80, f_com_preguica, tabela); printf("\nCom preguica, usando so %%c: '%s'\n", texto); return 0; }; // main() Sobre API Está sim usando uma API. API é uma abreviatura para Application Programming Interface, interface para programação de aplicações. E todo header é em essência uma API: ele faz exatamente isso: declara a interface para você usar o que está la dentro. Veja DENTRO de time.h a API para chamar strftime() A API do windows é exposta (essa é a terminologia em português, creio) em boa parte em windows.h por exemplo
  20. Mas que compilador vai usar? Leu a documentação? Vai usar no Windows? Windows 10 recente? ou no Linux ou no Mac? Vai compilar os programas no Windows pro Windows ou no Linux do Windows 10? O ambiente do VSCode é muito moderno e bonito. E tem umas funcionalidades fora do normal, como usar o debugger numa aplicação rodando no Linux sentado na máquina Windows com os arquivos no Windows e o código rodando no Linux. Mas não inclui um compilador. Você precisa instalar um, ou o Visual Studio Build Tools. E precisa configurar dois arquivos ao menos, e é meio automático, lá em Terminal | ... Como aparece aqui Esses no fim da lista. E aí pode escolher o que fazer na lista. Ou apertar F5 para rodar no debugger e Control F5 para rodar no modo normal. Claro, vai gerar o .exe e você roda em qualuqer lugar Veja nesse caso a máquina tem dois compiladores disponíveis. Veja o que diz na documentação Se você não usa Visual Studio e não tem um outro compilador instalado, pode instalar o da MicroSoft em https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019
  21. arfneto

    C++ Passar alg para app

    C++ está bem já. Esses sistemas foram todos escritos em C e C++ afinal. Games e outras aplicações de performance são escritas em C++ ao menos para Android Leia esse artigo e veja ao final tem muitas referencias https://medium.com/androiddevelopers/getting-started-with-c-and-android-native-activities-2213b402ffff E em especial veja https://developer.android.com/ndk aqui
  22. Não. Não é. E nesse caso aí você pode usar de i[0] a i[899]. Se tentar usar algo além disso seu programa vai cancelar. E de 101 a 999 são 899 valores apenas. E como usou i no vetor não pode usar de novo como índice no for
  23. Não entendi o que quer dizer. sizeof() é um operador. malloc() recebe um parâmetro, do tipo size_t malloc() reserva um espaço em bytes igual ao parâmetro. Em muitos casos não se quer alocar em bytes, mas sim em unidades de seja lá o que for que estamos alocando, e assim se escreve por exemplo Coisa* coisa = (Coisa*) malloc( N * sizeof(Coisa)); para alocar uma área equivalente a N vezes o tamanho de coisa. E parece java escrito assim Mas se pode escrever size_t tamanho = N * sizeof(Coisa); Coisa* coisa = (Coisa*) malloc(tamanho); size_t em geral é um unsigned int no meu caso definido em vcruntime.h
  24. do { int potencia(int A,int ) if ((A >= 1 && B >= 1)) ... Você declarou uma função no meio do loop? Qual o propósito de NÃO usar variáveis chamadas base e expoente por exemplo, para que você ou outro que viesse a ler seu programa não tivesse que perder tempo para descobrir qual variável é o que? A e B ou y ou yx ou jj ... tanto faz
  25. Eu postei um programa aqui que fazia isso mas não sei como procurar. A resposta curta é NÃO. Não dá para saber quanto alocou ou quando pode alocar. Vai depender claro da memória livre em sua máquina no momento do malloc(), e isso vai variar conforme o que está rodando num dado momento. O programa que eu tinha feito você pode refazer em minutos: era algo como uma busca binária tentando alocar um valor. Mas claro de você pode alocar de 1K em 1K ou 128K ou algo que ache relevante, Ou mesmo byte a byte. As máquinas são muito rápidas hoje em dia: O que eu tinha feito era alocar 1K e ir dobrando até estourar e a partir daí alocando de novo a partir da metade, e assim por diante. Em uma fração de segundo você tem o valor em K bytes( ou como preferir) que pode alocar no momento. Se precisar eu escrevo outro exemplo. Me avise. Mas isso vai contra o próprio sentido de alocação dinâmica: você aloca o quanto precisa e libera assim que puder. Quando você passa a não conseguir mais parte para uma máquina com mais memória ou muda a sua lógica, por exemplo paginando seus dados e usando o disco. Nada original. Todos os sistemas fazem isso.

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