Ir ao conteúdo
  • Cadastre-se

C o que esta errado com esse programa?(ponteiros)


Amanda Kellen

Posts recomendados

Tenho que fazer um programa dessa maneira usando ponteiro e um sem ponteiro,o sem ponteiro eu consegui fazer mas com ponteiro não está dando certo porque ainda tenho certa difiuldade com ponteiros.O q tenho q fazer para q o programa funcione?

#include <stdio.h>
#include <stdlib.h>
int leitura(char);
void xelevadoy(int,int,int*);
void imprime(int,int,int);

int main()
{
    int x,y,potencia=1;
    x=leitura('x');
    y=leitura('y');
    xelevadoy(x,y,&potencia);
    void imprime(x,y,potencia);
    system("pause");
    return 0;
}
int leitura(char x)
{
    int y;
    printf("\n Digite o valor de %c:",x);
    scanf("%d",&y);
    system("clear||cls");
    return y;
}

void xelevadoy(int x,int y,int *potencia)
{
    int i;
    potencia=1;
    for(i=0;i<=y;i++)
    {
        potencia=potencia*x;
    }

}

void imprime(int x,int y,int potencia)
{
    printf("\n %d^%d=%d \n",x,y,potencia);
}

 

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

@Amanda Kellen Olá!

Seu Editor não deveria ter compilador esse programa.

Erros na linha:12, 26 e 28 deCompilação, mais um erro lógico na linha 35.

 

Quando queremos gravar ou ler o conteúdo de um ponteiro qualquer colocamos o astéricos antes do nome do dito cujo.

Assim *RefQualquer= 13

Com relação aos demais erros, vou deixar por sua conta principalmente o 35 e o 12.

 

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

@Amanda Kellen    o que o @Mauro Britivaldo   disse está certo,    e  você colocou um void na chamada da função imprime, e com isso não está indo na função e por isso não imprime o resultado .
e na função xelevadoy a variável potencia é um ponteiro e precisa colocar o asterisco antes da palavra potencia, e no caso essa atribuição de hum à variável potencia não é necessária pois ela já foi atribuída lá na main, então essa palavra potencia=1; pode ser deletada , e na função xelevadoy modifique essa linha  :

potencia=potencia*x;

e coloque assim :

*potencia=*potencia*x;
      ou 
*potencia *= x;

 

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

  • Membro VIP

Olá @Amanda Kellen. Vou tentar dar uma luz sobre o que ocorre...

 

 

Em 03/02/2018 às 16:13, Amanda Kellen disse:

[...] mas com ponteiro não está dando certo [...]

Certo, onde não está dando certo? o que está dando erro? Tente identificar o que está ocorrendo.

 

 

 

Em 03/02/2018 às 16:13, Amanda Kellen disse:

[...] porque ainda tenho certa difiuldade com ponteiros

Veja, ter dificuldade é normal (e esperado), se os programadores não tivessem dificuldades o fórum não teria motivo existir, :)... ou seja, essa "porque" não quer dizer nada. :D

 

 

Onde quero chegar: foque nos sintomas do problema. Isso de um modo geral...

 

Então, vamos lá. Apenas compile o código e tente entender o que ocorre:

 

Apenas compilei seu código original, deu (erro de cima pra baixo):

13 18 [<caminho do arquivo>] [Error] variable or field 'imprime' declared void

Está dizendo algo sobre um erro na declaração de alguma coisa chamada imprime na linha 14, coluna 18. Talvez o erro não esteja tão claro, mas indo lá na linha/coluna, verás o que @devair1010 comentou.

17 horas atrás, devair1010 disse:

você colocou um void na chamada da função imprime

ou seja, por engano você colocou o termo void  antes do imprime. (ou será que no seu outro programa sem ponteiros tinha colocado e está funcionando? entende?). Referente ao "porque do erro", talvez a mensagem seja que o compilador achou que você tentou declarar uma variável nova ou método, sendo que você queria apenas usar um método já existe.

 

