Recursividade [RESOLVIDO]

1. Recursividade [RESOLVIDO]

Matheus de Castro Oliveira
Matheus10772

(usa Linux Mint)

Enviado em 22/05/2019 - 22:37h

Olá. Estou aprendendo a programar em C e estou enfrentando algumas dificuldades para entender funções recursivas.
Alguém consegue me dizer qual o erro do código, porque está errado e como consertar:

#include <stdio.h>
#include<stdlib.h>

int soma(int valor[],int y){
int i=y-1;

if(i>=0){
return valor[i] + soma valor[i-1];
}
}

void main () {
int x;

printf("\ndigite a quantidade de números que deseja somar.\n");
scanf("%d", &x);

int numeros[x],resultado;

printf("\nDigite os números para que a soma seja realizada.\n");
resultado=soma(numeros, x);
printf("\nA soma dos números é %d\n", resultado);
}



  


2. Re: Recursividade [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 23/05/2019 - 09:12h

Faltam pedaços do programa (por exemplo: a leitura das parcelas).

O tipo de retorno de main() tem de ser int, e sua lista de parâmetros não deve ser vazia, mas deve ser ou “void”, no caso de você não querer nenhum argumento, ou “int argc, char **argv”, se você quiser receber argumentos na forma de um array com argc elementos strings, contidas em argv[0] até argv[argc-1].

Na função soma(), se o parâmetro y receber como argumento um valor menor que 1, a função chega ao final sem retornar valor nenhum, o que viola a indicação de que o tipo de retorno é int.

Na mesma função, a linha que diz “return valor[i] + soma valor[i-1];” está sintaticamente errada. Se você quis invocar soma() recursivamente, faltaram os parênteses e o segundo argumento, e o tipo de “argv[i-1]” não seria compatível com o tipo do primeiro parâmetro.

Ainda em soma(), a variável i é desnecessária, especialmente se você lembrar que todas as chamadas a funções geram cópias dos valores dos argumentos, de modo que seria seguro você alterar o valor do parâmetro y dentro da função.


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


3. Re: Recursividade [RESOLVIDO]

Matheus de Castro Oliveira
Matheus10772

(usa Linux Mint)

Enviado em 25/05/2019 - 16:11h

paulo1205 escreveu:

Faltam pedaços do programa (por exemplo: a leitura das parcelas).

O tipo de retorno de main() tem de ser int, e sua lista de parâmetros não deve ser vazia, mas deve ser ou “void”, no caso de você não querer nenhum argumento, ou “int argc, char **argv”, se você quiser receber argumentos na forma de um array com argc elementos strings, contidas em argv[0] até argv[argc-1].

Na função soma(), se o parâmetro y receber como argumento um valor menor que 1, a função chega ao final sem retornar valor nenhum, o que viola a indicação de que o tipo de retorno é int.

Na mesma função, a linha que diz “return valor[i] + soma valor[i-1];” está sintaticamente errada. Se você quis invocar soma() recursivamente, faltaram os parênteses e o segundo argumento, e o tipo de “argv[i-1]” não seria compatível com o tipo do primeiro parâmetro.

Ainda em soma(), a variável i é desnecessária, especialmente se você lembrar que todas as chamadas a funções geram cópias dos valores dos argumentos, de modo que seria seguro você alterar o valor do parâmetro y dentro da função.


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)

]






Na verdade, a função main não precisa ser do tipo int porque eu não preciso retornar nada. E os parenteses pode ficar vazios, escrever void dentro deles é opcional.

Com relação a função soma, eu modifiquei o código, mas ainda não consigo entender o que pode estar errado.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>

float soma (float valor[], int X){
if(valor[X]==0) return 0;
return valor[X] + soma(valor[], X-1);
}

void main() {
int x,X;
printf("\nDigite quantos números deseja somar ");
scanf("%d", &x);
X=x+1;
float valor[X],resultado;
valor[0]=0;

printf("\nDigite números para somar");
for(int i=1; i<=X; i++){
scanf("%f", &valor[i]);
}
resultado=soma(valor,X);
printf("A soma é %f", resultado);
}




4. Re: Recursividade [RESOLVIDO]

Matheus de Castro Oliveira
Matheus10772

