Ir ao conteúdo
  • Cadastre-se

Ansi C

Membro Pleno
  • Posts

    3.259
  • Cadastrado em

  • Última visita

Tudo que Ansi C postou

  1. Então diga qual a versão que gostaria de ter visto, certamente não aquele que usou no programa abaixo (de tua autoria): int main(void) { int* de = (int[5]){1, 2, 3, 4, 5}; int* ate = de + 3; exibir_numeros(de, ate); exibir_numeros(ate, de); // tenta ao contrario return 0; } int exibir_numeros(int* ini, int* fim) { if (ini == NULL) return -1; if (fim == NULL) return -1; printf("\nMostra valores de 0x%p a 0x%p (inclusive)\n", ini, fim); if (ini > fim) { printf("\nx: 0x%p e maior que u_: 0x%p\n", ini, fim); return -1; } int* p = ini; printf("Valores: ["); for (int* p = ini; p <= fim; p += 1) printf(" %d", *p); printf(" ]\n"); return 0; } A saída tem "0x0x..." porque a string de formato tem um padrão fora do especificador! Qual o compilador que gera programas sem esse padrão para justificar eles na printf? Então (eu penso que) não pode ou nem sequer deveria tentar, já que é inútil e perigoso. Olhe! Eu sinceramente desisto, não é possível entender seus comentários. — Eu agradeço! Agora sei, entendi... tudo faz muito sentido. Tks! Obrigado!
  2. Está dizendo que as versões instaladas (compiladores) não são escritas conforme uma norma! Esse comentário ficou estranho. — para mim já temos o bastante de discussão sobre main, parâmetros, argumentos e variáveis não utilizadas. FUI!
  3. Tá! Mas, essa é uma resposta a uma pergunta que ser que fiz. Bom! O mesmo que entendi, não a razão para escrever main com parâmetros em sistemas simples ou quando não pretende utilizar. — Legal!
  4. Não faz sentiddo uma norma iso C, não ter nada a ver com C. Então, que tivesse dito com o que tem a ver, senão com C. Com Java, tudo tem a ver com JAVA mesmo OK! Mas, como isso explica o porquê declarar ou não parâmetros na função main, caso tenha sido uma tentativa de explicar refaço a pergunta. Qual o sentido para declarar parâmetro|variável e não utilizá-la? Ata! Também não, por isso perguntei talvez tivesse algo a mais especialista, porém não há razão fundamental. Ainda sim, não existem parâmetros (na função), não difere tanto assim de int main (void). Ok! Mas, que justificativa é essa (principalmente porque não entendi). Então, experimentemos isso fora do prompt, e daí será que essa tal filosofia|religião tem mais adeptos (online). Por exemplo, com solicitação na impressão de arquivo. Outro no prompt — Filosofia...
  5. A norma é complicada ou será que precisa de hábitos de leitura para acostumar com seu conteúdo, é muito formal|normal Caso tenha "leiteiros" iguais a mim que também não clicam em links de postagem, mas curte imagens|recortes de uma Normal (rascunho de Normal 2021), segue abaixo. Cansei de encontrar exemplos com argumento vazio ou indeterminado, nenhum desses exemplos tinha por objetivo escrever chamada recursiva da int main! A impressão que tiro dos exemplos é educar para não declarar desnecessariamente parâmetros|variáveis. Esse recorte é do especificar de impressão "%p" [Tradução]: Logo, se ativa o alerta (avisos) o compilador deve ter uma recomendação semelhante. Mas, curioso mesmo é a Norma deixar a impressão por conta da implementação, porque algumas podem corretamente escrever 0x... e outras não, daí fica o questionamento... não por quê? - ???
  6. Penso que talvez esclareça melhor se falar o que significa não usar um variável|parâmetro|argumento?
  7. Discordo que esteja pouco fora do tópico. É o contrário... a discussão é pertinente não somente às dúvidas com ponteiros: fragilidade, riscos e problematização de programar com linguagem de baixo nível igual à linguagem C (objeto primeiro da discussão), como também expressa importantes informações acerca de compiladores, protótipos de função, desperdício de memória, experimento de sintaxe, etc. A verdade, é que tudo está relacionado. Ou seja, a main não difere muito de outras funções: se tem argumento são alocados, senão... obvio não se reserva nada, tal qual todas as outras funções... logo quem programou o compilador tem razão, como é de se esperar. A escolha de palavras é típica de pessoa com muito idade (pensando bem isso não é preconceito é conceito), mas se ficou ofendido, eu retiro o que disse e permaneço dizendo que, refira-se ao meu nick name do mesmo modo que faz com os outros. De fato, não há nada de especial, muito comum.
  8. Senhor..., que isso..., haja cordialidade..., além disso, evidente que és mais velho, logo dirija-se a meu nick name da mesma maneira que faz com demais. Com relação aos seus exemplos, agradeço muitíssimo, são tão caprichosos, nota-se o esforço para escrever sempre o melhor. O que digo: parabéns! Essa é uma informação pertinente, obrigado por compartilhar que eu não devo usar MSVC, se bem que nunca usei mesmo, então é soma de zeros. Na próxima vez vou simplesmente ignorar. Seria interessante, talvez antes de postar seus resultados, informasse também no topo qual o modelo do compilador, considere isso! É claro que eu notei sua intenção, e fiz igual mesmo... mostrei um exemplo análogo ao seu, no mínimo reforçando sua intenção, agora não resta dúvida quanto a fragilidade|usabilidade dos ponteiros. Ponteiros são velozes, mas sua usabilidade tem risco. Alguém ainda tem dúvida disso? Sabemos que isso está relacionado ao grau de liberdade dos ponteiros não existe maneira mais frágeis ou menos frágeis. Só frágeis: usei um exemplo que utiliza pilha, a falha não é imediata talvez não acontecesse desde que ficasse na pilha, um espaço alocado. Penso que, foi isso. Nota agora que apenas não considero interessante utilizar memória heap (alocação dinâmica de variáveis) para um experimento de risco, apesar de baixo. Só isso! MINHA OPINIÃO? Seja honesto... porque a opinião não é somente minha, mas também daqueles que implementam compiladores, o aviso não é exclusivo para alertar o desperdício de variável com assinaturas e argumentos da main, como está pretendendo educar com seu discursa dirigido à terceira pessoa, mas sim para desperdícios no programa. Ainda que não fossem ativados, pense... qual o sentido de escrever o protótipo da main com argumentos que não pretende utilizar? Apenas para reforça um correto, assim a maioria dos códigos iniciantes, a proposito quase sempre desse fórum, escreveríamos exemplos com dois argumentos e não com nenhum, sendo nenhum a maioria. Em resumo são 4 protótipos: 1. int main(int, int **); 2. int main(int, int *[]); 3. int main(void); 4. int main(); Quando não se dar utilidade para argumentos, recomenda (aviso) utilizar as assinaturas 3, 4 Aviso pega até os desperdícios menores: Desperdício e desperdício não importa o tamanho. Só observo seu conhecimento acerca da elite! Não entendi!
  9. Ps.: Apenas por curiosidade: o for difere tanto assim de WHILE. Escolher entre um e outro é o quê? int exibir_numeros(int* ini, int* fim) { if (ini == NULL) return -1; if (fim == NULL) return -1; printf("\nMostra valores de 0x%p a 0x%p (inclusive)\n", ini, fim); if (ini > fim) { printf("\nx: 0x%p e maior que u_: 0x%p\n", ini, fim); return -1; } int* p = ini; printf("Valores: ["); for (int* p = ini; p <= fim; p += 1) printf(" %d", *p); printf(" ]\n"); return 0; } --------------------------------------------------------------------------------- .LC0: .string "\nMostra valores de 0x%p a 0x%p (inclusive)\n" .LC1: .string "\nx: 0x%p e maior que u_: 0x%p\n" .LC2: .string "Valores: [" .LC3: .string " %d" .LC4: .string " ]" exibir_numeros: push rbp mov rbp, rsp sub rsp, 32 mov QWORD PTR [rbp-24], rdi mov QWORD PTR [rbp-32], rsi cmp QWORD PTR [rbp-24], 0 jne .L2 mov eax, -1 jmp .L3 .L2: cmp QWORD PTR [rbp-32], 0 jne .L4 mov eax, -1 jmp .L3 .L4: mov rdx, QWORD PTR [rbp-32] mov rax, QWORD PTR [rbp-24] mov rsi, rax mov edi, OFFSET FLAT:.LC0 mov eax, 0 call printf mov rax, QWORD PTR [rbp-24] cmp rax, QWORD PTR [rbp-32] jbe .L5 mov rdx, QWORD PTR [rbp-32] mov rax, QWORD PTR [rbp-24] mov rsi, rax mov edi, OFFSET FLAT:.LC1 mov eax, 0 call printf mov eax, -1 jmp .L3 .L5: mov rax, QWORD PTR [rbp-24] mov QWORD PTR [rbp-16], rax mov edi, OFFSET FLAT:.LC2 mov eax, 0 call printf mov rax, QWORD PTR [rbp-24] mov QWORD PTR [rbp-8], rax jmp .L6 .L7: mov rax, QWORD PTR [rbp-8] mov eax, DWORD PTR [rax] mov esi, eax mov edi, OFFSET FLAT:.LC3 mov eax, 0 call printf add QWORD PTR [rbp-8], 4 .L6: mov rax, QWORD PTR [rbp-8] cmp rax, QWORD PTR [rbp-32] jbe .L7 mov edi, OFFSET FLAT:.LC4 call puts mov eax, 0 .L3: leave ret --------------------------------------------------------------------------------- --------------------------------------------------------------------------------- int exibir_numeros(int* ini, int* fim) { if (ini == NULL) return -1; if (fim == NULL) return -1; printf("\nMostra valores de 0x%p a 0x%p (inclusive)\n", ini, fim); if (ini > fim) { printf("\nx: 0x%p e maior que u_: 0x%p\n", ini, fim); return -1; } printf("Valores: ["); { int* p = ini; while (p <= fim){ printf(" %d", *p); ++p; } } printf(" ]\n"); return 0; } ----------------------------------------------------------------------------------- .LC0: .string "\nMostra valores de 0x%p a 0x%p (inclusive)\n" .LC1: .string "\nx: 0x%p e maior que u_: 0x%p\n" .LC2: .string "Valores: [" .LC3: .string " %d" .LC4: .string " ]" exibir_numeros: push rbp mov rbp, rsp sub rsp, 32 mov QWORD PTR [rbp-24], rdi mov QWORD PTR [rbp-32], rsi cmp QWORD PTR [rbp-24], 0 jne .L2 mov eax, -1 jmp .L3 .L2: cmp QWORD PTR [rbp-32], 0 jne .L4 mov eax, -1 jmp .L3 .L4: mov rdx, QWORD PTR [rbp-32] mov rax, QWORD PTR [rbp-24] mov rsi, rax mov edi, OFFSET FLAT:.LC0 mov eax, 0 call printf mov rax, QWORD PTR [rbp-24] cmp rax, QWORD PTR [rbp-32] jbe .L5 mov rdx, QWORD PTR [rbp-32] mov rax, QWORD PTR [rbp-24] mov rsi, rax mov edi, OFFSET FLAT:.LC1 mov eax, 0 call printf mov eax, -1 jmp .L3 .L5: mov edi, OFFSET FLAT:.LC2 mov eax, 0 call printf mov rax, QWORD PTR [rbp-24] mov QWORD PTR [rbp-8], rax jmp .L6 .L7: mov rax, QWORD PTR [rbp-8] mov eax, DWORD PTR [rax] mov esi, eax mov edi, OFFSET FLAT:.LC3 mov eax, 0 call printf add QWORD PTR [rbp-8], 4 .L6: mov rax, QWORD PTR [rbp-8] cmp rax, QWORD PTR [rbp-32] jbe .L7 mov edi, OFFSET FLAT:.LC4 call puts mov eax, 0 .L3: leave ret
  10. — Dica final: ative os alerta do compilador, lembre-se, ele foi/é desenvolvido com ajuda da Elite da Programação.
  11. O acesso é desreferenciar seguindo de leitura|gravação, isto é, se não desreferenciar um ponteiro com endereço ainda não alocado, não acontece a falha de segmentação, evidente que nada impede o programador de passar um endereço desalocado e com isso causar falha por engano|intencional|experimental. Uma estratégia é definir limite logicamente inválido: Como é o caso das ‘strings’ com ‘byte’ 0, outro exemplo é uma lista de idades com idade negativo, até mesmo fornecer o capacidade|tamanho|quantidade das variáveis vizinhas (vetor). Nesse último caso, o primeiro elemento do vetor (primeira variável) tem o seu tamanho e a implementação (função que operará esse vetor) tem potencial para captar esse tamanho, ainda assim, nada impediria um argumento qualquer nessas funções de causar falha lógica ou intencional. Não é O protótipo da main, mas sim UM protótipo da main, essa diferença é importante, apesar de parecer uma pouco pedante... A elite de programadores em C chegou no consenso de que há situações em que esses argumentos são dispensáveis, por conta disso tanto a norma quando os compiladores modernos são inflexíveis quando à declaração int main(...). Sendo main(int argc, char *arg[]) Sendo main(void) Sendo main() Sendo main(int argc, char **arg) Sendo que dois explicitamente descarta argumentos para aquelas situações em que são descartáveis. Observe que na sua exemplificação de como causar uma falha modificou o índice de um ponteiro. Nesse caso: Veja seu análogo: int exibir_numeros(int* ini, int* fim) { if (ini == NULL) return -1; if (fim == NULL) return -1; printf("\nMostra valores de 0x%p a 0x%p (inclusive)\n", ini, fim[100]); if (ini > fim) { printf("\nx: 0x%p e maior que u_: 0x%p\n", ini, fim[100]); return -1; } int* p = ini; printf("Valores: ["); for (int* p = ini; p <= fim; p += 1) printf(" %d", p[100]); printf(" ]\n"); return 0; } Nada difere em nada . Com relação os argumentos da função pensei o mesmo que a Elite da Programação, porém com há discussão de duplos ponteiros continuei seguindo contagiado. Concordo não haver garantia.
  12. É impossível, pois o ponteiro (sendo uma variável) tem um número tal qual uma variável do tipo inteiro. Para impedir que acesse, é necessário pelo menos mais um ponteiro e com o número desse limite. Desse modo, um ponteiro é o início (a_) e o outro o fim (u_), note haver necessidade de modifique a expressão para duplo ponteiro. Exemplo. #include<stdio.h> #include<stdlib.h> void exibir_numeros (int **nums); int main(void){ int *a_ = (int [5]) {1,2,3,4,5}; int *u_ = a_ + 4; int **nums = (int * [2]) {a_, u_}; exibir_numeros(nums); return 0; } void exibir_numeros(int **nums){ int *x = nums[0]; while (x <= nums[1]){ printf(" %d ", x++[0]); } if (x > nums[1]){ printf("\nx: %p e maior que u_: %p\n", (void*)x, (void*)nums[1]); } return; } Sabe que nums[0] tem o mesmo endereço que em a_ e nums[1] o mesmo que u_. A expressão de controle do “loop” (while) testa se o endereço na x é menor_ou_igual _a nums[1], quando diferente interrompe o “loop” impedindo acesso fora do alocado. O ponteiro que tem o endereço de memória não alocado ainda não acessa esse local se não desreferenciar. Quase! Mas, use o especificado ("%p") designado para imprimir pointes e realize o cast para void *. Se ainda tem dúvida, pergunte. — Dica final: ative os alerta do compilador, lembre-se, ele foi/é desenvolvido com ajuda da Elite da Programação.
  13. Essa expressão está correta? Sim porque a notação está correta, sabemos que notação de ponteiros é trocável por vetor. Um dublo ponteiro é o tipo que guardar o endereço de um ponteiro, se desreferenciar ele poderá ler seu conteúdo: o endereço de um ponteiro. Se declarar: int **ponteiros = (int * [4]) {NULL}; Alocará da pilha 4 ponteiros vizinhos (vetor de ponteiros) e atribuirá a 'ponteiros' o primeiro endereço. Se declarar: int *_0inteiros = (int [5]) {0}; int *_1inteiros = (int [5]) {1}; int *_2inteiros = (int [5]) {2}; int *_3inteiros = (int [5]) {3}; Alocará da pilha, sequencialmente, 4 vetores (int) e 4 ponteiros e atribuirá o endereço respectivamente. Agora tenho dois tipos derivados de int: 1 ponteiros e 4 inteiros, continue... ponteiros[0] = _0inteiros; ponteiros[1] = _1inteiros; ponteiros[2] = _2inteiros; ponteiros[3] = _3inteiros; Quando desreferenciar 'ponteiros' terá acesso a uma das 4 variáveis do vetor, no casso acima, é atribuído o endereço dos _Xinteiros de 0 á 3. Em seguida poderá gravar ou ler valores nas 'inteiros'. A assinatura [Y][X] acessa um dos endereços na '_Xinteiros' conforme os valore de Y, X e converte em variável do tipo int. Exemplo: #include <stdio.h> #include <stdlib.h> int main(){ int **ponteiros = (int * [4]) {NULL}; int *_0inteiros = (int [5]) {0,1,2,3,4}; int *_1inteiros = (int [5]) {1,2,3,4,5}; int *_2inteiros = (int [5]) {2,3,4,5,6}; int *_3inteiros = (int [5]) {3,4,5,6,7}; ponteiros[0] = _0inteiros; ponteiros[1] = _1inteiros; ponteiros[2] = _2inteiros; ponteiros[3] = _3inteiros; for(int i = 0; i < 4; ++i){ for(int j = 0; j < 5; ++j){ printf (" %d ", ponteiros[i][j]); } putchar('\n'); } printf("ponteiros[0][3]: %d\n", ponteiros[0][3]); } O mesmo exemplo e com argumento de função: #include <stdio.h> #include <stdlib.h> void print(int **m, int x, int y); int main(){ int **ponteiros = (int * [4]) {NULL}; int *_0inteiros = (int [5]) {0,1,2,3,4}; int *_1inteiros = (int [5]) {1,2,3,4,5}; int *_2inteiros = (int [5]) {2,3,4,5,6}; int *_3inteiros = (int [5]) {3,4,5,6,7}; ponteiros[0] = _0inteiros; ponteiros[1] = _1inteiros; ponteiros[2] = _2inteiros; ponteiros[3] = _3inteiros; print (ponteiros, 5, 4); printf("ponteiros[0][3]: %d\n", ponteiros[0][3]); } void print (int **m, int x, int y){ for(int i = 0; i < y; ++i){ for(int j = 0; j < x; ++j){ printf (" %d ", m[i][j]); } putchar('\n'); } return; } Observe o mesmo exemplo com uso da malloc #include <stdio.h> #include <stdlib.h> void print(int **m, int x, int y); int main(){ int **ponteiros = malloc (sizeof(int * [5])); int *_0inteiros = (int [5]) {0,1,2,3,4}; int *_1inteiros = (int [5]) {1,2,3,4,5}; int *_2inteiros = (int [5]) {2,3,4,5,6}; int *_3inteiros = (int [5]) {3,4,5,6,7}; ponteiros[0] = _0inteiros; ponteiros[1] = _1inteiros; ponteiros[2] = _2inteiros; ponteiros[3] = _3inteiros; print (ponteiros, 5, 4); printf("ponteiros[0][3]: %d\n", ponteiros[0][3]); free (ponteiros); } void print (int **m, int x, int y){ for(int i = 0; i < y; ++i){ for(int j = 0; j < x; ++j){ printf (" %d ", m[i][j]); } putchar('\n'); } return; } Ops! Algo deu errado. Os compiladores modernos são escritos por programadores de altíssimo desempenho só os melhores da categoria, PhD, engenheiros, homens e mulheres, jovens que se dedicaram/dedicam-se a Normal da Linguagem de Programação C, fazem esse excelente trabalho na implementação de rotinas de verificação de sintaxe, alimentadas com os erros/falhas mais comuns objetivando educar os seus adeptos com boas práticas. Nessa falha o compilador afirma que existe a hipótese' dereference '(desreferenciar) ponteiros NULL, de fato mesmo que pequena. Logo, é necessário verificar o retorno da malloc, ou ignorar o aviso! Mas, lembre-se que os compiladores são escritos por programadores que possuem a mais elevada prática da linguagem de programação. Logo... Vamos seguir o compilador, agora e sempre! #include <stdio.h> #include <stdlib.h> void print(int **m, int x, int y); int main(){ int **ponteiros = malloc (sizeof(int * [5])); if(ponteiros != NULL){ int *_0inteiros = (int [5]) {0,1,2,3,4}; int *_1inteiros = (int [5]) {1,2,3,4,5}; int *_2inteiros = (int [5]) {2,3,4,5,6}; int *_3inteiros = (int [5]) {3,4,5,6,7}; ponteiros[0] = _0inteiros; ponteiros[1] = _1inteiros; ponteiros[2] = _2inteiros; ponteiros[3] = _3inteiros; print(ponteiros, 5, 4); printf("ponteiros[0][3]: %d\n", ponteiros[0][3]); free(ponteiros); return 0; } puts("FAIL ponteiros es NULL!!!"); return 1; } void print(int **m, int x, int y){ for(int i = 0; i < y; ++i){ for(int j = 0; j < x; ++j){ printf (" %d ", m[i][j]); } putchar('\n'); } return; } Por fim, represento seu experimento, esse que tem na sua postagem original, e respondo todas as perguntas de uma só vez. #include <stdio.h> #include <stdlib.h> int main(){ int **ponteiros = malloc (sizeof(int * [5])); if(ponteiros != NULL){ int *_1inteiros = (int [5]) {1,2,3,4,5}; int *_2inteiros = NULL; _2inteiros = &_1inteiros[1]; free (ponteiros); ponteiros = &_2inteiros; (void)_2inteiros; printf("ponteiros[0][3]: %d\n", ponteiros[0][3]); return 0; } puts("FAIL es NULL"); return 1; } A variável tem valor 5 o experimento da expressão é SUCESSO! Essa expressão está correta? Sim! Esse ponteiro aponta para o endereço do ponteiro2 que aponta para o endereço do ponteiro1? Sim, os endereços são vizinhos (no vetor inteiros) Como eu faria para exibir essa expressão? Como escrevi! Se ainda tem dúvida, pergunte. [] — espero que ajude.
  14. @ricardo_br Comendando abaixo de sua fala, Pois, sé -- o mercado mente -- a verdade é que interessa mais a pessoa (com excelência lógica e tecnológica) do que sua linguagem de estimação. Se existe um ponto de convergência das linguagens, eu acredito ser a lógica. Isto é, com uma boa lógica o céu é o limite. Não penso que C\C++ sejam complicadas se comparado a Python que figura com uma das linguagens mais recomendadas para um iniciante. Acredito que as apostilas e vídeos de Python são o seu segredo, por exemplo, JavaScript quase sempre foca na solução e linguagem é apenas um meio, assim como em python e raramente em C. Tem cada aberração de C, às vezes, a comunidade se expressa não como se fosse uma linguagem, mais sim uma língua. Negócio é ridículo
  15. Viverá a base de biscoite e óleo escrevendo CRUD até surtar, quando não... encarnará o d'us da GRUD a dar dica de como escrever mais legíveis. Sem brincadeira nenhuma, conheço muitos pais de família assim! Para se destacar com C\C++ é preciso QI. Tecnologia por enquanto é uma da poucas áreas em que proficiência importa mais diplomas e idade, onde mais se vê crianças ganhando $$$ de crachá consultor da CIA e com apenas 8 – 14 anos de vida? Mercado de cibersegurança cresce menos que jogos e às duas crescem mais que outras Estudar, estudar e estudar para pegar uma fatia do mercado com mais grana.
  16. Rapinha... Tive que remover muitos códigos de sua função original porque estou com pouquinho de tempo, o bastante para exemplificar aquela observação: {C} typedef struct _data { int dia; int mes; int ano; } Data, DataAniv, Quandoconheci; struct _contato{ char Nome[30]; char Apelido[20]; long long int CPF; char Sexo; char Endereco[40]; int TelResidencial; int TelComercial; int Celular; } Contato; #include<stdio.h> void inserir (FILE *cadastro); int main (void){ FILE *conectado_com_cadastro = fopen ("cadastro.dat", "rb+"); if (!conectado_com_cadastro) { if (!(conectado_com_cadastro = fopen ("cadastro.dat", "wb+"))) { perror(__func__); return 0;}} inserir (conectado_com_cadastro); fclose (conectado_com_cadastro); (void) conectado_com_cadastro; return 0;} void inserir (FILE *cadastro){ printf ("=====================================\n"); printf (" A G E N D A E L E T R O N I C A \n"); printf ("=====================================\n"); long long CPF = 0; struct _contato *index = (struct _contato[1]) {0}; int opcao = 0; fseek (cadastro, 0, SEEK_SET); printf ("Digite o CPF: "); (void) scanf ("%lld", &CPF); while(1){ fread (index, sizeof(*index), 1, cadastro); if (feof(cadastro)){ index->CPF = CPF; break;} if (index->CPF == CPF){ printf ("%s", "[!] Existe um contato, deseja altera-lo [s/n]? "); char sim = 's'; (void) scanf (" %c", &sim); if (sim != 's'){ return;} fseek (cadastro, -sizeof(*index), SEEK_CUR); break;}} while (1) { printf ("- - - - - - - - - - - - - - - - - - - \n"); printf ("Escolha o item que deseja preencher: \n"); printf ("[1] - Nome; \n"); printf ("[2] - Apelido; \n"); printf ("[3] - Sexo; \n"); printf ("[4] - Endereço; \n"); printf ("[5] - Telefones; \n"); printf ("[0] - Cancelar; \n"); printf ("- - - - - - - - - - - - - - - - - - - \n"); (void) scanf ("%d", &opcao); switch (opcao){ case 0: printf ("- - - - - - - - - - - - - - - - - - - \n"); printf ("Gravar contato [s/n]? \n"); char sim = 's'; (void) scanf (" %c", &sim); if (sim == 's'){ fwrite (index, sizeof(*index), 1, cadastro);} return; break; case 1: printf ("Digite o nome: "); while (getchar() != '\n'); gets(index->Nome); break; case 2: printf ("Digite o apelido: "); while (getchar() != '\n'); gets(index->Apelido); break; case 3: printf("Digite o sexo: "); while (getchar() != '\n'); (void) scanf (" %c", &index->Sexo); index->Sexo = ((index->Sexo|' ') == 'f') ? 'F' : 'M'; break; case 4: printf ("Digite o endereço: "); while (getchar() != '\n'); gets(index->Endereco); break; case 5: printf("Escolha qual número de telefone deseja\n"); printf ("- - - - - - - - - - - - - - - - - - - \n"); printf("[1] - Residencial; \n"); printf("[2] - Comercial; \n"); printf("[3] - Celular. \n"); printf ("- - - - - - - - - - - - - - - - - - - \n"); (void) scanf ("%d", &opcao); printf ("Digite o novo numero: "); switch (opcao){ case 1: while (getchar() != '\n'); (void) scanf ("%d", &index->TelResidencial); break; case 2: while (getchar() != '\n'); (void) scanf ("%d", &index->TelComercial); break; case 3: while (getchar() != '\n'); (void) scanf ("%d", &index->Celular); break; default: printf ("- - - - - - - - - - - - - - - - - - - \n"); printf ("Opcao invalida, tente novamente. \n");} break; default: printf ("- - - - - - - - - - - - - - - - - - - \n"); printf ("Opcao invalida, tente novamente. \n");} }return;} TELA Penso que é o suficiente para ter uma boa ideia do ponto, e se alguém tiver otimizações fique Avon! — OK!
  17. @RafaelaOliv Olá, tudo bem com você? Seja bem-vindo ao fórum CdH! como é possível depois de tantas linhas ainda existirem falhas? Que coisa! MANO. #Uma observação A ficha de contato tem 15 campos se eu não errei na contagem, ok... agora imagine você que um sujeito erra no meu da informação ou simplesmente não tenha os dados. Daí sua opção será continuar com dados falsos e alterar mais tarde! O que faz de alterar uma opção eficaz, quando inserir não é. Melhor que seja alterar também inserir contado se o contado não existir. Já com relação à falha da postagem: me desculpe, eu não faço ideia! [] — Boa Sorte
  18. Ansi C

    C Jogo perfil em C

    @Ilanez Santos Olá, tudo bem com você? Eu estou muito bem... Seja bem-vindo ao fórum CdH! Então... — Exceto se alguém (ninguém nesse fórum tem gabarito para tanto) me prove o contrário, insistir com seu nível atual é "dá um salto maior que a perna", a solução ética é inverter a ordem dos estudos! Ou seja, você sabe o teor do exercício agora o momento para estudar apenas aquilo que importa à solução 2021 2022; tem praticamente 2 meses de estudo (tem que renunciar 1 hora diária de compromissos que não pode anteriormente)... para aprender (mais) os fundamentos da linguagem C e seus exercícios nos livros! Certamente essa não é a categoria de ajuda que busca no fórum (de "resolução de exercício"). Entretanto, é o caminho... não mais ético! E sim O ético! []
  19. @João Vitor GO Olá — Supondo que as alternativas são digitadas sequencialmente: *, seria os alunos suas notas. *, o que chamam “item” seriam os valores para as colunas do vetor gabarito. *, assim -- são dois vetores, um de 30 posições e outro de 10 posições (notas finais e gabarito). Após o gabarito, digite as 10 alternativas de cada aluno para calcular sua nota durante a entrada. Logo seriam 30 linhas com 10 itens cada (resposta das questões) Para minimizar use 7 linhas e 2 itens! Talvez resolva com dois ‘Loop’: 1st Para processamento durante a entrada! 2nd Para saída. [] — espero que ajude!
  20. @Lipeco Tudo bem você? Comigo, está tudo bem! Sobre o exercício percebe-se 3 operações () no enunciado e se remover toda a gordura da estrutura de dados tabela de Hash, sobram operações e iterações sobre vetores. — Tudo se resume em saber operar os vetores. Após 24 horas a dúvida persistiu... *, vejo que nomeou um apontador de end (não sei o porquê disso), depois declarou uma iteração (certo), imprimiu o código de hash (certo), e por fim chama a função recursivamente (falhou): aproposito, essa função se quer tem argumento. {C} Escrevi rapidamente uma função semelhante à tua, inclusive a simulação utiliza a mesma lógica do vetor global mais ‘loop’-FOR int observar (void) { for (long unsigned indice = 0; indice < 13UL; ++indice) { Linha_hash *lh = tabela_hash + indice; if (lh->tamanho_vet) { printf ("%2lu->", indice); for (long unsigned e = 0; e < 10UL; ++e) { if ((lh->vet + e)->chave) { printf ("%.3lu:%s\t", (lh->vet + e)->chave, (lh->vet + e)->usuario); } } puts (""); } } return 0; } itera a matriz 'tabela_hash' de 0 até 12 *, pega a linha do índice *, verifica se o vetor tem tamanho diferente de zero *, escreve o índice (código de hash) da matriz *, itera o vetor de recipientes (ou de elementos) de 0 até 9 *, com operador de acesso de membros através de ponteiro (->) acessa o apontador dos recipientes (vet) adiciona (e) para indexar, usa o operador (->) para acessar seu membro 'chave', verifica se tem valor diferente de 0 e escreve: 'chave' como decimal positivo, 'usuario' como “strings”. *, escreve uma nova linha e recomeça. Resultado: [] — espero que ajude!
  21. A primeira parte do exercício: {C} #include"stdio.h" int main (void) { int n_maximo = 5; int fatorial = 1; for (int n = 1; n <= n_maximo; ++n) { fatorial *= n; printf ("%d! %d\n", n, fatorial); } return 0; } SAÍDA [] — espero que ajude!
  22. Boa Noite... entendo! Realmente, pelo enunciado o programa não deve solicitar que o usuário digite os valores para n. Ou seja é para exibir (n, resultado) por linha de 1 a 5. [] -
  23. Tudo isso! E além dessas alternativas existe outra pouca /ou nada discutida, principalmente porque envolve duas variáveis além do ponteiro necessário para alocação dinâmica de memória, sendo a alocação dinâmica o seu pior contra, já que implica na liberação da memória após não ser mais necessária, um serviço extra que incomoda às vezes! Essa função é a GETLINE Observo sendo semelhante, pelo menos no processo de entrada, com a 'fgets' Para um exemplo escrevo um programa que digitada uma lista de números positivos inteiros exibirá respectivamente seus fatoriais. Usarei a função na captura dessa lista (linha) de números (“strings”), após conversão para inteiro no programa calcula-se o fatorial, exibe-se o resultado, aponta para hipoteticamente a próxima “strings” e repete tudo enquanto não falhar a conversão de ‘texto’ para número. {C} #include"stdio.h" #include"stdlib.h" int main (void) { char *nums_como_strings = NULL; long unsigned capacidade = 0; //GETLINE //se voltar como esperado, 'sucesso' tem tamanho (>0) da strings //e 'capacidade' tem o numero em bytes alocados int sucesso = getline (&nums_como_strings, &capacidade, stdin) - 1; if (sucesso < 0) { return EXIT_FAILURE; } unsigned num = 1, fatorial = 1; int proximo = 0; while (sscanf (nums_como_strings, "%u%n", &num, &proximo) == 1) { for (unsigned i = 1; i <= num; ++i) { fatorial*= i; } printf ("%u! %u\n", num, fatorial); nums_como_strings+= proximo; num = 1, fatorial = 1; proximo = 0; } free (nums_como_strings - sucesso); (void) sucesso; return EXIT_SUCCESS; } [SAÍDA] [] — espero que ajude!
  24. @Swalls Isso! Eu continuo 'achar' que a quantidade de números inteiros positivos não deve ser importante e a preocupação é com tamanho do fatorial que pode ultrapassar (“overflow”) a capacidade da variável int, logo pedir de 1 a 5 é a maneira dele garantir os fatoriais do exercício. Exemplo: Se fosse eu, gostaria que escrevesse um programa que digitada uma lista de números inteiros positivos mostrasse os respectivos fatoriais, na esperança que o programador (aluno) perceba que pode passar o limite de um inteiro durante os ('debug') testes. {C} #include"stdio.h" int main (void) { char linha_como_strings [BUFSIZ] = {""}; scanf ("%[^\n]", linha_como_strings); char *nums_como_strings = linha_como_strings; unsigned num = 1, fatorial = 1; int proximo = 0; while (sscanf (nums_como_strings, "%u%n", &num, &proximo) == 1) { for (unsigned i = 1; i <= num; ++i) { fatorial*= i; } printf ("%u! %u\n", num, fatorial); nums_como_strings+= proximo; num = 1, fatorial = 1; proximo = 0; } return 0; } SAÍDA [] — espero que ajude!

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

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!