Mas poderia ocorrer algo do tipo.. "Ah! mas eu de fato não sabia que não era para colocar um void ali... entretanto você iria buscar soluções a partir disso! O compilador diz onde e qual erro encontrou, e geralmente é objetivo... ;)

 

 

Compilando novamente deu:

29 13 [Error] invalid conversion from 'int' to 'int*' [-fpermissive]

Está dizendo que a conversão de "int" para "int*" é inválida. O que significa? não sabia direito, mas tendo um pouco de contato com a linguagem, e pelo contexto, é que aquele "*" se refere a ponteiros, ou seja, que o compilador diz que é invalido converter de "não ponteiro" para "ponteiro" daquela forma. O quê que o erro quer dizer exatamente? não sei, mas dá para deduzir que é algo relacionado a alguma sintaxe para uso de ponteiro...

 

Então, o foco não está em converter ou não, mas sim na sintaxe para acessar o ponteiro, que é usando o "*" antes. Como citado por @devair1010

 

17 horas atrás, devair1010 disse:

a variável potencia é um ponteiro e precisa colocar o asterisco antes da palavra potencia

 

 

 

obs.:

17 horas atrás, devair1010 disse:

*potencia *= x;

Esse "*" do "*=" não tem nada a ver com "*" do ponteiro, é apenas uma "simplificação de sintaxe"  (uma forma mais elegante de dizer que a variável da esquerda será igual ao próprio valor dela pela a variável que está na direita), como sugere o código do @devair1010.

 

 

RESUMINDO:

- não tem void antes do imprime;

- use * para acessar as variáveis de ponteiros.

 

obs. 2: essas verificações se referem aos erros sintaxe... teste o código e veja se está ocorrendo tudo certinho, caso não, tente identificar onde está com problemas e tente corrigir... ai posta aqui o resultado ou onde está com dúvidas.

 

 

No aguardo

 

 

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

Muito obrigado a todos,o void antes do imprime foi porque eu copiei o nome e colei na main e esqueci de tirar o void,agora está funcionando corretamente,troquei também na função xelevadoy o void por int,que eu tinha colocado errado mesmo por descuido e também mudei o valor recebido por i,antes estava 0,troquei por 1 e ficou assim:

#include <stdio.h>
#include <stdlib.h>
int leitura(char);
int xelevadoy(int,int,int*);
void imprime(int,int,int);
int main()
{
    int x,y,potencia=1;
    x=leitura('x');
    y=leitura('y');
    xelevadoy(x,y,&potencia);
    imprime(x,y,potencia);
    system("pause");
    return 0;
}
int leitura(char x)
{
    int y;
    printf("\n Digite o valor de %c:",x);
    scanf("%d",&y);
    system("clear||cls");
    return y;
}

int xelevadoy(int x,int y,int *potencia)
{
    int i;
    for(i=1;i<=y;i++)
    {
        *potencia=*potencia*x;
    }

}

void imprime(int x,int y,int potencia)
{
    printf("\n %d^%d=%d \n",x,y,potencia);
}

 

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

  • Membro VIP

Olá @Amanda Kellen.

 

19 minutos atrás, Amanda Kellen disse:

troquei também na função xelevadoy o void por int,que eu tinha colocado errado mesmo por descuido

Errado por quê? você mudou para int. OK! mas não está retornando nada, ou seja, agora que ficou errado. :wiggle:

 

Sendo assim... ou você retorna a resposta pela variável ponteiro lá do parâmetro (ficando void mesmo), ou retorna pelo return (ai sim ficaria int).

 

 

Adendo: coloquei 2^-3 e deu 1. Tem algo errado ai. Então, qual o enunciado do problema? é para usar apenas números naturais?

 

 

No aguardo.

 

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

segue abaixo o enunciado:

enunciado.thumb.jpg.f3903ca36fd6fae4a1e08941a2853987.jpg

adicionado 10 minutos depois
57 minutos atrás, Simon Viegas disse:

adendo: coloquei 2^-3 e deu 1. tem algo errado ai. então, qual o enunciado do problema? é para usar apenas números naturais?

