[DUVIDA] Duvida em um exercicio de liguagem de programação C

1. [DUVIDA] Duvida em um exercicio de liguagem de programação C

pedro vitor
pedronardoni

(usa Ubuntu)

Enviado em 19/03/2017 - 17:16h

Boa tarde, Pessoal.
Estou com uma duvida relativamente simples numa questão que pede que o usuário digite 5 notas, cada uma com uma casa decimal, e no final do programa mostre soma dessas notas, excluindo a maior e a menor notas das 5 digitadas inicialmente.
Fiz o codigo mas não está compilando, porém não sei se é problema no meu ubuntu ou no proprio codigo mesmo, alguem poderia dar uma olhada e vê se está tudo certinho? Desde já, obrigado. (A lista de exercicios vale 1 ponto, me ajudem por favor)

#include <stdio.h>
int main (){
double n[5], maior=0.0, menor=0.0, soma=0.0, extremos, nota;
int i;

printf ("Digite as 5 notas, cada uma entre 5 e 10, com uma casa decimal: ");

for (i=1;i<=5;i++){
printf ("Nota %d: ", i);
scanf ("%.1lf", &n[i]);
if (n[i]>maior){
maior=n[i];
}

if (n[i]<menor){
menor=n[i];
}
soma=soma+n[i];
}

extremos=maior+menor;
nota=soma-extremos;

printf ("A nota final da escola de samba, neste quesito, é: %.1lf", nota);

return 0;
}



  


2. Re: [DUVIDA] Duvida em um exercicio de liguagem de programação C

Paulo
paulo1205

(usa Ubuntu)

Enviado em 20/03/2017 - 00:02h

pedronardoni escreveu:

Boa tarde, Pessoal.
Estou com uma duvida relativamente simples numa questão que pede que o usuário digite 5 notas, cada uma com uma casa decimal, e no final do programa mostre soma dessas notas, excluindo a maior e a menor notas das 5 digitadas inicialmente.
Fiz o codigo mas não está compilando, porém não sei se é problema no meu ubuntu ou no proprio codigo mesmo, alguem poderia dar uma olhada e vê se está tudo certinho? Desde já, obrigado. (A lista de exercicios vale 1 ponto, me ajudem por favor)


Seu programa não tem nenhum erro de sintaxe. Contudo, ele tem erros semânticos e possíveis problemas de segurança.

Como os compiladores hoje em dia são capazes de pegar esses erros, pode ser que isso esteja impedindo uma compilação limpa.

De certa maneira, isso é bom. Se isso estiver acontecendo, é uma boa chance de você já aprender a programar usando técnicas adequadas, para não cair nos mesmos erros bobos que atormentavam os que, como eu, aprenderam a programar três décadas atrás.

#include <stdio.h>
int main (){


Primeiro problema aqui. Há duas maneiras corretas de declarar main em C:

1) Se ela não receber argumentos do ambiente de execução, você pode declará-la como “int main(void)” (o “void” na lista de arqgumentos significa justamente que essa é uma lista vazia).

2) Se ela receber argumentos do ambiente de execução, tais argumentos serão passados ao programa através de um vetor de strings e de um valor inteiro que indica quantos elementos há nesse vetor. Assim sendo, a declaração tem ter a forma “int main(int argc, char **argv)”, com argc funcionando como contador da quantidade de argumentos, e argv servindo como vetor cujos elementos apontam para strings que contêm os valores textuais de cada argumento recebido.

A declaração que você usou significa, em C, que a função main() pode receber qualquer quantidade de argumentos de quaisquer tipos.

	double n[5], maior=0.0, menor=0.0, soma=0.0, extremos, nota;
int i;

printf ("Digite as 5 notas, cada uma entre 5 e 10, com uma casa decimal: ");

for (i=1;i<=5;i++){


Aqui você varia a variável i, que vai fazer o papel de índice do array, entre 1 e 5. No entanto, os índices de arrays em C começam sempre com zero. Assim sendo, um array com cinco elementos só pode ter índices que vão de 0 a 4 (note que isso dá cinco valores possíveis: 0, 1, 2, 3 e 4).

A maneira canônica de fazer em C um laço com N repetições, é começar com zero, e repetir enquando a variável de controle for menor que N. Isso é particularmente verdadeiro se a variável de controle for usada para indexar arrays, como é o seu caso.

		printf ("Nota %d: ", i); 


Se você ajustar o laço de repetição como eu sugeri (que não é invenção minha, mas sim a prática de toda a comunidade que usa C no planeta), na hora de imprimir com sentido ordinal, você teria de usar i+1.

		scanf ("%.1lf", &n[i ]); 


Essa string de formatação está errada. A sintaxe de especificação de precisão não existe para scanf(). O máximo que você consegue fazer com scanf() é limitar a quantidade de caracteres a ser lida (por exemplo, fazendo algo como “"%5lf"”, que lhe permitiria pegar os cinco primeiros caracteres de um texto digitado como “1.234567890”, extraindo dele o valor 1.234). Portanto, pode tirar aquele caráter ponto dali, pois ele está comprometendo a correção e o funcionamento do programa.

		if (n[i ]>maior){
maior=n[i ];
}

if (n[i ]<menor){
menor=n[ i];
}
soma=soma+n[ i];
}


Depois de ter dito o que eu disse acima, agora vou desconstruir um pouco, mas porque o algoritmo e os requisitos do seu programa exigem isso.

Veja: você começa dizendo que a menor nota é zero. Mas se todas as notas que o usuário digitar estão entre 5 e 10 (possivelmente sempre perto de 10, se for para parecer com a realidade que eu lembro de um dia ter assistido em apuração de campeonato de escolas de samba), nunca vai aparecer uma nota menor do que o valor inicialmente suposto, de modo que sua lógica não vai funcionar.

Você poderia supor que a menor inicialmente tem a maior nota possível, ou então o maior valor representável pelo tipo de dado (infinito positivo, que é um valor válido nos nossos PCs), e poderia fazer o oposto para o valor inicial da maior nota, e a sua lógica passaria a funcionar num PC.

Só que existe uma maneira bem melhor de fazer, e que vai funcionar mesmo em máquinas que não consigam representar infinitos positivo e negativo (porque elas existem!): leia a primeira nota fora do laço de repetição, e assuma inicialmente que tal nota é a maior e a menor, porque ela realmente é tanto a maior quanto a menor nota lida até aquele momento. Depois você prossegue com o laço de repetição iniciando no segundo elemento (ou seja, aquele cujo índice é igual a 1).

Aliás, você só usa o vetor para ler as notas, e não usa mais cada nota depois que o laço de repetição termina. Isso sugere fortemente que você não precisa de um vetor: uma variável comum daria conta do recado, podendo ser comparada com cada um dos extremos e tranquilamente adicionada à soma.

	extremos=maior+menor;
nota=soma-extremos;

printf ("A nota final da escola de samba, neste quesito, é: %.1lf", nota);

return 0;
}



3. Re: [DUVIDA] Duvida em um exercicio de liguagem de programação C

pedro vitor
pedronardoni

(usa Ubuntu)

Enviado em 20/03/2017 - 03:31h

paulo1205 escreveu:

pedronardoni escreveu:

Boa tarde, Pessoal.
Estou com uma duvida relativamente simples numa questão que pede que o usuário digite 5 notas, cada uma com uma casa decimal, e no final do programa mostre soma dessas notas, excluindo a maior e a menor notas das 5 digitadas inicialmente.
Fiz o codigo mas não está compilando, porém não sei se é problema no meu ubuntu ou no proprio codigo mesmo, alguem poderia dar uma olhada e vê se está tudo certinho? Desde já, obrigado. (A lista de exercicios vale 1 ponto, me ajudem por favor)


Seu programa não tem nenhum erro de sintaxe. Contudo, ele tem erros semânticos e possíveis problemas de segurança.

Como os compiladores hoje em dia são capazes de pegar esses erros, pode ser que isso esteja impedindo uma compilação limpa.

De certa maneira, isso é bom. Se isso estiver acontecendo, é uma boa chance de você já aprender a programar usando técnicas adequadas, para não cair nos mesmos erros bobos que atormentavam os que, como eu, aprenderam a programar três décadas atrás.

#include <stdio.h>
int main (){


Primeiro problema aqui. Há duas maneiras corretas de declarar main em C:

1) Se ela não receber argumentos do ambiente de execução, você pode declará-la como “int main(void)” (o “void” na lista de arqgumentos significa justamente que essa é uma lista vazia).

2) Se ela receber argumentos do ambiente de execução, tais argumentos serão passados ao programa através de um vetor de strings e de um valor inteiro que indica quantos elementos há nesse vetor. Assim sendo, a declaração tem ter a forma “int main(int argc, char **argv)”, com argc funcionando como contador da quantidade de argumentos, e argv servindo como vetor cujos elementos apontam para strings que contêm os valores textuais de cada argumento recebido.

A declaração que você usou significa, em C, que a função main() pode receber qualquer quantidade de argumentos de quaisquer tipos.

	double n[5], maior=0.0, menor=0.0, soma=0.0, extremos, nota;
int i;

printf ("Digite as 5 notas, cada uma entre 5 e 10, com uma casa decimal: ");

for (i=1;i<=5;i++){


Aqui você varia a variável i, que vai fazer o papel de índice do array, entre 1 e 5. No entanto, os índices de arrays em C começam sempre com zero. Assim sendo, um array com cinco elementos só pode ter índices que vão de 0 a 4 (note que isso dá cinco valores possíveis: 0, 1, 2, 3 e 4).

A maneira canônica de fazer em C um laço com N repetições, é começar com zero, e repetir enquando a variável de controle for menor que N. Isso é particularmente verdadeiro se a variável de controle for usada para indexar arrays, como é o seu caso.

		printf ("Nota %d: ", i); 


Se você ajustar o laço de repetição como eu sugeri (que não é invenção minha, mas sim a prática de toda a comunidade que usa C no planeta), na hora de imprimir com sentido ordinal, você teria de usar i+1.

		scanf ("%.1lf", &n[i ]); 


Essa string de formatação está errada. A sintaxe de especificação de precisão não existe para scanf(). O máximo que você consegue fazer com scanf() é limitar a quantidade de caracteres a ser lida (por exemplo, fazendo algo como “"%5lf"”, que lhe permitiria pegar os cinco primeiros caracteres de um texto digitado como “1.234567890”, extraindo dele o valor 1.234). Portanto, pode tirar aquele caráter ponto dali, pois ele está comprometendo a correção e o funcionamento do programa.

		if (n[i ]>maior){
maior=n[i ];
}

if (n[i ]<menor){
menor=n[ i];
}
soma=soma+n[ i];
}


Depois de ter dito o que eu disse acima, agora vou desconstruir um pouco, mas porque o algoritmo e os requisitos do seu programa exigem isso.

Veja: você começa dizendo que a menor nota é zero. Mas se todas as notas que o usuário digitar estão entre 5 e 10 (possivelmente sempre perto de 10, se for para parecer com a realidade que eu lembro de um dia ter assistido em apuração de campeonato de escolas de samba), nunca vai aparecer uma nota menor do que o valor inicialmente suposto, de modo que sua lógica não vai funcionar.

Você poderia supor que a menor inicialmente tem a maior nota possível, ou então o maior valor representável pelo tipo de dado (infinito positivo, que é um valor válido nos nossos PCs), e poderia fazer o oposto para o valor inicial da maior nota, e a sua lógica passaria a funcionar num PC.

Só que existe uma maneira bem melhor de fazer, e que vai funcionar mesmo em máquinas que não consigam representar infinitos positivo e negativo (porque elas existem!): leia a primeira nota fora do laço de repetição, e assuma inicialmente que tal nota é a maior e a menor, porque ela realmente é tanto a maior quanto a menor nota lida até aquele momento. Depois você prossegue com o laço de repetição iniciando no segundo elemento (ou seja, aquele cujo índice é igual a 1).

Aliás, você só usa o vetor para ler as notas, e não usa mais cada nota depois que o laço de repetição termina. Isso sugere fortemente que você não precisa de um vetor: uma variável comum daria conta do recado, podendo ser comparada com cada um dos extremos e tranquilamente adicionada à soma.

	extremos=maior+menor;
nota=soma-extremos;

printf ("A nota final da escola de samba, neste quesito, é: %.1lf", nota);

return 0;
}


Muito obrigado de verdade!!! Foi muito esclarecedor mesmo, obg!!! Consegui fazer o programa rodar direitinho.







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts