Ir ao conteúdo
  • Cadastre-se

C Função recursiva em C


kampa896

Posts recomendados

Pessoal, boa tarde. Estou iniciando meus estudos em C, e estou com algumas questões pra praticar, juntamente com questões propostas pela faculdade.

Eles deram o seguinte problema:

"Faça, em linguagem C, uma função recursiva para o cálculo potenciação. Sabe-se que o cálculo pode ser feito através de multiplicações sucessivas. Para demonstrar o funcionamento utilize o primeiro digito do seu RU como base e o último digito como expoente."

 

Fiz um código aqui, mas não estou entendendo a saída dele.

 

#include <stdio.h>

void multiplica(int base, int cont, int exp);

int main(){

    int base, expoente;

    printf("Digite a base: ");
    scanf("%d", &base);
    printf("Digite o expoente: ");
    scanf("%d", &expoente);


    multiplica(base, 2, expoente);
#include <stdio.h>

void multiplica(int base, int cont, int exp);

int main(){

    int base, expoente;

    printf("Digite a base: ");
    scanf("%d", &base);
    printf("Digite o expoente: ");
    scanf("%d", &expoente);


    multiplica(base, 2, expoente);




    return 0;
}

void multiplica(int base, int cont, int exp){
    int aux;

	if(exp == 0){
		aux = 1;
	}
	if(exp == 1){
		aux = base;
	}
	if(exp == 2){
		aux = base * base;
	}
	while(exp > 2 && cont <= exp){
		if(cont == 2){
			aux = base * base;
			cont++;
			multiplica(aux, cont, exp);
		}
		else{
			aux = aux * base;
			cont++;
			multiplica(aux, cont, exp);
		}
	}
    printf("%d", aux);
}

    return 0;
}

void multiplica(int base, int cont, int exp){
    int aux;

	if(exp == 0){
		aux = 1;
	}
	if(exp == 1){
		aux = base;
	}
	if(exp == 2){
		aux = base * base;
	}
	while(exp > 2 && cont <= exp){
		if(cont == 2){
			aux = base * base;
			cont++;
			multiplica(aux, cont, exp);
		}
		else{
			aux = aux * base;
			cont++;
			multiplica(aux, cont, exp);
		}
	}
    printf("%d", aux);
}

 

Ele está apresentando a seguinte saída, anexada na postagem.

 

Alguém poderia me dar um auxílio?

 

Screenshot from 2021-09-28 15-46-13.png

  • Amei 1
Link para o comentário
Compartilhar em outros sites

Faz pouco sentido uma função recursiva que retorna void... No geral evite isso. Em geral é um erro. No mínimo um desperdício.

 

Mas no caso de recursão o retorno é o caminho normal de encerrar a recursão. Usando void só complica tudo, porque muitas vezes a recursão é justamente o retorno da função...

 

Exemplo

 

    f(x)
    {
        if ( algo )
            return 300;
        else
            return f(y); // recursao
    }

 

Como vê, com void só fica mais difícil...

 

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

2 main no mesmo corpo?

recursividade nada mais é do que uma função em que dentro dela tem uma chamada pra ela mesma.
a recursividade a gente usa a todo momento. Quando a gente faz por exemplo uma divisão, enquanto o resto não for zero, a gente continua fazendo a divisão... Ou, se preferir, usa um mecanismo de poda para parar a divisão, como por exemplo nas dizimas periódicas. O mecanismo de poda pode ser um valor que você passa por parametro mas é reduzido em 1 a cada vez que a função é chamada. Ai, quando esse valor é zero, a condicional, dentro dessa função que é recursiva  vai testar se é zero. Se for, ela para de chamar a função.

Eu usei recursividade na impressão dos nós que existem nesse codigo:
https://tivideotutoriais.blogspot.com/2021/09/linguagem-c-trabalhando-com-nos-lista.html

 

outros exemplos, mas em javaScript:

http://tivideotutoriais.blogspot.com/2020/09/recursividade-e-vida.html

http://tivideotutoriais.blogspot.com/2020/09/recursividade.html

Olhe que a função galho, responsavel por fazer novas linhas, tem outra chamada para galho. Note também que foi usado um mecanismo de poda, para impediro o crescimento infinito de novos galhos.
você poderá ver isso em arvores, listas encadeadas, nós... é bem usado na computação, mas é um mecanismo que deve ser evitado se não for usado com sabedoria e responsabilidade. Normalmente só usamos isso quando existirão dois caminhos... um que poda em algum momento e você está certo de que isso acontecera... e quando quer que continue crescendo.

Esse seu fonte pode ser feito de varias formas. Usando laço for, ou recursividade. vou lhe mostrar alguns exemplos.
 


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

// isso não é recursividade...
// porque? porque dentro da funão não existe
// chamada pra ela mesma
int fatorial1(int n)
{
	int resp=1;
	while(n>1)
	{
		resp*=n;
		n--;
	}
	return resp;
}

// essa é recursividade...
// porque? porque? porque? adivinha...
int fatorial2(int n)
{
	int resp=n;	
	if(n>1) // mecanismo de poda
	{
		resp*=fatorial2(n-1); // olha aqui!
	}
	else
	{
		return 1;
	}
	return resp;
}

// as vezes você vai querer usar alguma
// struct (objeto) na recursividade e ai, 
// só com ponteiro pra atualizar seus valores
void fatorial3(int *n)
{
	int temp=*n-1;
	if(*n>1) // mecanismo de poda
	{
		fatorial3(&temp); // olha aqui!
		*n*=temp;
	}
}

int main()
{
	int resp1 = fatorial1(5);
	printf("resp1: %i\n", resp1);

	int resp2 = fatorial2(5);
	printf("resp2: %i\n", resp2);

	int resp3 = 5;
	fatorial3(&resp3);
	printf("resp3: %i\n", resp3);

	// o mesmo pode ser feito com sua potenciação
}

 

  • Obrigado 2
Link para o comentário
Compartilhar em outros sites

Obrigado a todos. Entendi a ideia, mais ou menos. Vou continuar praticando.

Meu código ficou dessa forma, utilizando as ideias gerais que me passaram, principalmente do retorno que a função deve ter.

 

#include <stdio.h>


int multiplica(int valor, int base, int cont, int exp);

int main(){

    int base, expoente, resultado;

    printf("Digite a base: ");
    scanf("%d", &base);
    printf("Digite o expoente: ");
    scanf("%d", &expoente);


    resultado = multiplica(base, base, 2, expoente);

    printf("%d", resultado);


    return 0;
}

int multiplica(int valor, int base, int cont, int exp){
	if(exp == 0){
		return 1;
	}
	if(exp == 1){
		return base;
	}
	if(exp == 2){
		return base * base;
	}
	while(cont <= exp){
		if(cont == 2){
            valor = base * base;
            cont++;
            multiplica(valor, base, cont, exp);
        }
        else{
            valor = valor * base;
            cont++;
            multiplica(valor, base, cont, exp);
        }
	}

    return valor;
}

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

1 hora atrás, kampa896 disse:
while(cont <= exp){
		if(cont == 2){
            valor = base * base;
            cont++;
            multiplica(valor, base, cont, exp);
        }
        else{
            valor = valor * base;
            cont++;
            multiplica(valor, base, cont, exp);
        }

Parece que não entendeu...
só pode chamar essa função de recursiva por ter chamada dela mesma. Mas não tem utilidade da sua recursividade. Chama mas não usa os resultados dela. Só chegou no resultado por causa do while fazer suas contas... tenta só comentar essas chamadas multiplica dentro desse while só pra você entender que não está tendo utilidade nenhuma essas duas recursividades. O codigo pode ficar mais simples quando entender de verdade.
 

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

int potence(int base, int potencia)
{
	int result; 
	if(potencia>1)
	{
		result = base*potence(base, potencia-1);
	}
	else 
	{
		result = base;
	}

	// faça tabelas pra mostrar o que está acontecendo a cada passo...
	printf("base=%i, potencia atual=%i, resutadoAtual=%i\n", base, potencia, result);
	// exercicio: entenda porque na tabela a primeira potencia que aparece tem valor 1

	return result;
}

int main()
{
	int base = 3;
	int potencia = 4;
	int resutado = potence( base,  potencia);
	printf("resutado de %i^%i = %i\n", base, potencia, resutado);
	return 0;
}

// sem usar tabela ficaria assim:
int potence2(int base, int potencia)
{
	if(potencia>1)
	{
		return base*potence2(base, potencia-1);
	}
	else 
	{
		return base;
	}
}

 

  • Curtir 1
  • Amei 1
Link para o comentário
Compartilhar em outros sites

@codigo rápido agora sim eu entendi. Quando eu comentei a chamada da função, funcionou da mesma forma. Então era o 'while' que estava calculando. Pelo que eu percebi, as funções recursivas colocam as variáveis tipo em pilha, é isso? Pra chegar no resultado final. Estou tendo essa dificuldade de entender o processo da recursividade.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

1 hora atrás, kampa896 disse:

@codigo rápido agora sim eu entendi. Quando eu comentei a chamada da função, funcionou da mesma forma. Então era o 'while' que estava calculando. Pelo que eu percebi, as funções recursivas colocam as variáveis tipo em pilha, é isso? Pra chegar no resultado final. Estou tendo essa dificuldade de entender o processo da recursividade.

pilha é outra coisa... pesquise o que é uma pilha em linguagens formais e automatos. Maquina de turing. Mas é como se fosse isso, se observar a ordem de execução dos processos.

um processo (função) só termina quando todos os processos dentro dela terminarem. Isso quer dizer o return da primeira função só será dado depois que concluir todas as funções antes desse return. Então, na verdade, é que a ultima função chamada é que é a primeira a terminar.
 

  • Curtir 1
  • Amei 1
Link para o comentário
Compartilhar em outros sites

@codigo rápido agora sim, meu amigo.

Ficou claro porque a função recurso funciona sem outras variáveis.

A função vai utilizando as informações que ela mesma produz. Se o último processo chamado é o primeiro a terminar, faz sentido ela utilizar os return dos demais.

Vou pesquisar pilhas também.

 

Obrigado mais uma vez!

  • Obrigado 2
Link para o comentário
Compartilhar em outros sites

22 horas atrás, arfneto disse:

Faz pouco sentido uma função recursiva que retorna void... No geral evite isso. Em geral é um erro. No mínimo um desperdício.

 

Mas no caso de recursão o retorno é o caminho normal de encerrar a recursão. Usando void só complica tudo, porque muitas vezes a recursão é justamente o retorno da função...

 

Parece que não entendeu o que eu expliquei :( Mas não perguntou nada.

 

Do seu programa...

 

	while(cont <= exp){
		if(cont == 2){
            valor = base * base;
            cont++;
            multiplica(valor, base, cont, exp);
        }
        else{
            valor = valor * base;
            cont++;
            multiplica(valor, base, cont, exp);

 

Pergunto:

  • Que diferença faz declarar multiplica() retornando um int se despreza o valor de retorno? Viu o exemplo que te mostrei, em C? [quase off-topic] Em C++ até tem um atributo, [[nodiscard]] que evita que o programador possa fazer isso com o resultado de uma função ;) 
  • porque uma função que calcula base elevada a um expoente, a popular potência, se chama multiplica? não devia reservar isso para uma função que, digamos, multiplica?
    resultado = multiplica(base, base, 2, expoente);

 

  • não acha estranho ter 4 parâmetros, dois iguais, e mais o valor de retorno, se precisa apenas de f(x,y) = x^y ?
     
5 horas atrás, codigo rápido disse:
// sem usar tabela ficaria assim:
int potence2(int base, int potencia)
{
	if(potencia>1)
	{
		return base*potence2(base, potencia-1);
	}
	else 
	{
		return base;
	}
}

 

Está errado. Considere:
 

  • x^0 = 1 para qualquer x... e x^1 = x para qualquer x. Do modo como escreveu vai retornar o mesmo resultado para potências 0 e 1. 4^0 = 1, 4^1 = 4 por exemplo.
  • essas chaves são redundantes e não parecem ajudar na legibilidade
  • um pouco off-topic, mas C tem a função pow(), de power, lembrando que potência na matemática em inglês é power, ou potency no coloquial. Em francês puissance, em espanhol potencia, para citar idiomas mais próximos, se pretendia usar uma grafia dessas linguagens.


Exemplo da função

 

Provavelmente o exemplo clássico para pow() seria
 

int potencia(int valor, int exp)
{
    if (exp == 0) return 1;
    if (exp == 1) return valor;
    return valor * potencia(valor, exp-1);
}

 

Sobre o exemplo acima

 

4 horas atrás, kampa896 disse:

Quando eu comentei a chamada da função, funcionou da mesma forma. Então era o 'while' que estava calculando. Pelo que eu percebi, as funções recursivas colocam as variáveis tipo em pilha, é isso?

 

A recursão é um simples loop. Só que quase sem contexto.

 

3 horas atrás, codigo rápido disse:

pilha é outra coisa... pesquise o que é uma pilha em linguagens formais e automatos

 

Não, não é assim "outra coisa".

 

Recursão e pilha tem tudo a ver e a recursão acontece mesmo na pilha. Um erro simples num programa recursivo e vem de imediato um... stack overflow, no popular "estouro da pilha" .

 

Uma maneira de entender e aplicar recursão é abstrair do algoritmo exatamente onde se volta a fazer a mesma coisa, e ver se dá pra passar todo o contexto adiante usando apenas os argumentos. Um recurso comum é usar variáveis estáticas para salvar algo entre uma chamada e outra.

 

Mas o uso do stack e da memória é grande. E não é assim rápido. Todos os argumentos vão para a pilha entre cada chamada, mais o óbvio endereço de retorno

 

Recursão e potência:

 

Considere 2 ao cubo: 2 x 2 x 2

A abstração: 2 ao cubo é a mesma coisa que 2 * (2 ao quadrado), então 2^3 = 2x(2^2). Mas 2 ao quadrado é a mesma coisa que 2 vezes 2, que é 2 * (2^0). Então se o expoente não for 1 o valor é base * (base ^(expoente - 1) )  e se tem a recursão procurada. 

E o caso trivial de expoente zero, que retorna 1 para qualquer base.

 

 

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

Citação

Que diferença faz declarar multiplica() retornando um int se despreza o valor de retorno? Viu o exemplo que te mostrei, em C? [quase off-topic] Em C++ até tem um atributo, [[nodiscard]] que evita que o programador possa fazer isso com o resultado de uma função  

O senhor equivocado. Devia rever o que entende por programação. Não é assim com esse pensamento que se desenvolve programas.
Uma forma comum de se fazer alteração, ou "receber um valor", pode ser passando um parametro na forma de ponteiro.
Quem decide se vai usar ou não o valor de retorno não é a linguagem. É o desenvolvedor. Até porque muitas funções retornam valor apenas para testes (aguns ainda programam assim e funciona) e podem ser ignoradas quando não for necessidade testa-las.

 

Citação

x^0 = 1 para qualquer x... e x^1 = x para qualquer x. Do modo como escreveu vai retornar o mesmo resultado para potências 0 e 1. 4^0 = 1, 4^1 = 4 por exemplo.

verdade. Obrigado. Eu não tinha visto isso. O senhor tem razão.
 

Citação

um pouco off-topic, mas C tem a função pow(), de power, lembrando que potência na matemática em inglês é power, ou potency no coloquial. Em francês puissance, em espanhol potencia, para citar idiomas mais próximos, se pretendia usar uma grafia dessas linguagens.


não é o que está sendo discutido. Não vem ao caso. O assunto é recursividade. ele poderia chegar aos mesmos resultados apenas usando axiomas de peano. mas também não é o caso.
 

Citação

Recursão e pilha tem tudo a ver e a recursão acontece mesmo na pilha. Um erro simples num programa recursivo e vem de imediato um... stack overflow, no popular "estouro da pilha" .


Está equivocado quanto a isso também. ter a ver é uma coisa... a gora, ser, é outra. Por isso eu fui especifico quando eu disse que fazemos isso numa divisão. Mesmo no papel. Agora pilha é outra coisa. Pode olhar isso na diciplina de linguagens formais e sistemas automatos.

 

Citação

E o caso trivial de expoente zero, que retorna 1 para qualquer base.


É sim. Já falou disso, mas novamente agradeço, pois tem razão.

Link para o comentário
Compartilhar em outros sites

12 horas atrás, codigo rápido disse:

Quem decide se vai usar ou não o valor de retorno não é a linguagem. É o desenvolvedor


Ignorando valores de retorno de funções: será de propósito?

 

Eu estou certo. E te mostrei o exemplo de C++. 

E vou explicar de novo apenas porque:

  • Pode ser interessante para algum leitor que não tenha tantos anos de experiência como você, mas tenha interesse em entender as razões por trás de algo
     
  • Muitas vezes a função retorna algo e o tal desenvolvedor despreza o valor POR ERRO. Engano. Simples assim. E muitas o desenvolvedor original, O CARA QUE ESCREVEU A FUNÇÃO, sabe que o resultado dela não deveria ser desprezado.

 

Imagine:

  • uma função sem efeitos externos, como uma que :D calcula potência a partir de base e expoente. Vai achar familiar já que é exatamente o que está escrito aqui.
  • Os argumentos vem por valor
  • a função retorna um int com o valor de base elevada ao expoente. O cara que escreveu a função, como essa que você escreveu, sabe que ela retorna um resultado. E que não muda nada no sistema exceto isso, porque ela não chama outras funções, não altera variáveis globais ou algo assim. Apenas faz uma conta e retorna o resultado.

Então:

  • Se o resultado for ignorado então se trata de uma provável bobagem, uma perda de tempo, talvez porque o cara que chamou a função esqueceu de atribuir o resultado, ou não está seguro do que está escrevendo, como na função que @kampa896 escreveu acima

E assim o comitê ISO --- do qual eu não faço parte --- votou a favor de introduzir uma maneira de O COMPILADOR avisar isso. Mudar a linguagem, tal a importância possível de algo assim.

 

A julgar pelo nível e experiência das pessoas que votam nesse comitê e pelas companhias que estão nele representadas, os caras entendem de desenvolvimento e ferramentas. Lá estão IBM, Microsoft, Google, Apple, e gente como o professor Stroustrup, que escreveu entre outras coisas a linguagem C++, bem como  alguns dos autores mais renomados de C e C++ no planeta.

 

E porque? Porque deve ser um erro do programador não usar o resultado e é melhor avisar do que ter uma postura negacionista e dizer que o problema é do cara que chamou. Assim, em C++, se pode escrever

 


[[nodiscard]] int potencia(int, int);

int main(int argc, char** argv)
{
    int base     = 0;
    int expoente = 1;

//...

 

E aí se o tal desenvolvedor escrever

 


    potencia(2, 3);
    return 0;

 

Vai receber esse aviso:

 

warning C4834: discarding return value of function with 'nodiscard' attribute

 

Não tenho agora um compilador com mensagens em português, mas como vê é só um warning para o desenvolvedor se ligar se era isso mesmo que ele queria escrever: o valor de retorno foi descartado e a declaração diz que não devia ser...

 

C++20 e nodiscard

 

Mais ainda, na versão mais recente de C++ ao declarar a função você pode explicar o porque das coisas e usar algo como
 


[[nodiscard("Se não vai usar o valor porque chamou então?")]]
int potencia(int,int);

 

E ler isso na tela 

 

ch210929.cpp(33,13): warning C4858: discarding return value: Se não vai usar o valor porque chamou então?

 

Se não usar o valor de retorno. E entender que na linha 33 do programa chamou uma função para calcular algo e talvez tenha esquecido de usar o resultado.

 

De todo modo é só um warning e muitos desenvolvedores nem leêm os avisos do compilador afinal. 

 

12 horas atrás, codigo rápido disse:

Está equivocado quanto a isso também. ter a ver é uma coisa... a gora, ser, é outra. Por isso eu fui especifico quando eu disse que fazemos isso numa divisão. Mesmo no papel. Agora pilha é outra coisa. Pode olhar isso na diciplina de linguagens formais e sistemas automatos

 

Tenho alguma noção de onde procurar informação sobre isso. E expliquei aquilo porque você contradisse a afirmação de @kampa896 sobre aquilo ficar na pilha e acho que mesmo nessas disciplinas de que falou deve ter ouvido falar que stack overflow --- estouro da PILHA --- e funções recursivas sempre aparecem juntas em programas de iniciantes. Essa era a referência importante: o stack, a pilha do sistema. E foi você que leu menção a pilha como estrutura de dados. @kampa896 estava no caminho certo.

 

Talvez possa postar a versão corrigida da função que postou antes, para ficar mais completo o tópico. E note que a versão mais comum é a que eu mostrei mesmo:

 

Em C++ talvez

 

[[nodiscard("Se não vai usar o valor calculou porque?")]]
int potencia(int valor, int exp)
{
    if (exp == 0) return 1;
    if (exp == 1) return valor;
    return valor * potencia(valor, exp - 1);
}

 

Ou C

 

int potencia(int valor, int exp)
{
    if (exp == 0) return 1;
    if (exp == 1) return valor;
    return valor * potencia(valor, exp - 1);
}
Link para o comentário
Compartilhar em outros sites

@arfneto, @codigo rápido obrigado, pessoal.

 

Estou no primeiro ano de faculdade e tenho várias dúvidas. Como a faculdade é EAD, o fórum aqui muitas vezes me ajuda mais rápido e com explicações mais claras que a tutoria. Fora a atenção que recebo dos senhores.

 

Desculpa se as vezes a pergunta é simples demais, mas estou me esforçando.

 

Mais um vez, agradeço. Vou terminar de entender essa parte de recursão e entrar em manipulação de arquivos, utilização de arquivos CSV em C e qualquer dúvida posto aqui no fórum.

 

Obrigado!

Link para o comentário
Compartilhar em outros sites

ja... já li, já trabalhei, já escrevi sobre tudo isso. Só que pilha e recursividade, não são a mesma coisa. O estouro de pilha acontece simplesmente por tentar colocar valores além do acordado na pilha. Entendeu?
 

Citação

Eu estou certo. E te mostrei o exemplo de C++. 

Não é assim que se programa. Até porque se a linguagem não tivesse limites, não teria nem necessidade pra descer ao nivel do assembly. E isso, como estou tentando lhe ensinar, é escolha do desenvolvedor. O compilador permite e dá ideias.... Assim como é o uso de goto. Eu não uso. Mas tem que goste de usa-lo.

Link para o comentário
Compartilhar em outros sites

10 horas atrás, codigo rápido disse:

Não é assim que se programa. Até porque se a linguagem não tivesse limites, não teria nem necessidade pra descer ao nivel do assembly. E isso, como estou tentando lhe ensinar, é escolha do desenvolvedor

 

O que eu te mostrei, ou tentei, e em detalhes da segunda vez, está no padrão da linguagem. E foi estendido em 2020 como eu também mostrei há pouco. Não estou tentando ensinar nada, apenas repassando algo que está das linguagens mais importantes dessa época.

 

E também te expliquei a razão da preocupação de avisar de um possível erro ao descartar um valor de retorno.

 

10 horas atrás, codigo rápido disse:

Não é assim que se programa. Até porque se a linguagem não tivesse limites, não teria nem necessidade pra descer ao nivel do assembly. E isso, como estou tentando lhe ensinar, é escolha do desenvolvedor. O compilador permite e dá ideias

 

Compiladores não são fonte de ideias, imagino. Vou tentar pensar nisso.

 

11 horas atrás, kampa896 disse:

Vou terminar de entender essa parte de recursão e entrar em manipulação de arquivos, utilização de arquivos CSV em C

 

@kampa896 Entendeu o que eu expliquei sobre a abstração e a recursão? Rodou a função que eu mostrei? Entendeu a diferença e o lance do valor de retorno naquelas 3 linhas? Entendeu porque a função funciona e que o loop dela está na recursão?
 

Acho que em '19 eu postei vários programas completos aqui sobre leitura e criação de arquivos csv em em C++ e C. Pode pesquisar no meu conteúdo do forum. Pode ajudar.

  • Amei 1
Link para o comentário
Compartilhar em outros sites

10 horas atrás, arfneto disse:

E também te expliquei a razão da preocupação de avisar de um possível erro ao descartar um valor de retorno.


tem como mostrar a fonte? eu não concordo com tudo o que vejo, mas apresento minha forma de fazer sem nem citar quem não concordo. E sempre apresento fontes.

Link para o comentário
Compartilhar em outros sites

11 horas atrás, arfneto disse:

Muitas vezes a função retorna algo e o tal desenvolvedor despreza o valor POR ERRO. Engano. Simples assim. E muitas o desenvolvedor original, O CARA QUE ESCREVEU A FUNÇÃO, sabe que o resultado dela não deveria ser desprezado.

Quando a gente sabe o que faz e o compilador dá permissão, quem manda é o desenvolvedor. Como eu lhe disse, se a linguagem fosse perfeita, não necessitava de abertura para descer ao nivel do assembly.

 

Observe como eu fiz ai acima, quando você falou de que função recursiva só tem sentido quando retorna valor. Eu fiz usando ponteiro só pra mostrar que isso não é necessário nem obrigatorio. Nem te citei pra mostrar isso.

Link para o comentário
Compartilhar em outros sites

10 horas atrás, codigo rápido disse:

tem como mostrar a fonte? eu não concordo com tudo o que vejo, mas apresento minha forma de fazer sem nem citar quem não concordo. E sempre apresento fontes.

 

O que eu te mostrei é um programa, em C++. Está no padrão da linguagem. Te mostrei a saída do compilador e um código. Isso é uma fonte. Um programa fonte. E um compilador oficial.

 

O parâmetro adicional foi incluído em 2020. votado como tudo que entrou de novo na linguagem nessa versão. O mesmo caso de 2017 quando esse conceito foi introduzido, ainda sem o parâmetro. A proposta original vinha de '15 eu acho. Isso não é uma fonte válida para você? A razão eu tentei te explicar, mas deve imaginar que alguém mais concorda comigo, já que falamos da linguagem em si, e não de qualquer linguagem qualquer derivada do ambiente Clang.

 

Já leu o standard? Tem acesso? Está na linguagem e a razão de estar foi discutida no comitê por gente com provavelmente mais experiência do que você ou eu. Incluído aí o prof. Stroustrup, que criou a linguagem.

 

Só continuo explicando isso porque acho que é um conceito importante e pode ajudar muita gente a usar versões mais seguras e critérios mais seguros de desenvolvimento.

 

image.thumb.png.60aa04914730520e7c15dd5a0c3bac99.png

 

https://en.cppreference.com/w/cpp/language/attributes/nodiscard

 

Eis uma fonte com erro

 

19 horas atrás, codigo rápido disse:
// sem usar tabela ficaria assim:
int potence2(int base, int potencia)
{
	if(potencia>1)
	{
		return base*potence2(base, potencia-1);
	}
	else 
	{
		return base;
	}
}

 

Eis outra fonte, no mesmo tópico

 

11 horas atrás, arfneto disse:
int potencia(int valor, int exp)
{
    if (exp == 0) return 1;
    if (exp == 1) return valor;
    return valor * potencia(valor, exp - 1);
}

 

Ou em C++20, no mesmo tópico

 

11 horas atrás, arfneto disse:
[[nodiscard("Se não vai usar o valor calculou porque?")]]
int potencia(int valor, int exp)
{
    if (exp == 0) return 1;
    if (exp == 1) return valor;
    return valor * potencia(valor, exp - 1);
}
Link para o comentário
Compartilhar em outros sites

Citação

O parâmetro adicional foi incluído em 2020. votado como tudo que entrou de novo na linguagem nessa versão. O mesmo caso de 2017 quando esse conceito foi introduzido, ainda sem o parâmetro.

Pode ser... meu ubunto é de 2016. Mas isso não importa.

 

Citação

Muito bom... porque não fez isso antes?

Ou simplesmente... você deve estar usando uma versão antiga do compilador que a iso ja descartou...

Programar não é isso ai que você tá achando que é. vai muito além de conhecer profunda mente a linguagem. Quem programa, programa até em eletronica, até com caixas daguas dá pra programar...

Link para o comentário
Compartilhar em outros sites

9 horas atrás, codigo rápido disse:

Ou simplesmente... você deve estar usando uma versão antiga do compilador que a iso ja descartou...

 

O comitê não descarta versões de nada.  Ao contrário, os compiladores são atualizados para incorporar as mudanças no padrão, mas ninguém descarta nada. Desenvolver software custa muito dinheiro e em geral ninguém pensa em atualizar bases de código porque agora tem ou deixou de ter isso ou aquilo em java ou C ou C++.

 

Por isso muita gente ainda trabalha em C++98, alguns em C++11, por exemplo. Java 8 foi dominante até um dia desses, Python 2.7 era ok até outro dia. C17 é desconhecido em muitos projetos e empresas.

 

A linguagem evolui. As ferramentas evoluem. O código tem suas regras. Outras.

 

9 horas atrás, codigo rápido disse:

Programar não é isso ai que você tá achando que é. vai muito além de conhecer profunda mente a linguagem. Quem programa, programa até em eletronica, até com caixas daguas dá pra programar

 

Entendo.

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...