-
Posts
3.284 -
Cadastrado em
-
Última visita
Tipo de conteúdo
Artigos
Selos
Livros
Cursos
Análises
Fórum
Tudo que Ansi C postou
-
É 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.
-
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.
-
Ainda tem vagas no mercado de programação para C/C++?
Ansi C respondeu ao tópico de Gabe Grechuk em Estudos e mercado de trabalho
@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 -
Ainda tem vagas no mercado de programação para C/C++?
Ansi C respondeu ao tópico de Gabe Grechuk em Estudos e mercado de trabalho
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. -
C++ Tenho que criar uma agenda mas todas as opções do menu estão encerrando o progra
Ansi C respondeu ao tópico de RafaelaOliv em C/C#/C++
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! -
C++ Tenho que criar uma agenda mas todas as opções do menu estão encerrando o progra
Ansi C respondeu ao tópico de RafaelaOliv em C/C#/C++
@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 -
@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! []
-
@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!
-
@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!
-
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!
-
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. [] -
-
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!
-
@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!
-
Desculpa por nada: pois na minha opinião, o enunciado é escrito para gerar confusão mesmo! Do contrário seria explicito na (rotina de) entrada. Dizer "1 a 5 inteiros" (para mim) insinua muitas coisas... [] — valeu, espero que ajude.
-
Isso, @Thmpv Enunciado "1 a 5 inteiros" para insinuar que serão de 1 até 5 teste para digitação. Por ouro lado, alguém poderia interpretar sendo para exibir os 5 fatoriais de n = 1 até 5, mas não necessariamente digitar os 5 termos..., ou seja, as entradas são; 1, 2, 3, 4, 5. Nessa caso, um ‘loop’ fornece n sequencialmente (de 1 até 5) sem necessidade da digitação por parte do usuário (que só observa o resultado). Quer mais? Coloque no mesmo 'loop' (de 5 repetições) as rotinas que; captura o inteiro, calcula o fatorial e exibe o resultado! Lembre-se de reiniciar a variável fatorial (= 1) depois que a exibir no ("Resultado"). Enfim, independentemente da interpretação sabemos que calcular o fatorial de (n) é a parte principal do exercício e (na minha opinião) seu programa nesse quesito está correto, @Thmpv. [] — acabei, espero que ajude, valeu!
-
Isso! Foi dito e eu reforço ser um exercício comum com muitíssimas respostas. (Solução complexa): lembro-me aqui (neste fórum) que um usuário resolveu a pergunta com uma função fatorial (n), a propósito, ele usou programação dinâmica: nada de mais, a função tem capacidade de guarda o último produto e argumento (em variáveis static) para ter uma resposta otimizada ao reduzir a hipótese de repetição (ou dar chance de não recalcular). Para uma resposta complexa? Com certeza. Ou Seja: 1st: ‘loop’ pega valor de n, 2th: ‘loop’ faz o "produto de todos os inteiros positivos menores ou iguais a n" (há repetição de produto) [] — espero que ajude!
-
Python Testar se todos os caracteres da primeira string também aparecem na segunda str
Ansi C respondeu ao tópico de Regis Marcos Correa Junior em Programação - outros
Isso (@Midori)! Outra solução usa a instrução else. Entretanto, não é a If-else e sim a for-else! Apenas dessa vez anteciparei o experimento e escreverei eu mesmo a minha sugestão. Advirto que você (@Regis Marcos Correa Junior) exercite a lógica do post acima. — Puxe a else para margem do for que passará a pertencer-lhe (apague a última break). Caso: FALSO input0 = 'Ola Python'#input ('Escreva um texto e tecla ENTER? ') input1 = 'Ola Pithon'#input ('Escreva um texto e tecla ENTER? ') for i in input0: if i not in input1: print ('Nem todos os caracteres da primeira string aparecem na segunda') break else: print ('Todos os caracteres da primeira string aparecem na segunda') SAÍDA (Nem...) Caso: VERDADE input0 = 'Ola Python'#input ('Escreva um texto e tecla ENTER? ') input1 = 'Ola Python'#input ('Escreva um texto e tecla ENTER? ') for i in input0: if i not in input1: print ('Nem todos os caracteres da primeira string aparecem na segunda') break else: print ('Todos os caracteres da primeira string aparecem na segunda') SAÍDA (Todos...) [] — espero que ajude. -
@iTzCrazy Boa noite! O programa "pausa" na 'scanf' após leitura da 'fgets', na verdade, aguarda o recebimento de mais informações! Digite um texto (de no máximo 9 caracteres) e tecla ENTER.
-
Acabei lendo às pressas e não vi uma passagem importante de sua resposta, @Chr15 [!] esta passagem Em tese, só isso não basta! RESUMIDAMENTE, as variáveis na função main são vizinhas e o especificador no formato da 'scanf' ("%d") exige um parâmetro do tipo int * (na arquitetura 32 bits aponta para um início da sequência de 4 ‘bytes’). E os compiladores atuais tem (porém, não perfeita) regras para verificação da sintaxe, logo "os comados" abaixo são uma "falha gramatical" [ALERTA DURANTE COMPILAÇÃO] Ignoraremos e continuamos… com esta versão reduzida do programa de maneira que sobrou só a bendita 'scanf' (ou seja, sem as tais 'printf') #include"stdio.h" #include"stdlib.h" #include"stdbool.h" //Incluindo bibliotecas pre-definidas int main (void) { int Inteiro; float Decimal; char Caractere; bool Booleano; //Definindo variáveis e seus tipos Inteiro = 4; Decimal = 1.4; Caractere = 'C'; Booleano = false; //Definindo valores das variáveis printf("\nO valor da variavel Decimal atualmente = %f!\n", Decimal); //Imprimindo na tela scanf("%d", &Booleano); //Pedindo usuário para inserir novo valor printf("\nO novo valor de A = %d", Inteiro); printf("\nO novo valor de B = %f", Decimal); printf("\nO novo valor de C = %c", Caractere); printf("\nO novo valor de D = %d\n\n", Booleano); //Imprimindo valores após a modificação system("pause"); //Pausando após execução return 0; } [SAÍDA] *O valor zero, abaixo da saída do valor atual na 'Decimal', é a entrada para scanf. Observe a igualdade de B C. [] — espero que ajude.
-
Isso, a resposta do usuário acima (@Izera XD) é a maneira C de pegar a capacidade (em “bytes”) dos tipos. Então, usarei a sugestão dele e anteciparei o experimento com um programa demostrativo que ilustra a capacidade das variáveis do teu programa e seus respectivos tipos, @Chr15. Ilustração #include"stdio.h" #include"stdlib.h" #include"stdbool.h" //Incluindo bibliotecas pre-definidas int main (void) { int Inteiro; float Decimal; char Caractere; bool Booleano; unsigned long capacidade_Inteiro = sizeof(Inteiro), capacidade_Decimal = sizeof(Decimal), capacidade_Caractere = sizeof(Caractere), capacidade_Booleano = sizeof(Booleano), capacidade_int = sizeof(int), capacidade_float = sizeof(float), capacidade_char = sizeof(char), capacidade_bool = sizeof(bool); puts ("capacidade . . . = bytes"); puts ("VARIAVEIS:"); printf ("%s%lu\n%s%lu\n%s%lu\n%s%lu\n", "capacidade_Inteiro = ", capacidade_Inteiro, "capacidade_Decimal = ", capacidade_Decimal, "capacidade_Caractere = ", capacidade_Caractere, "capacidade_Booleano = ", capacidade_Booleano ); puts ("TIPOS:"); printf ("%s%lu\n%s%lu\n%s%lu\n%s%lu\n", "capacidade_int = ", capacidade_int, "capacidade_float = ", capacidade_float, "capacidade_char = ", capacidade_char, "capacidade_bool = ", capacidade_bool ); system ("pause"); //Pausando após execução return 0; } [SAÍDA] * Há 4s e 1s! Agora que ilustrei o operador, usarei a mesma sugestão também numa versão do exemplo comprobatório da estrutura contígua na definição de variáveis do 'post' anterior. #include"stdio.h" #include"stdlib.h" #include"stdbool.h" int main (void) { int Inteiro; float Decimal; char Caractere; bool Booleano; //Definindo variáveis e seus tipos Inteiro = 4; Decimal = 1.5; Caractere = 'C'; Booleano = 0; //Definindo valores das variáveis *(int *) (&Booleano + (sizeof(bool) + sizeof(char) + sizeof(float))) = 1010111; //Com exceção gravar na 'Inteiro' -- tudo isso equivale a referencia dela >'< printf("\nO novo valor de A = %d", Inteiro); printf("\nO novo valor de B = %f", Decimal); printf("\nO novo valor de C = %c", Caractere); printf("\nO novo valor de D = %d\n\n", Booleano); //Imprimindo valores após a modificação system("pause"); //Pausando após execução return 0; } [SAÍDA] *Comprova (pela 2th vez) que as variáveis são vizinhas! [] — espero que ajude!
-
Isso! Uma boa porção do mistério foi revelado, só não sei dizer se ficou evidente para todos da mesma maneira que para mim, assim explanarei mais um pouco o que acontece entre Booleano e Caractere. 1# Interpretando está cascata de declarações na forma de um vetor de bytes. Sendo que começa em Booleano e termina em Inteiro, por exemplo, se eu desejo trocar o valor da variável 'Inteiro' posso fazer também por qualquer endereço a partir da 'Booleano'. Veja só: #include"stdio.h" #include"stdlib.h" #include"stdbool.h" int main (void) { int Inteiro; float Decimal; char Caractere; bool Booleano; //Definindo variáveis e seus tipos Inteiro = 4; Decimal = 1.5; Caractere = 'C'; Booleano = 0; //Definindo valores das variáveis *(int *) (&Booleano + 6) = 40; //Com exceção gravar na 'Inteiro' printf("\nO novo valor de A = %d", Inteiro); printf("\nO novo valor de B = %f", Decimal); printf("\nO novo valor de C = %c", Caractere); printf("\nO novo valor de D = %d\n\n", Booleano); //Imprimindo valores após a modificação system("pause"); //Pausando após execução return 0; } [SAÍDA] *Prova a si mesmo que a memória dessas declarações é contígua ao tentar outros valores. É dito que um tipo bool tem 8 bits (1 byte), char tem 8 bits (1 byte), float tem 32 bits (4 bytes) que somados é: 6 bytes, daí o motivo de adicionar 6 ao endereço da 'Booleano' para conduzir até o endereço do 'byte' menos significativo da 'Inteiro' que nos permiti acessa-lo. #2 O especificador na função Insinua que o parâmetro tem um decimal inteiro (ou seja, tipo int (32 bits (4 bytes))), entretanto sabemos ser falso, pois um tipo _Bool (ou bool — sendo seu apelido) tem 1 byte tal qual o tipo char. Então, pergunta-se... a scanf grava em cima de quem, já que bool tem 1 byte, mas 'scanf' precisa de 4 bytes? — DA 'Caractere' e DA 'Decimal' e com isso altera suas estruturas e seus valores. [] — espero que ajude!
-
Olá @Thmpv Isso, e agora que está resolvido, vou acrescentar um detalhe a discussão só para conscientizar. — A cada ciclo no 'loop' a pow repete a potência do ciclo anterior porque está em sequência (1 ... 10) for (ano = 1; ano <= 10; ano++) { quantia = principal * pow(1.0 + taxa, ano); printf ("%4d %21.2f\n", ano, quantia); } Não significa dizer ser um erro porque não é! Digamos que talvez gaste energia. Ilustração /* Calculando juros compostos */ #include"stdio.h" #include"math.h" int main (void) { int ano; double quantia, principal = 1000.0, taxa = .05; double pow_acumulado = 1; printf ("%4s%21s\n", "Ano", "Saldo na conta"); for (ano = 1; ano <= 10; ano++) { pow_acumulado *= 1.0 + taxa; quantia = principal * pow_acumulado; printf ("%4d%21.2f\n", ano, quantia); quantia = principal * pow (1.0 + taxa, ano); printf ("%4d%21.2f\n", ano, quantia); } return 0; } [Saída] [] — sem pânico!
-
Tive numa discussão pouco semelhante (mais acalorado) com 5 pessoas de um fórum fechado em Portugal que até a moderação entrou na lista de desleixados, é sério! Revendo postagens antigas, notei que aqui também houve discussões semelhantes (no tempo do AnsiC há ~10 anos e outras recentemente no privado: para piorar... odeio privado), mas diferente de ti, que foste de uma observação divertida, outro foi para ridicularizar/constranger. Eu faço o meu melhor sem cobrar muito de mim Esses que curtem ridicularizar o fazem naturalmente porque todos nós procuramos o destaque. Entendo ser perfeitamente normal quando é um jovem, já para os demais eu não tenho paciência mesmo. [] Off-tópico assim é bem legal.
-
Isso, fica a gosto, já que o resultado é certamente igual; Por exemplo, São argumentos para fazer o que dizem ser "mais simples", mas ambos são igualmente simples a graduação de simplicidade (que para mim) nem existe é mera questão de gosto. Dizer que uma coisa é mais fácil de ler porque tem 0 ou '/0' ou "" e ridiculamente preferencial. Ridiculamente porque o limite do irrelevante. * "Mais fácil de ler" é tão evasivo quanto "mais simples" porque se trata de uma limitação pessoal. Todas as notações são igualmente fáceis ter isso ou aquilo de mais fácil/simples é excluir um por motivo de preferências É bem mais honesto quando dizem: eu prefiro isso do que aquilo. * Economizar teclas, estamos por Acaso numa crise de teclas * "são maiúsculas então ainda tem que apertar o shift" Preocupação com a Lesão por Reforço Repetitivo — LER é razoável e advirto ser um problema que não se evita na "economias teclas" ou qualquer outra regra esdruxula, se não com bom descanso. Descanso será também útil na produtividade. São observações divertidas SIM, que não faz de ninguém um programador melhor/produtivo. #0 A constante é um inteiro de 4 “bytes”, no caso é também uma sequência de ‘bytes’ e sua estrutura ou configuração na memória do computador também são iguais. Determinante na solução que usa (somente) uma camada de switch e case para aquele "desafio". Nossa odeio quando os meus alunos (os mais "fraquinhos") dizem o mesmo... poque isso é evasiva (sem justificativa) porque é uma limitação pessoal/ gosto pessoal no caso estilo. Sempre digo que estilo é algo que só importa alguém se esse trabalha na sua equipe, pois cada equipe define as configurações de estilo e com isso evita discussões inúteis. Uma união é uma categoria de dado especial disponível em C que permite armazenar diferentes categorias de dados no mesmo local de memória. #include"stdio.h" #include"stdlib.h" int main (void) { union {char Chars[sizeof(int)]; int Int;} estado = {"SP"}; printf ("O resultado e igual: %s\n", estado.Int == ('S'|'P' << 8) ? "SIM" : "não"); (void) estado; return 0; } O conceito de “strings” aqui é mais abstrato que aquele dos antigos e adeptos programadores/experientes em C ensinam... o inteiro do lado oposto da varável é sim uma "strings" porque em sua memória há dois ‘bytes’ não nulos seguindo de outros nulos igual à variável 'estado'. #1 Essa condicional IF inicial não tem sentido porque faz o que a 'default' existe para fazer. Digamos que importa saber que toda switch e case são condicionais que um pouco mais analiticamente pode ter o seguinte aspecto: int indice = 0; if (1 != scanf("%2s", Dual.estado)) indice = 4; if (Dual.numero == SP) { indice = 3; } else if (Dual.numero == MG) { indice = 0; } else if (Dual.numero == RJ) { indice = 2; } else if (Dual.numero == MS) { indice = 1; } else { indice = 4; } printf("%s\n", estados[indice]); A primeira condicional examina o 'return' da 'scanf' de 1 especificador, para quê? Para atribuir último índice de um vetor, cuja utilidade persiste durante a função, mas só é útil em uma ocasião e está logicamente acobertado pelo que se chama "Otherwise" (por outro lado)/último else de uma cascata de IF-ELSE. Melor ficou por último *E aspas mudam de lugar de um teclado para outro. O 0 não, [] — sem comentários... Mas, digo que achar as "" é problema pessoal (de poucos) e se resolve.
-
@Leucosia Olá tudo bem... Há muitos anos outro usuário escreveu dúvida semelhante, me lembro que ele rejeitou as soluções que usaram mais que uma camada de condicionais, ou seja, tinha que ser somente uma camada switch e case. Foram dadas duas propostas: #A consiste em multiplicar o primeiro padrão por um decimal de modo que define outro composto com o segundo padrão. Uma combinação de produto e soma e.g: C language #include"stdio.h" #include"stdlib.h" int main (void) { printf ("Ola, digite uma das siglas dos estados do Basil [SP MG RJ MS]: "); char estado[4] = { "" }; scanf ("%2s", estado); switch (estado[0]*100 + estado[1]) { case 'S'*100 + 'P': printf ("Sao Paulo - %s\n", estado); break; case 'M'*100 + 'G': printf ("Minas Gerais - %s\n", estado); break; case 'R'*100 + 'J': printf ("Rio Janeiro - %s\n", estado); break; case 'M'*100 + 'S': printf ("Mato Grosso Sul - %s\n", estado); break; default: printf ("Sigla inexistente!\n"); } return 0; } #B consiste em deslocar a sequência de 8 bits do segundo padrão por um inteiro de modo que define outro integrando o primeiro padrão. e.g: C language #include"stdio.h" #include"stdlib.h" int main (void) { printf ("Ola, digite uma das siglas dos estados do Basil [SP MG RJ MS]: "); char estado[4] = { "" }; scanf ("%2s", estado); switch (*(int *) estado) { case 'S'|'P' << 8: printf ("Sao Paulo - %s\n", estado); break; case 'M'|'G' << 8: printf ("Minas Gerais - %s\n", estado); break; case 'R'|'J' << 8: printf ("Rio Janeiro - %s\n", estado); break; case 'M'|'S' << 8: printf ("Mato Grosso Sul - %s\n", estado); break; default: printf ("Sigla inexistente!\n"); } return 0; } — Essa é minha recomendação veja que expressão da cláusula simula 'multi-character constant' (uma “strings”). Sugeri também que se usar uma estrutura union ocultaria o cast na expressão da switch. #include"stdio.h" #include"stdlib.h" int main (void) { printf ("Ola, digite uma das siglas dos estados do Basil [SP MG RJ MS]: "); union { char Chars[sizeof(int)]; int Int; } estado; scanf ("%2s", estado.Chars); switch (estado.Int) { case 'S'|'P' << 8: printf ("Sao Paulo - %s\n", estado.Chars); break; case 'M'|'G' << 8: printf ("Minas Gerais - %s\n", estado.Chars); break; case 'R'|'J' << 8: printf ("Rio Janeiro - %s\n", estado.Chars); break; case 'M'|'S' << 8: printf ("Mato Grosso Sul - %s\n", estado.Chars); break; default: printf ("Sigla inexistente!\n"); } return 0; } [SAÍDA] É possível substituir os operadores por multiplicação e adição, mas lógica binária é, para mim, muita mais elegante. [] — 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