referente a essa parte eu cometi um erro me desculpe,eu também tenho um programa q calcula apenas com expoentes negativos e ele estava aberto no momento e por falta de atenção calculei 2^-3 nele e acabei me equivocando.esse programa em questão calcula apenas com expoentes positivos.

 

segue o código abaixo,adicionei um while para q não aceite expoentes negativos:

#include <stdio.h>
#include <stdlib.h>
int leitura(char);
int xelevadoy(int,int,int*);
void imprime(int,int,int);
int main()
{
    int x,y,potencia=1;
    x=leitura('x');
    y=leitura('y');
    while(y<0)
    {
        printf("\nERRO!!ESTE PROGRAMA CALCULA SOMENTE POTENCIAS DE EXPOENTE POSITIVOS!!\n");
        y=leitura('y');
    }
    xelevadoy(x,y,&potencia);
    imprime(x,y,potencia);
    system("pause");
    return 0;
}
int leitura(char x)
{
    int y;
    printf("\n Digite o valor de %c:",x);
    scanf("%d",&y);
    system("clear||cls");
    return y;
}

int xelevadoy(int x,int y,int *potencia)
{
    int i;
    for(i=1;i<=y;i++)
    {
        *potencia=*potencia*x;
    }
    return *potencia;
}

void imprime(int x,int y,int potencia)
{
    printf("\n %d^%d=%d \n",x,y,potencia);
}

 

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

  • Membro VIP

Então:

 

Acho que você ainda não entendeu para que serve o void ou o int ali no início da assinatura do método. "Isso" define o que vai ser retornado no próprio método, ou seja, o que vai ser retornado pelo return ou se não vai ter return algum. Veja como está funcionando o leitura(), e veja como está funcionando XelevadoY(). No primeiro, você faz algo e retorna na própria função um int. Ex.:

    x=leitura('x');
    y=leitura('y');

Ou seja, o método funciona como uma variável... um valor está sendo retornado nela mesma. Entende? esse valor é um int, pois na assinatura tem int leitura(). Tá certo ai!

 

Já no XelevadoY() você não retorna nada nela mesma (não está sendo solicitado isso no enunciado), veja:

xelevadoy(x,y,&potencia);

Não temos ai um "ALGO=XelevadoY(x,y,&potencia);". Se não precisa retornar algo nela mesmo, então o método é void!. Não tem um return lá dentro. Assim como imprime() também é void.

 

No contexto do problema, XelevadoY(), ficou definido que seria retornado algo em uma das variáveis que foi passada por parâmetro (e não nele mesmo)... daí o motivo de usar ponteiros! pois é uma forma de "persistir" as alterações que foram feitas dentro do método... Seria como se a variável "potencia" do método recebesse o endereço de memória do "potencia" externo. Por consequência, ao alterar o potencia (variável local lá do método), vai acabar alterando de fato o potencia externo (variável global)... se atente que são duas variáveis distintas, apenas tem o mesmo nome. Não precisaria ser igual! Entretanto, é permitido! Poderia por exemplo ser assim:

void xelevadoy(int x,int y,int *xxx)
{
    int i;
    for(i=1;i<=y;i++)
    {
        *xxx=*xxx*x;
    }
}

As variáveis estão em universos (escopos) diferentes.

 

 

Em outras palavras: O método main tem ficar exatamente como o enunciado exige. Por sinal está bem claro:

Citação

A função: int main() deverá conter as seguintes instruções:

 

 

 

RESUMINDO:

1) O método main deve ficar idêntico ao enunciado, você apenas vai implementar o restante para que o método funcione corretamente;

2) O nome do método é XelevadoY(), e não xelevadoy(); (vide item 1)

3) O tipo int está relacionado aos inteiros, e não aos naturais, logo, tecnicamente deveria aceitar números negativos... e o enunciado não diz nada sobre essa limitação;

4) Em vez de for(i=1;i<=y;i++) prefira for(i=0;i<y;i++). (apenas sugestão... no mundo do C, a contagem começam do 0. É bom seguir o padrão).

 

 

No aguardo.

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

@Simon Viegas   a questão do void int eu até entendo,só mudei pra ficar parecido  ao exercicio anterior que é assim:

ffff.thumb.jpg.9a5f695e1d93ac94a535fdb34053f2e4.jpg

mas tinha me esquecido dessa questão do ponteiro.

 

19 horas atrás, Simon Viegas disse:

2) O nome do método é XelevadoY(), e não xelevadoy(); (vide item 1)

em relação a isso eu não estava levando tanto em consideração isso porque esse exercicio estou refazendo partes q fiquei com duvidas,mais como um treino mesmo,logo nem levei isso em consideração.

 

 

19 horas atrás, Simon Viegas disse:

3) O tipo int está relacionado aos inteiros, e não aos naturais, logo, tecnicamente deveria aceitar números negativos... e o enunciado não diz nada sobre essa limitação;

realmente no exercicio não tem essa limitação mas o exercicio após esse pede somente expoentes negativos então preferi fazer esse apenas para expoentes positivos.

 

muito obrigado!

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Olá @Amanda Kellen.

 

23 horas atrás, Amanda Kellen disse:

@Simon Viegas   a questão do void int eu até entendo,só mudei pra ficar parecido  ao exercicio anterior que é assim:

&key=932d69d8514fc575ffff.thumb.jpg.9a5f695e1d93ac94a535fdb34053f2e4.jpg

mas tinha me esquecido dessa questão do ponteiro.

Justamente. Perceba que o enunciado é diferente. Num, a proposta é retornar o valor no próprio método (em algumas linguagens essa característica é chamada de funcion ou funcao). Já no atual, o retorno foi proposto para ser em um dos parâmetros (em algumas linguagens essa característica de não retornar nada no próprio método é chamado de procedure ou procedimento). No C, acho que tudo é chamado de método mesmo, e quando não retorna nada poderia ser chamado de "método void" ("método sem retorno").

 

Na minha visão, é um erro usar int por 2 motivos principais:

a- O enunciado é explícito. Devem-se sempre segui-lo (estou batendo nessa tecla). Tipo, seria como você ir na padaria e pedir um bolo de chocolate, ai o padeiro vai e te entrega uma torta de chocolate. Não pode (não deveria). No máximo precisaria "entrar num acordo" com o requerente, entende?

b- A funcionalidade do retorno int não está servindo para nada. Você até implementou o return lá dentro do método (assim como existe um return no método main, mas lá existe um motivo para isso), mas fora não está usando, pois a proposta é justamente "introduzir/estimular" o uso de retorno via parâmetro (em detrimento do teoricamente mais convencional retorno na própria função), ou seja, a proposta seria justamente tirar esse retorno pelo return.

 

 

 

23 horas atrás, Amanda Kellen disse:

em relação a isso eu não estava levando tanto em consideração isso porque esse exercicio estou refazendo partes q fiquei com duvidas,mais como um treino mesmo,logo nem levei isso em consideração.

Entendi. Apenas quis reforçar que deve seguir o que se pede.

 

Imagine assim. A ideia é que o método main seja executado exatamente como está o enunciado, se deixar com xelevadoy() vai dar erro, pois o C é Case-Sensitive.

 

 

 

23 horas atrás, Amanda Kellen disse:

realmente no exercicio não tem essa limitação mas o exercicio após esse pede somente expoentes negativos então preferi fazer esse apenas para expoentes positivos.

Entendi. Faz sentido.

 

Entretanto a limitação não está na existência de outro exercício, mas sim por outro detalhe que passou despercebido:

Sobre:

Em 05/02/2018 às 17:33, Simon Viegas disse:

3) O tipo int está relacionado aos inteiros, e não aos naturais, logo, tecnicamente deveria aceitar números negativos... e o enunciado não diz nada sobre essa limitação;

Nesse sentido eu falei besteira, pois apensar da base e expoentes poderem ser inteiros (int e int) , o resultado para expoentes são reais!, ou seja, o retorno para poder aceitar expoentes negativos não poderia ser int*. Acho que seria float* (ou algo do tipo). Resumindo: de fato essa assinatura contida no enunciado:

int XelevadoY(int,int,int*);

não permite expoentes negativos.

Acho que poderia ser algo como:

int XelevadoY(int,int,float*);

 

Ai, como ainda ratifico a questão do uso do "main" (e toda aquela parte inicial em cima também) exatamente como o enunciado propõe, essa "proteção":

Em 05/02/2018 às 16:38, Amanda Kellen disse:

    {
        printf("\nERRO!!ESTE PROGRAMA CALCULA SOMENTE POTENCIAS DE EXPOENTE POSITIVOS!!\n");
        y=leitura('y');
    }

não poderia ficar lá. Talvez poderia colocar dentro do método XelevadoY() ou simplesmente ignorar isso e supor que só serão informados expoentes positivos.

 

 

 

No aguardo.

 

Link para o comentário
Compartilhar em outros sites

Em 05/02/2018 às 17:38, Amanda Kellen disse:

{

        printf("\nERRO!!ESTE PROGRAMA CALCULA SOMENTE POTENCIAS DE EXPOENTE POSITIVOS!!\n"); y=leitura('y');

}

Eu acho que em caso de teste esse trecho de código não será executado. Porque o enunciado do problema diz y-ésima, chamo destaque para letra a no final da palavra y-ésima que vem de enésima que de forma leiga quer dizer; Último elemento de ordem, ou seja, não existe número ordinal negativo.  y := 1,2,3,4... e nunca < 1.

 

PS.: Na física disso em tenho certeza! Um salva para UFPE Universidade do Meu :tw_heart:.

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

  • Membro VIP
2 horas atrás, Mauro Britivaldo disse:

y-ésima que vem de enésima que de forma leiga quer dizer; Último elemento de ordem, ou seja, não existe número ordinal negativo.  y := 1,2,3,4... e nunca < 1.

 

PS.: Na física disso em tenho certeza! Um salva para UFPE Universidade do Meu :tw_heart:.

Interessante essa questão, e faz sentido pra mim. Seria mais um ponto que corrobora que deve ser aceito só números positivos.

 

 

ADENDOS:

1)

Sobre:

2 horas atrás, Mauro Britivaldo disse:

Porque o enunciado do problema diz y-ésima, chamo destaque para letra a no final da palavra y-ésima

Entendi que essa letra "a" é uma pura e simples questão de concordância de gênero com termo "potência" (feminino). Se fosse masculino, seria y-ésimo. Ex.: "y-ésimo número de Fibonacci". ou "y-ésimo grau" etc. Seria o adjetivo/numeral concordando com o sujeito. (é sujeito mesmo? tô chutando, rs)

 

 

 

2)

Sobre:

2 horas atrás, Mauro Britivaldo disse:

Eu acho que em caso de teste esse trecho de código não será executado

Acho que depende do contexto... no sentido de escopo (a faixa que é subentendida e limitada), não iria mesmo, pois de fato só iriam ser usados números naturais (isso desconsiderando o 0). Aí seria um trecho de código "inútil" e oneroso (tem custos - no mínimo de implementação e do processamento da máquina. Talvez irrisório, mas tem). Mas no sentido de "tratamento de erro", iria, pois, possivelmente, o objetivo da @Amanda Kellen foi dar um tratamento à possibilidade do usuário inserir um número negativo, ou seja, o usuário "errando" a faixa estipulada (só naturais*).

 

 

***

 

Obs.: independente dos 2 pontos supracitados, como já frisado, eu acho que não deveria existir essa verificação, pois não conta no enunciado. O main e aquela parte de cima tem quer ficar idênticos... nem uma vírgula a mais. (minha opinião)

Link para o comentário
Compartilhar em outros sites

16 horas atrás, Simon Viegas disse:

possivelmente, o objetivo da @Amanda Kellen foi dar um tratamento à possibilidade do usuário inserir um número negativo

Ficou claro o objetivo de amada. Porém não é necessário pensar nisso porque o enunciado do problema garante que o "usuário" não vai errar (nem com número não positivos e nem para outros caracteres não numéricos).

 

PS.: A boa interpretação do problema é fundamental. Não vai-se além e nem aquém do essencial da questão, foi o que aprendi no URI entre outras coisas.

  • Curtir 2
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...