Aprendendo programar em C [RESOLVIDO]

1. Aprendendo programar em C [RESOLVIDO]

Matheus de Castro Oliveira
Matheus10772

(usa Linux Mint)

Enviado em 26/05/2019 - 14:07h

Estou aprendendo a programar em C e toda vez que tento executar o programa a seguir, o terminal retorna a seguinte mensagem "Segmentation fault (core dumped)"

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


float fatorial(float n){
float x=n;
if(n==1){return 1;}
for(int i=1;i<=n;i++){
x=x*n;
}
return (x + fatorial(n-1));
}



void main() {
float n,resultado;
printf("\nDigite um número n para calcular o hiperfatorial");
resultado=fatorial(n);
printf("\nO resultado do hiperfatorial %f é %f", n,resultado);
}




  


2. Re: Aprendendo programar em C [RESOLVIDO]

José
DeuRuimDotCom

(usa Linux Mint)

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

Há muitas impropriedades em seu código. Para começo de conversa, não há sequer valor de entrada.
Acho que esse erro deriva disso, você apenas declarou a variável "n", sem lhe atribuir um valor.


3. Re: Aprendendo programar em C

Paulo
paulo1205

(usa Ubuntu)

Enviado em 27/05/2019 - 09:40h

A causa provável é o que disse nosso colega DeuRuimDotCom. É possível que esse valor indefinido seja negativo ou que seja absurdamente grande, e isso pode provocar tantos níveis de recursividade que esgotam a memória entregue ao programa para a pilha de execução.

Como se proteger de situações como essa? Seguem algumas dicas:

1) Invoque o compilador de modo a maximizar o diagnóstico de código
Para os compiladores do GCC, use sempre, no mínimo, as opções “-Wall -Werror -pedantic-errors -O2”. Entre outras coisas que ajudam a produzir código mais seguro, essas opções vão fazer com o compilador emita um alerta e interrompa a compilação caso ele detecte que uma variável foi usada antes de ter sido inicializada.

2) Faça com que suas funções rejeitem argumentos inválidos passados como parâmetros
Faz sentido falar em fatorial (ou hiperfatorial) de números negativos? Se não, recuse tais argumentos, sinalizando erro (no seu caso, a função poderia devolver NaN).

3) Avalie se você precisa realmente de recursividade
Recursividade é muitas vezes considerada uma forma elegante de expressar matematicamente certas construções. Contudo, no contexto de linguagens de programação imperativas como C e C++, pode vir a se mostrar muito ineficiente, tanto quanto a alocação de recursos quanto em tempo de execução. Se você não tiver de resolver o problema por recursividade, considere muito as eventuais formas não-recursivas.


Fora isso, algumas outras observações:

Procure usar para a função um nome que reflita o que ela realmente faz
“Fatorial” é um conceito matemático muito bem estabelecido. Se a sua função chamada “fatorial” calcula algo que é diferente desse conceito bem estabelecido, você deveria trocar o nome da função.

Tem certeza de que está realmente calculando uma hiperfatorial?
Aquela operação de soma que aparece na recursividade da sua função me pareceu muito estranha numa função que tem “fatorial” como nome (ou parte do nome). Ao procurar definições de hiperfatorial, todas elas falavam em um produtório de cujos fatores têm a forma i elevado a i-ésima potência (em C, “pow(i, i)”), para todo i inteiro no intervalo fechado de 1 a n. Assim, a função que você definiu com o nome de “fatorial” não calcula a fatorial nem o que geralmente se conhece como hiperfatorial, mas alguma outra coisa.


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


4. Re: Aprendendo programar em C [RESOLVIDO]

Matheus de Castro Oliveira
Matheus10772

(usa Linux Mint)

Enviado em 27/05/2019 - 17:35h

paulo1205 escreveu:

A causa provável é o que disse nosso colega DeuRuimDotCom. É possível que esse valor indefinido seja negativo ou que seja absurdamente grande, e isso pode provocar tantos níveis de recursividade que esgotam a memória entregue ao programa para a pilha de execução.