(usa Linux Mint)

Enviado em 25/05/2019 - 17:04h

Matheus10772 escreveu:

paulo1205 escreveu:

Faltam pedaços do programa (por exemplo: a leitura das parcelas).

O tipo de retorno de main() tem de ser int, e sua lista de parâmetros não deve ser vazia, mas deve ser ou “void”, no caso de você não querer nenhum argumento, ou “int argc, char **argv”, se você quiser receber argumentos na forma de um array com argc elementos strings, contidas em argv[0] até argv[argc-1].

Na função soma(), se o parâmetro y receber como argumento um valor menor que 1, a função chega ao final sem retornar valor nenhum, o que viola a indicação de que o tipo de retorno é int.

Na mesma função, a linha que diz “return valor[i] + soma valor[i-1];” está sintaticamente errada. Se você quis invocar soma() recursivamente, faltaram os parênteses e o segundo argumento, e o tipo de “argv[i-1]” não seria compatível com o tipo do primeiro parâmetro.

Ainda em soma(), a variável i é desnecessária, especialmente se você lembrar que todas as chamadas a funções geram cópias dos valores dos argumentos, de modo que seria seguro você alterar o valor do parâmetro y dentro da função.


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)

]






Na verdade, a função main não precisa ser do tipo int porque eu não preciso retornar nada. E os parenteses pode ficar vazios, escrever void dentro deles é opcional.

Com relação a função soma, eu modifiquei o código, mas ainda não consigo entender o que pode estar errado.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>

float soma (float valor[], int X){
if(valor[X]==0) return 0;
return valor[X] + soma(valor[], X-1);
}

void main() {
int x,X;
printf("\nDigite quantos números deseja somar ");
scanf("%d", &x);
X=x+1;
float valor[X],resultado;
valor[0]=0;

printf("\nDigite números para somar");
for(int i=1; i<=X; i++){
scanf("%f", &valor[i]);
}
resultado=soma(valor,X);
printf("A soma é %f", resultado);
}







Fiz novas alterações no código, mas agora o compilador acusa erro nos colchetes de "valor", dentro da função soma.


#include<stdio.h>
#include<stdlib.h>
#include<string.h>


float soma (float valor[], int X){
if(valor[X]==0) return 0;
else
{
return (valor[X] + soma (valor[], X-1));
}

}

void main() {
int x,X;
printf("\nDigite quantos números deseja somar ");
scanf("%d", &x);
X=x+1;
float valor[X],resultado;
valor[0]=0;

printf("\nDigite números para somar");
for(int i=1; i<=X; i++){
scanf("%f", &valor[i]);
}
resultado=soma(valor,X);
printf("A soma é %f", resultado);
}



5. Re: Recursividade [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 25/05/2019 - 18:02h

Matheus10772 escreveu:

Na verdade, a função main não precisa ser do tipo int porque eu não preciso retornar nada.


Errado. Se o seu programa executar num sistema operacional como Linux, Windows ou MS-DOS, ou qualquer outro que caracterize que um ambiente hspedado (hosted environment) para o programa em C, então o padrão da linguagem (§5.1.2.2.1 do padrão de 2011, que é pago, mas cujo rascunho pode ser encontrado em http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf) determina que você tem de retornar um valor do tipo int. E essa determinação já existia desde o primeiro padrão (de 1989).

Se o seu compilador está aceitando outra especificação, é porque eles deve estar compilando em modo permissivo (geralmente para habilitar a compilação de código obsoleto, anterior à padronização do C) e com opções de diagnóstico desabilitadas. Não tome esse caso como se fosse a regra, pois não é.

Eu recomendo fortemente que você não utilize código obsoleto. E recomendo também que você ligue o máximo de opções de diagnóstico que seu compilador tiver (se você estiver usando o compilador do GCC, indico pelo menos as opções “-O2 -Wall -Werror -pedantic-errors”), pois elas ajudarão você a garantir que seu código vai conseguir compilar com o mínimo de dificuldades em múltiplos ambientes diferentes.

E os parenteses pode ficar vazios, escrever void dentro deles é opcional.


Não é opcional em C (poderia ser em C++, que tem uma semântica para a lista de argumentos vazias diferente da que tem o C, mas não parece que você esteja usando C++). A mesma §5.1.2.2.1 determina que você deve usar uma das formas alternativas que eu indiquei na mensagem anterior.

Em C, a lista de argumentos vazia significa que a função pode receber qualquer quantidade de argumentos de quaisquer tipos.

Com relação a função soma, eu modifiquei o código, mas ainda não consigo entender o que pode estar errado.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>

float soma (float valor[], int X){
if(valor[X]==0) return 0;


Tem certeza de que o critério para interromper a recursividade depende do valor do elemento? Não seria com base no índice desse elemento?

     return valor[X] + soma(valor[], X-1); 


Esses colchetes vazios estão errados.

Eu tenho quase certeza de que o seu compilador deve ter alarmado a respeito dessa linha, indicando erro de sintaxe, não? Se sim, então existe uma indicação clara de erro que você poderia ter corrigido antes de postar o código aqui.

}

void main() {


Duas violações da §51.2.2.1 na declaração de main().

    int x,X; 


Aconselho-o a usar nomes mais significativos para suas variáveis, e evite usar nomes distintos entre si apenas no fato de que um usa letras minúsculas e o outro, maiúsculas, e mais especialmente quando as letras minúsculas e maiúsculas tem formatos muito parecidos, pois isso dificulta a leitura, tanto visualmente quanto semanticamente.

    printf("\nDigite quantos números deseja somar ");
scanf("%d", &x);


Alguns sistemas modernos (por exemplo, todos os derivados do Debian, incluindo Ubuntu e Mint) podem reclamar do fato de você não verificar o valor de retorno de scanf(), pelo potencial que isso abre para que uma falha de segurança e erros de execução, pois o valor da variável que deveria ter sido lida mas não foi pode ficar indefinido.

Acostume-se, portanto, a verificar o estado da entrada após o retorno de cada operação de leitura.

    X=x+1;
float valor[X],resultado;
valor[0]=0;


Se você usar o índice do elemento na função soma(), não vai precisar da gambiarra de usar um elemento a mais. Até porque, se você não conhecer antecipadamente os dados que o usuário do seu programa tiver, não deveria impedi-lo, na prática, de colocar uma das parcelas como zero.


printf("\nDigite números para somar");
for(int i=1; i<=X; i++){


Esse “<=” está errado. Deveria ser apenas “<”.

E se você usar o índice em lugar do valor em soma(), pode contar de [0, x), em lugar de [1, X) (e pior ainda se for [1, X], por causa do “<=”).

    scanf("%f", &valor[i]);
}
resultado=soma(valor,X);
printf("A soma é %f", resultado);
}



... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


6. Re: Recursividade [RESOLVIDO]

Matheus de Castro Oliveira
Matheus10772

(usa Linux Mint)

Enviado em 25/05/2019 - 19:24h

paulo1205 escreveu:

Matheus10772 escreveu:

Na verdade, a função main não precisa ser do tipo int porque eu não preciso retornar nada.


Errado. Se o seu programa executar num sistema operacional como Linux, Windows ou MS-DOS, ou qualquer outro que caracterize que um ambiente hspedado (hosted environment) para o programa em C, então o padrão da linguagem (§5.1.2.2.1 do padrão de 2011, que é pago, mas cujo rascunho pode ser encontrado em http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf) determina que você tem de retornar um valor do tipo int. E essa determinação já existia desde o primeiro padrão (de 1989).

Se o seu compilador está aceitando outra especificação, é porque eles deve estar compilando em modo permissivo (geralmente para habilitar a compilação de código obsoleto, anterior à padronização do C) e com opções de diagnóstico desabilitadas. Não tome esse caso como se fosse a regra, pois não é.

Eu recomendo fortemente que você não utilize código obsoleto. E recomendo também que você ligue o máximo de opções de diagnóstico que seu compilador tiver (se você estiver usando o compilador do GCC, indico pelo menos as opções “-O2 -Wall -Werror -pedantic-errors”), pois elas ajudarão você a garantir que seu código vai conseguir compilar com o mínimo de dificuldades em múltiplos ambientes diferentes.

E os parenteses pode ficar vazios, escrever void dentro deles é opcional.


Não é opcional em C (poderia ser em C++, que tem uma semântica para a lista de argumentos vazias diferente da que tem o C, mas não parece que você esteja usando C++). A mesma §5.1.2.2.1 determina que você deve usar uma das formas alternativas que eu indiquei na mensagem anterior.

Em C, a lista de argumentos vazia significa que a função pode receber qualquer quantidade de argumentos de quaisquer tipos.

Com relação a função soma, eu modifiquei o código, mas ainda não consigo entender o que pode estar errado.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>

float soma (float valor[], int X){
if(valor[X]==0) return 0;


Tem certeza de que o critério para interromper a recursividade depende do valor do elemento? Não seria com base no índice desse elemento?

     return valor[X] + soma(valor[], X-1); 


Esses colchetes vazios estão errados.

Eu tenho quase certeza de que o seu compilador deve ter alarmado a respeito dessa linha, indicando erro de sintaxe, não? Se sim, então existe uma indicação clara de erro que você poderia ter corrigido antes de postar o código aqui.

}

void main() {


Duas violações da §51.2.2.1 na declaração de main().

    int x,X; 


Aconselho-o a usar nomes mais significativos para suas variáveis, e evite usar nomes distintos entre si apenas no fato de que um usa letras minúsculas e o outro, maiúsculas, e mais especialmente quando as letras minúsculas e maiúsculas tem formatos muito parecidos, pois isso dificulta a leitura, tanto visualmente quanto semanticamente.

    printf("\nDigite quantos números deseja somar ");
scanf("%d", &x);


Alguns sistemas modernos (por exemplo, todos os derivados do Debian, incluindo Ubuntu e Mint) podem reclamar do fato de você não verificar o valor de retorno de scanf(), pelo potencial que isso abre para que uma falha de segurança e erros de execução, pois o valor da variável que deveria ter sido lida mas não foi pode ficar indefinido.

Acostume-se, portanto, a verificar o estado da entrada após o retorno de cada operação de leitura.

    X=x+1;
float valor[X],resultado;
valor[0]=0;


Se você usar o índice do elemento na função soma(), não vai precisar da gambiarra de usar um elemento a mais. Até porque, se você não conhecer antecipadamente os dados que o usuário do seu programa tiver, não deveria impedi-lo, na prática, de colocar uma das parcelas como zero.


printf("\nDigite números para somar");
for(int i=1; i<=X; i++){


Esse “<=” está errado. Deveria ser apenas “<”.

E se você usar o índice em lugar do valor em soma(), pode contar de [0, x), em lugar de [1, X) (e pior ainda se for [1, X], por causa do “<=”).

    scanf("%f", &valor[i]);
}
resultado=soma(valor,X);
printf("A soma é %f", resultado);
}



... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)


corrigi o colchete e o código funcionou. Mais tarde vou dar uma olhada nas sugestões que me fez, mas por hora, vou colocar o tópico como resolvido.


#include<stdio.h>
#include<stdlib.h>
#include<string.h>


float soma (float valor[], int X){
if(valor[X]==0) return 0;
else
{
return (valor[X] + soma (valor, X-1));
}

}

void main() {
int x,X;
printf("\nDigite quantos números deseja somar ");
scanf("%d", &x);
X=x;
float valor[X],resultado;
valor[0]=0;

printf("\nDigite números para somar");
for(int i=1; i<=X; i++){
scanf("%f", &valor[i]);
}
resultado=soma(valor,X);
printf("A soma é %f", resultado);
}




7. Re: Recursividade [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 26/05/2019 - 21:32h

Você pediu ajuda e recebeu. Contudo, mostrou pouco interesse (e até algum desprezo, fundamentado em pura falta de conhecimento da sua parte) pela ajuda que recebeu. Isso desanima.

Mesmo assim, eu não posso me omitir de dizer que a forma final do seu programa continua com erros. Não apenas os erros formais que você escolheu fingir que não existem, mas pelo menos um erro crasso, que é o de usar mais elementos do vetor do que os que você declarou, o que significa necessariamente que você está corrompendo alguma coisa na memória que porventura esteja logo após o fim do vetor.


... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner
Linux banner

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts