Ir para o conteúdo
Dexter's Lab

Problema com código par/impar, maior/menor

Mensagens Recomendadas

Dexter's Lab

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

Editado por Dexter's Lab
Falta LP

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

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.

Editado por 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!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Dexter's Lab

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;
}

Editado por pmg
apaguei formatacao, adicionei GeSHi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

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.

Editado por 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!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Dexter's Lab

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.

Editado por apocsantos
geshi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
thoga31

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;

Editado por thoga31

Knowledge is free!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Dexter's Lab

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

Editado por Dexter's Lab

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

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 *);

Editado por 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!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Dexter's Lab

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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

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.

Editado por 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!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Dexter's Lab

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?

Editado por pmg
correcao ao GeSHi

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

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)

Editado por 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!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Dexter's Lab

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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

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!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Dexter's Lab

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

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

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!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

Vou procurar resolver.

empurrãozinho : como sabes que o valor pmaior ou pmenor ou imaior ou imenor contem um valor inserido ?


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
Dexter's Lab

Já me apareceu corretamente o menor sendo 0 e os outros valores corretos também.

	else if ((num%2)!=0) {
					[b] if (iaux == 0) [/b]{
							   imenor = num;
[b]								   iaux++;[/b]
							   }
							   else if (num < imenor) {
									imenor = num;
									}

					 if (num > imaior) {
							 imaior = num;
							 }
[b]								 else if (iaux == 0 && num < imaior) {[/b]
							 iaux++;
							 imaior = num;
							 }
					 }

Adicionei outra variável que tomou lugar ao pmaior/imaior com a referência do 0 para demarcar a primeira volta.

Assim o programa já não vbloqueia o 0 de pertencer aos pares.

empurrãozinho : como sabes que o valor pmaior ou pmenor ou imaior ou imenor contem um valor inserido ?

Neste momento, na primeira volta nenhum o tem. Apenas o auxiliar tem o valor de 0.

A cada volta que recolhe numeros pares e impares empurra-os para a variável correspondente e mantêm-se até ser empurrado um novo numero par/impar, superior/inferior.

Não sei se era aqui que querias chegar. Desculpa se não era.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

estás a ir bem, mas agora testa estes valores :

1 3 5 7 -4 9

deveria aparecer :

pmenor = -4

pmaior = -4

imenor = 1

imaior = 9

no entanto, parece-me que irá aparecer

pmenor = -4

pmaior = 0

imenor = 1

imaior = 9


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
thoga31

@Dexter's Lab, a inicialização deverá ser feita com o primeiro valor inserido. É isto que te está a faltar. Depois disso é que se faz o ciclo com comparação.

pmaior = pmenor = imaior = imenor = num;
for(i = 1; i < total; i++) { // etc...

Não podes começar com o valor 0, se não há sempre os problemas que te têm aparecido com os inputs que te têm proposto.

  • Voto 1

Knowledge is free!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.