Como se proteger de situações como essa? Seguem algumas dicas:

1) Invoque o compilador de modo a maximizar o diagnóstico de código
Para os compiladores do GCC, use sempre, no mínimo, as opções “-Wall -Werror -pedantic-errors -O2”. Entre outras coisas que ajudam a produzir código mais seguro, essas opções vão fazer com o compilador emita um alerta e interrompa a compilação caso ele detecte que uma variável foi usada antes de ter sido inicializada.

2) Faça com que suas funções rejeitem argumentos inválidos passados como parâmetros
Faz sentido falar em fatorial (ou hiperfatorial) de números negativos? Se não, recuse tais argumentos, sinalizando erro (no seu caso, a função poderia devolver NaN).

3) Avalie se você precisa realmente de recursividade
Recursividade é muitas vezes considerada uma forma elegante de expressar matematicamente certas construções. Contudo, no contexto de linguagens de programação imperativas como C e C++, pode vir a se mostrar muito ineficiente, tanto quanto a alocação de recursos quanto em tempo de execução. Se você não tiver de resolver o problema por recursividade, considere muito as eventuais formas não-recursivas.


Fora isso, algumas outras observações:

Procure usar para a função um nome que reflita o que ela realmente faz
“Fatorial” é um conceito matemático muito bem estabelecido. Se a sua função chamada “fatorial” calcula algo que é diferente desse conceito bem estabelecido, você deveria trocar o nome da função.

Tem certeza de que está realmente calculando uma hiperfatorial?
Aquela operação de soma que aparece na recursividade da sua função me pareceu muito estranha numa função que tem “fatorial” como nome (ou parte do nome). Ao procurar definições de hiperfatorial, todas elas falavam em um produtório de cujos fatores têm a forma i elevado a i-ésima potência (em C, “pow(i, i)”), para todo i inteiro no intervalo fechado de 1 a n. Assim, a função que você definiu com o nome de “fatorial” não calcula a fatorial nem o que geralmente se conhece como hiperfatorial, mas alguma outra coisa.


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


Corrigi o código

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


float hiperfatorial(float n){
float x;
if(n==1){return 1;}
x=pow(n,n);
return (x+fatorial (n-1));
}



int main(void) {
float n,resultado;
printf("\nDigite um número n para calcular o hiperfatorial");
scanf("%f", &n);
resultado=fatorial(n);
printf("\nO resultado do hiperfatorial de %f é %f", n,resultado);

return 0;
}

Pelo que eu etendi o hiper fatorial se calcula assim:
hiperfatorial de 5 é 5^5+4^4+3^3+2^2+1^1

e com relação a necessidade de usar a recursividade, existe sim um modo de fazer esse código usando o laço interativo, mas meu professor pediu para fazer usando recursividade para que possamos aprender.


5. Re: Aprendendo programar em C [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 27/05/2019 - 18:32h

Ainda está errado. Em lugar de somar pow(n, n) com hyperfactorial(n-1), você provavelmente quer o produto entre eles.


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


6. Re: Aprendendo programar em C [RESOLVIDO]

Matheus de Castro Oliveira
Matheus10772

(usa Linux Mint)

Enviado em 27/05/2019 - 21:52h

paulo1205 escreveu:

Ainda está errado. Em lugar de somar pow(n, n) com hyperfactorial(n-1), você provavelmente quer o produto entre eles.


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


paulo1205 escreveu:

A causa provável é o que disse nosso colega DeuRuimDotCom. É possível que esse valor indefinido seja negativo ou que seja absurdamente grande, e isso pode provocar tantos níveis de recursividade que esgotam a memória entregue ao programa para a pilha de execução.

Como se proteger de situações como essa? Seguem algumas dicas:

1) Invoque o compilador de modo a maximizar o diagnóstico de código
Para os compiladores do GCC, use sempre, no mínimo, as opções “-Wall -Werror -pedantic-errors -O2”. Entre outras coisas que ajudam a produzir código mais seguro, essas opções vão fazer com o compilador emita um alerta e interrompa a compilação caso ele detecte que uma variável foi usada antes de ter sido inicializada.

2) Faça com que suas funções rejeitem argumentos inválidos passados como parâmetros
Faz sentido falar em fatorial (ou hiperfatorial) de números negativos? Se não, recuse tais argumentos, sinalizando erro (no seu caso, a função poderia devolver NaN).

3) Avalie se você precisa realmente de recursividade
Recursividade é muitas vezes considerada uma forma elegante de expressar matematicamente certas construções. Contudo, no contexto de linguagens de programação imperativas como C e C++, pode vir a se mostrar muito ineficiente, tanto quanto a alocação de recursos quanto em tempo de execução. Se você não tiver de resolver o problema por recursividade, considere muito as eventuais formas não-recursivas.


Fora isso, algumas outras observações:

Procure usar para a função um nome que reflita o que ela realmente faz
“Fatorial” é um conceito matemático muito bem estabelecido. Se a sua função chamada “fatorial” calcula algo que é diferente desse conceito bem estabelecido, você deveria trocar o nome da função.

Tem certeza de que está realmente calculando uma hiperfatorial?
Aquela operação de soma que aparece na recursividade da sua função me pareceu muito estranha numa função que tem “fatorial” como nome (ou parte do nome). Ao procurar definições de hiperfatorial, todas elas falavam em um produtório de cujos fatores têm a forma i elevado a i-ésima potência (em C, “pow(i, i)”), para todo i inteiro no intervalo fechado de 1 a n. Assim, a função que você definiu com o nome de “fatorial” não calcula a fatorial nem o que geralmente se conhece como hiperfatorial, mas alguma outra coisa.


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


Corrigi o código

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


float hiperfatorial(float n){
float x;
if(n==1){return 1;}
x=pow(n,n);
return (x+fatorial (n-1));
}



int main(void) {
float n,resultado;
printf("\nDigite um número n para calcular o hiperfatorial");
scanf("%f", &n);
resultado=fatorial(n);
printf("\nO resultado do hiperfatorial de %f é %f", n,resultado);

return 0;
}

Pelo que eu etendi o hiper fatorial se calcula assim:
hiperfatorial de 5 é 5^5+4^4+3^3+2^2+1^1

e com relação a necessidade de usar a recursividade, existe sim um modo de fazer esse código usando o laço interativo, mas meu professor pediu para fazer usando recursividade para que possamos aprender.


Na verdade é preciso calcular a soma do números elevados a uma potência de valor igual ao prórpio número.

Exemplo: hiperfatorial de 5= 5^5+4^4+3^3+2^2+1^1

então o código está correto. Eu fiz o teste, o programa retornou o resultado correto



7. Re: Aprendendo programar em C [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 28/05/2019 - 10:14h

Matheus10772 escreveu:

Na verdade é preciso calcular a soma do números elevados a uma potência de valor igual ao prórpio número.

Exemplo: hiperfatorial de 5= 5^5+4^4+3^3+2^2+1^1

então o código está correto. Eu fiz o teste, o programa retornou o resultado correto


De onde veio essa definição? Porque tanto na Wikipedia (https://en.wikipedia.org/wiki/Factorial#Hyperfactorial) quanto Wolfram MathWorld (http://mathworld.wolfram.com/Hyperfactorial.html) e em todos os outros sites em que eu olhei, a hiperfatorial é definida como o produtório (não como somatório!) de k^k, para todo k inteiro e maior ou igual a 1 (recursivamente, H(1)=1; H(k)=k^k×H(k-1), k>1).

Se seu enunciado usa soma, então seu professor foi quem errou. E erro crasso, porque “fatorial” implica fatores, e fatores implicam multiplicação. Se fosse soma, seriam parcelas (ou termos).


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






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts