Dexter's Lab Posted January 5, 2013 at 10:34 PM Report #489825 Posted January 5, 2013 at 10:34 PM (edited) Boas, estou há algum tempo a tentar resolver este problema e estou completamente encravado no porquê de isto me estar a dar estes valores. O exercício é, primeiro, para receber um limite de valores que se vai digitar. Depois, o utilizador digita esse numero de valores. O programa devolve o par maior e menor, o impar maior e menor. Contudo, para começar, estão a entrar pares para o filtro impar e vice versa. Ou seja, os impares aparecem onde deviam aparecer os pares. Segundo, não estou a conseguir obter os resultados maiores/menores que deveria. Gostaria de perceber convosco o que estou a fazer de errado. # include <stdio.h> /*Pedir limite de numeros a analisar. Mostra o maior e menor par, o maior e menor impar*/ int maior (int a); int menor (int b); int main () { int val, cont, num; int pmaior, pmenor, imaior, imenor; pmaior = pmenor = imaior = imenor = 0; printf ("Limite de numeros a analisar: "); scanf ("%d",&val); printf ("\n"); for (cont = 0; cont < val; cont ++) { printf ("%d valor: ", cont+1); scanf ("%d", &num); if ((cont%2)==0) { pmaior = maior (num); pmenor = menor (num); } else if (!(cont%2)==0) { imaior = maior (num); imenor = menor (num); } } printf ("\t \t MAIOR \t MENOR \n \n"); printf ("PARES: \t \t %d \t %d \n", pmaior, pmenor); printf ("IMPARES: \t %d \t %d", imaior, imenor); getche (); return 0; } int maior (int a) { int maior = 0; if (maior == 0) { maior = a; } else if (a > maior) { maior = a; } return maior; } int menor (int b) { int menor = 0; if (menor == 0) { menor = b; } else if (b < menor) { menor = b; } return menor; } Agradeço a atenção e disponibilidade. Também agradeço a paciência e a pedagogia, uma vez que só programo em C há 1 mês e meio. Cumprimentos Edited January 5, 2013 at 10:45 PM by Dexter's Lab Falta LP
pmg Posted January 5, 2013 at 10:41 PM Report #489826 Posted January 5, 2013 at 10:41 PM (edited) So uma ajudita ... o teu problema esta na definicao de "maior". 42 é maior? Para saberes se um numero é maior que outro tens de comparar os dois numeros. Edited January 5, 2013 at 10:42 PM by pmg What have you tried? Não respondo a dúvidas por PM A minha bola de cristal está para compor; deve ficar pronta para a semana. Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!
Dexter's Lab Posted January 5, 2013 at 10:52 PM Author Report #489829 Posted January 5, 2013 at 10:52 PM (edited) Não sei se percebi, porque eu acho que estou a compará-los: int maior (int a) // recebe o parâmetro para "a" { int maior = 0; // "maior" é 0, para não haverem erros na primeira volta e // receber à vontade o valor do utilizador if (maior == 0) { maior = a; // se o maior for 0 (que e o que acontece na primeira // volta) o "maior" recebe o valor que veio de parâmetro } else if (a > maior) { maior = a; //senão (isto é para as voltas seguintes), // sempre que o valor a for maior que a // variável "maior", ele atribui-lhe o seu // valor; de modo a que fica sempre com o // valor maior } return maior; } Edited January 5, 2013 at 10:53 PM by pmg apaguei formatacao, adicionei GeSHi
HappyHippyHippo Posted January 5, 2013 at 10:55 PM Report #489834 Posted January 5, 2013 at 10:55 PM int maior (int a) { int maior = 0; if (maior == 0) { // sim, maior é igual a zero (acabaste de fazer a atribuição) maior = a; // isto é sempre executado } else { // ... irrelevante } return maior; } pensa no que deves comparar e como o fazer IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
pmg Posted January 5, 2013 at 10:57 PM Report #489837 Posted January 5, 2013 at 10:57 PM (edited) Não sei se percebi, porque eu acho que estou a compará-los: int maior (int a) // recebe o parâmetro para "a" { int maior = 0; // "maior" é 0, para não haverem erros na primeira volta e // receber à vontade o valor do utilizador if (maior == 0) { maior = a; // se o maior for 0 (que e o que acontece na primeira // volta) o "maior" recebe o valor que veio de parâmetro } else if (a > maior) { maior = a; //senão (isto é para as voltas seguintes), // sempre que o valor a for maior que a // variável "maior", ele atribui-lhe o seu // valor; de modo a que fica sempre com o // valor maior } return maior; } Ao fazeres int maior = 0; o programa vai sempre fazer isso. Nao o vai fazer apenas na primeira volta. Sempre que se executar a funcao maior vai ser 0 e a primeira parte do if sera executada. A melhor maneira seria passares 2 valores para a funcao ... e guardares informacao sobre o maior ate ao momento na funcao que chama esta. Ha maneiras de fazer variaves guardarem o valor de uma chamada a funcao para outra, mas isso é um topico mais avancadito Podes ler, se te interessar, sobre variaveis com o static. Nota que o identificador maior é usado duas vezes com dois significados diferentes. Fora das funcoes é o nome duma funcao, denro da funcao maior é o nome duma variavel. Habitua-te a nao dar o mesmo identificador a "coisas" com significados diferentes. Edited January 5, 2013 at 11:10 PM by pmg Informacao sobre static dentro dum spoiler; nota sobre uso duplicado de identificador What have you tried? Não respondo a dúvidas por PM A minha bola de cristal está para compor; deve ficar pronta para a semana. Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!
Dexter's Lab Posted January 5, 2013 at 11:45 PM Author Report #489850 Posted January 5, 2013 at 11:45 PM (edited) Já resolvi a questão dos pares e ímpares trocados. Eu estava a ler o contador em vez do valor digitado. Erro de distração. Agora a questão do maior/menor é que me está a ser um completo desafio. int main () { int val, cont, num; [b]int hlp_1 = 0;[/b] int pmaior, pmenor, imaior, imenor; pmaior = pmenor = imaior = imenor = 0; printf ("Limite de numeros a analisar: "); scanf ("%d",&val); printf ("\n"); for (cont = 0; cont < val; cont ++) { printf ("%do valor: ", cont+1); scanf ("%d", &num); [b]if ((num%2)==0) {[/b] [b]pmaior = maior (num, hlp_1);[/b] pmenor = menor (num); } ... [b]int maior (int a, int maior_val)[/b] [b]{[/b] [b]if (a > maior_val) {[/b] [b]maior_val = a;[/b] [b]}[/b] [b]return maior_val;[/b] Não entendo. Mesmo assim não vai lá. O valor só seria 0 no primeiro momento de entrar porque vem de antes e de fora do ciclo. Nos outros já não seria 0, supostamente. Mesmo assim a função não me está a guardar o número mais alto mas sim o último par que encontrou. Edited January 6, 2013 at 01:49 PM by apocsantos geshi
thoga31 Posted January 5, 2013 at 11:51 PM Report #489851 Posted January 5, 2013 at 11:51 PM (edited) Estás a fazer o mesmo... hlp_1 é sempre 0, não estás a comparar se o número inserido pelo utilizador é maior que o que já está definido como maior... Isto diz-te algo? if (num > par_maior) par_maior = num; Edited January 5, 2013 at 11:52 PM by thoga31 Knowledge is free!
Dexter's Lab Posted January 5, 2013 at 11:58 PM Author Report #489853 Posted January 5, 2013 at 11:58 PM (edited) Estás a fazer o mesmo... hlp_1 é sempre 0, não estás a comparar se o número inserido pelo utilizador é maior que o que já está definido como maior... Isto diz-te algo? if (num > par_maior) par_maior = num; O que me está a criar mais dificuldade é o fato de na primeira volta ter de começar o valor com que vou comparar ser 0, para evitar erros de ele comparar aquele valor com um valor qualquer que esteja naquele espaço de memória. O problema é que, depois de o deixar a 0 não consigo com que ele efetue isso somente na primeira volta. Pensei que se ele tivesse sido declarado fora e antes do ciclo for que já não fosse buscar mais o valor que lhe foi atribuído no início... Edited January 5, 2013 at 11:59 PM by Dexter's Lab
pmg Posted January 6, 2013 at 12:03 AM Report #489855 Posted January 6, 2013 at 12:03 AM (edited) Para alterar o valor duma variavel dentro doutro funcao, tens de passar o endereco da variavel. Se passas o valor da variavel, qualquer alteracao é local na funcao chamada Passagem do valor num = 42; hlp_1 = 17; pmaior = maior(num, hlp_1); // depois da funcao, independentemente do que ela faz // tanto num como hlp_1 continuam com o mesmo valor de antes. Passagem do endereco num = 42; hlp_1 = 17; pmaior = maior(num, &hlp_1); // depois da funcao // num continua com o mesmo valor de antes // mas hlp_1 pode ter sido alterado é claro que a funcao maior deve ser diferente para os dois exemplos de cima Para o primeiro exemplo o prototipo deve ser int maior(int, int); e para o segundo exemplo deve ser int maior(int, int *); Edited January 6, 2013 at 12:05 AM by pmg prototipo What have you tried? Não respondo a dúvidas por PM A minha bola de cristal está para compor; deve ficar pronta para a semana. Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!
Dexter's Lab Posted January 6, 2013 at 12:13 AM Author Report #489857 Posted January 6, 2013 at 12:13 AM Para alterar o valor duma variavel dentro doutro funcao, tens de passar o endereco da variavel. Se passas o valor da variavel, qualquer alteracao é local na funcao chamada Passagem do valor num = 42; hlp_1 = 17; pmaior = maior(num, hlp_1); // depois da funcao, independentemente do que ela faz // tanto num como hlp_1 continuam com o mesmo valor de antes. Passagem do endereco num = 42; hlp_1 = 17; pmaior = maior(num, &hlp_1); // depois da funcao // num continua com o mesmo valor de antes // mas hlp_1 pode ter sido alterado é claro que a funcao maior deve ser diferente para os dois exemplos de cima Para o primeiro exemplo o prototipo deve ser int maior(int, int); e para o segundo exemplo deve ser int maior(int, int *); Ah! Era provavelmente o ingrediente que me faltava. Não conhecia isso. Na verdade eu ainda não aprendi funções sob orientação do meu professor. Apenas andei a pesquisar e treinar durante as férias as passagens de parâmetros e sub-procedimentos para poder chegar à escola já preparado nessa matéria. Pensei que funções se resumissem muito apenas a isso. Afinal não. São estes toques que me fascinam na programação. Muito obrigado, pessoal, pelo conhecimento. Pmg, onde posso ler específicamente sobre isso (endereço de memória (&))? Aconselhas-me alguma peça literária que contenha atenção a esse fator ou algum artigo na net? Sempre o usei no Scanf, mas pensei que fosse próprio dessa função e não um elemento essencial em todo o C. Espectacular, se me permitem a opinião.
pmg Posted January 6, 2013 at 12:26 AM Report #489858 Posted January 6, 2013 at 12:26 AM (edited) O nome usual para este tipo de passagem de parametros (com o &) é "passagem por referencia". Se nao te importares de veres montanhas de coisas relacionadas com C++ pesquisa por "pass by value" e "pass by reference". Nota que o conceito de referencia é bastante mais abrangente em C++ do que em C (eu nao sei C++, por isso interpreta este paragrafo com um pé atras). Em C, todos os parametros sao passados por valor (ou o valor proprio da variavel ou o valor do endereco de memoria onde essa variavel reside). O assunto relacionado com o operador & é o assunto de ponteiros. Talvez seja melhor esperares pelo professor para teres um apoio mais proximo quando comecares a mexer com ponteiros. Edited January 6, 2013 at 12:32 AM by pmg What have you tried? Não respondo a dúvidas por PM A minha bola de cristal está para compor; deve ficar pronta para a semana. Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!
HappyHippyHippo Posted January 6, 2013 at 09:56 AM Report #489868 Posted January 6, 2013 at 09:56 AM pelas razões acima referidas, o que deverias usar para concretizar o teu problema seria o uso do valor de retorno int maior_par(int valor, int maior_actual) { if (valor % 2 == 0) { if (valor > maior_actual) { return valor; } } return maior_actual; } int main() { // ... pmaior = maior_par(valor, pmaior); // ... } depois de teres o código a funcionar (mais ou menos) apresenta o que tens porque poderão existir casos particulares onde verás tudo a dar bronca IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Dexter's Lab Posted January 6, 2013 at 06:26 PM Author Report #489907 Posted January 6, 2013 at 06:26 PM (edited) Boas, só vi novamente este tópico agora. Acabei por concluir o programa hoje de manhã, por enquanto, sem funções - que teria sido logo de início muito fácil. Mostro-vos já como está pois agora quero trabalhá-lo para ter funções, que esse sim será para mim o desafio. Se no entanto tiverem alguma indicação e crítica agradecerei. Peço-vos que sejam chatos nesse sentido. # include <stdio.h> /*Pedir limite de numeros a analisar. Mostra o maior e menor par, o maior e menor impar*/ int main () { int val, cont, num; int pmaior = 0, pmenor; int imaior = 0, imenor; printf ("Limite de numeros a analisar: "); scanf ("%d",&val); printf ("\n"); for (cont = 0; cont < val; cont ++) { printf ("%do valor: ", cont+1); scanf ("%d", &num); if ((num%2)==0) { if (pmaior == 0) { pmenor = num; } else if (num < pmenor) { pmenor = num; } if (num > pmaior) { pmaior = num; } } else if (!(num%2)==0) { if (imaior == 0) { imenor = num; } else if (num < imenor) { imenor = num; } if (num > imaior) { imaior = num; } } } printf ("\t \t MAIOR \t MENOR \n \n"); printf ("PARES \t \t %d \t %d \n", pmaior, pmenor); printf ("IMPARES \t %d \t %d", imaior, imenor); getche (); return 0; } Há algo a fazer para melhorar o código antes de avançá-lo para funções? Edited January 6, 2013 at 06:43 PM by pmg correcao ao GeSHi
pmg Posted January 6, 2013 at 06:48 PM Report #489913 Posted January 6, 2013 at 06:48 PM (edited) Se no entanto tiverem alguma indicação e crítica agradecerei. Peço-vos que sejam chatos nesse sentido. ... Há algo a fazer para melhorar o código antes de avançá-lo para funções? Indentacao: escolhe um estilo de indentacao e usa-o Nao compliques as condicoes logicas if (!(num % 2) == 0) pode ser escrito assim, com o operador "diferente de" if ((num % 2) != 0) Edited January 6, 2013 at 06:53 PM by pmg What have you tried? Não respondo a dúvidas por PM A minha bola de cristal está para compor; deve ficar pronta para a semana. Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!
HappyHippyHippo Posted January 6, 2013 at 06:58 PM Report #489914 Posted January 6, 2013 at 06:58 PM quais os valores de menores que te aparecem ? se meter valores negativos, quais os valores maiores que te aparecem ? IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Dexter's Lab Posted January 6, 2013 at 07:22 PM Author Report #489918 Posted January 6, 2013 at 07:22 PM Existe muita diferença entre colocar (!(num%2)==0), ((num%2)==1), ((num%2)!=0)? Em que situações se usa então o operador lógico NOT? Em relação à Indentação, o meu código está colocado, mas no copy paste e porque o coloquei em Código ficou assim chegado à esquerda. HHHippo, neste teste este foi o output: Limite de numeros a analisar: 8 1o valor: 8 2o valor: 7 3o valor: -3 4o valor: -2 5o valor: -45 6o valor: 8 7o valor: 78 8o valor: -23 MAIOR MENOR PARES 78 -2 IMPARES 7 -45
HappyHippyHippo Posted January 6, 2013 at 07:31 PM Report #489920 Posted January 6, 2013 at 07:31 PM Existe muita diferença entre colocar (!(num%2)==0), ((num%2)==1), ((num%2)!=0)? Em que situações se usa então o operador lógico NOT? o resultado é igual, a diferença na na legibilidade do código HHHippo, neste teste este foi o output: desculpa, testa com todos negativos IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
pmg Posted January 6, 2013 at 07:34 PM Report #489922 Posted January 6, 2013 at 07:34 PM E se meteres so valores negativos (nem zero nem nada acima de zero)? Em que situações se usa então o operador lógico NOT? Eu gosto de "ler" o codigo tal e qual como se fosse portugues (ou ingles). A expressao if (!(a == 0)) ... e lida mais ou menos assim: "se a nao for igual a zero"; eu prefiro ler "se a for diferente de zero" if (a != 0) ... Um exemplo onde o operador NOT se pode aplicar muito logicamente e com funcoes que devolvem um valor booleano if (!isblank(ch)) // se ch nao for um espaco em branco ou para "inverter" condicoes compostas if (!((100 <= a) && (a <= 999))) // se a estiver fora do intervalo 100 a 999 What have you tried? Não respondo a dúvidas por PM A minha bola de cristal está para compor; deve ficar pronta para a semana. Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!
Dexter's Lab Posted January 6, 2013 at 07:51 PM Author Report #489926 Posted January 6, 2013 at 07:51 PM Bem observado. Como estão iniciados a zero é isto que resulta. Limite de numeros a analisar: 6 1o valor: -6 2o valor: -78 3o valor: -9 4o valor: -4 5o valor: -35 6o valor: -6 MAIOR MENOR PARES 0 -6 IMPARES 0 -35 Penso que já resolvi. Eis a mudança que fiz no código tanto para o par como para o ímpar: if ((num%2)==0) { if (pmaior == 0) { pmenor = num; } else if (num < pmenor) { pmenor = num; } if (num > pmaior) { pmaior = num; } [b] else if (pmaior == 0 && num < pmaior) {[/b] [b] pmaior = num;[/b] [b] }[/b] } Novo teste: Limite de numeros a analisar: 6 1o valor: -2 2o valor: -7 3o valor: -8 4o valor: -78 5o valor: -9 6o valor: -1 MAIOR MENOR PARES -2 -78 IMPARES -1 -9
pmg Posted January 6, 2013 at 07:57 PM Report #489928 Posted January 6, 2013 at 07:57 PM So para ser mauzinho (LOL): testa com os seis numeros -1 0 1 2 3 4 🙂 What have you tried? Não respondo a dúvidas por PM A minha bola de cristal está para compor; deve ficar pronta para a semana. Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now