markusmetal Posted April 5, 2012 at 11:44 PM Report #447877 Posted April 5, 2012 at 11:44 PM Boa noite. Comecei recentemente a estudar C++ e comecei pelas classes. Tenho tido algumas dificuldades pois algumas coisas não são muito claras para mim como algumas funções em que não sei interpretar o será feito ou é suposto fazer. Segui um dos links que estão disponiveis no forum para iniciar em C++. http://agnor.gamedev-pt.net/gamedev/cpp/cpp015.html Estou com um erro no sqrt. Vou deixar o código para mostrar a minha dúvida: Ponto.h #pragma once class Ponto { private: int x, y; public: Ponto(); void alterarX(int u_x); void alterarY(int u_y); void alterar(int u_x, int u_y); Ponto (const Ponto &p); int mostrarX(); int mostrarY(); float modulo(); int soma(); }; Ponto.cpp #include "Ponto.h" #include <math.h> #include <stdio.h> #include <stdlib.h> Ponto::Ponto() { x=0; y=0; } void Ponto::alterarX(int u_x) { x=u_x; } void Ponto::alterarY(int u_y) { y=u_y; } void Ponto::alterar(int u_x, int u_y) { x=u_x; y=u_y; } int Ponto::mostrarX() { return x; } int Ponto::mostrarY() { return y; } float Ponto::modulo() { return sqrt(x*x+y*y); //Erro em sqrt } int Ponto::soma() { return x+y; } prog.cpp #include "Ponto.h" #include <stdio.h> #include <stdlib.h> int main() { Ponto point; point.alterar(3, 5); printf("X= %d Y= %d\n\n",point.mostrarX(),point.mostrarY()); point.alterarX(10); printf("X= %d Y= %d\n\n",point.mostrarX(),point.mostrarY()); printf("Soma de X com Y: %d + %d = %d\n\n",point.mostrarX(),point.mostrarY(),point.soma()); printf("Modulo: %d\n\n",point.modulo()); system("pause"); } Não sei porque dá erro no sqrt para cálcular o módulo. O erro que aparece é "ambiguous call to overloaded function". Num programa anterior creio que fiz o mesmo e não deu qualquer tipo de erro. Também gostaria que me explicassem realmente para que serve isto: Ponto (const Ponto &p); complex operator *( const complex& c ); Vi estas duas funções num exercicio que fazia várias operações entre dois numeros complexos. Pelo que percebi da segunda função, sei que o calculo vai ser do tipo *, uma multiplicação, mas não compreendo a designação ( const complexo& c ). Agradecia a vossa ajuda.
pikax Posted April 6, 2012 at 12:30 AM Report #447879 Posted April 6, 2012 at 12:30 AM muda para //como garantia, converte para float float Ponto::modulo() { return sqrt(float(x*x+y*y)); //Erro em sqrt } printf("Modulo: %f\n\n",point.modulo()); Ponto (const Ponto &p); complex operator *( const complex& c ); Vi estas duas funções num exercicio que fazia várias operações entre dois numeros complexos. Pelo que percebi da segunda função, sei que o calculo vai ser do tipo *, uma multiplicação, mas não compreendo a designação ( const complexo& c ). Agradecia a vossa ajuda. O primeiro e' um construtor da class/struct Ponto, o "const Ponto &p" significa que e' uma referencia constante do tipo ponto. o segundo e' um "overload" do simbolo aritmético '*', significa que quando fizeres assim: complex a,b; complex c; c=a*b; sem essa funcao este codigo em cima daria erro, basicamente serve para facilitar a vida(ou nao) em ves de chamares uma funcao que te faca isso. Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender. A beleza de um código está em decompor problemas complexos em pequenos blocos simples. "learn how to do it manually first, then use the wizzy tool to save time." "Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."
markusmetal Posted April 6, 2012 at 03:20 PM Author Report #447921 Posted April 6, 2012 at 03:20 PM Obrigado pela ajuda. Resolveu o problema com o sqrt 😉 Vou agora tentar fazer uns exercicios que usem aquelas duas funções para ficar a perceber bem como funcionam.
markusmetal Posted April 6, 2012 at 06:13 PM Author Report #447966 Posted April 6, 2012 at 06:13 PM Estou a tentar fazer um programa em que o utilizador insira 2 numeros complexos e sejam realizadas as operações normais entre eles. Só que bloqueei logo no inicio. Dá-me um erro estranho e estupidamente não sei como guardar valores inseridos pelo utilizador porque em todos os exercicios que vi até agora os dados já estavam atribuidos previamente 😉 complexo.h #pragma once class complexo { private: float re, im; public: complexo(); complexo( float r, float i = 0 ); complexo( const complexo& c ); float modulo(); } complexo.cpp #include "complexo.h" #include <math.h> #include <stdio.h> complexo::complexo() { re=0; im=0; } complexo::complexo( float r, float i=0) //ERRO---> complexo::complexo : redifinition of default parameter: parameter 2 { re=r; im=i; } complexo::complexo( const complexo& c ) //Suponho que seja assim este construtor. Ainda não sei para que serve esta função { re=c.re; im=c.im; } float complexo::modulo() { return sqrt((float)re*re+im*im); } prog.cpp #include <stdio.h> #include <stdlib.h> #include "complexo.h" int main() { complexo z1; printf("\t\tPROGRAMA QUE REALIZA OPERAÇOES ENTRE 2 NUMEROS COMPLEXOS\n\n\n"); printf("Introduza um numero complexo: Z1= "); scanf("%f",&z1); printf("Modulo: %f\n\n",z1.modulo()); system("pause"); } scanf("%f",&z1); Suponho que isto que estou a fazer seja uma estupidez. Tanto que obviamente só guarda o primeiro valor que vou inserir. Mas para guardar um complexo tenho que inserir por exemplo 3+5j. Já tive a pensar em como vou guardar o valor do sinal dado a 5 e se realmente se guarda o j que indica que é um numero imaginário. Pensei neste caso colocar o j no fim de todas as operações.
bsccara Posted April 6, 2012 at 06:47 PM Report #447970 Posted April 6, 2012 at 06:47 PM Tens aí três constructores: o primeiro inicializa-o a zero, o segundo inicializa-o a partir dos parâmetros passados (o erro é por causa do '=0' a seguir à declaração do parâmetro, tira-o) e o terceiro é um 'copy constructor', que cria uma cópia do objecto passado (http://en.wikipedia.org/wiki/Copy_constructor). Quanto a receber os valores uma hipótese é: int main() { float re = 0; float im = 0; printf("\t\tPROGRAMA QUE REALIZA OPERAÇOES ENTRE 2 NUMEROS COMPLEXOS\n\n\n"); printf("Introduza um numero complexo: Z1= "); scanf("%f + %fj",&re,&im); complexo z1(re,im); printf("Modulo: %f\n\n",z1.modulo()); system("pause"); }
HappyHippyHippo Posted April 6, 2012 at 09:37 PM Report #447977 Posted April 6, 2012 at 09:37 PM nota : há quem use a notação "i" em vez de "j" para dizer que é a parte imaginária do número complexo IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
markusmetal Posted April 7, 2012 at 05:51 AM Author Report #448000 Posted April 7, 2012 at 05:51 AM Funcionou essa sugestão 😉 O "j" colocado na função scanf("%f + %fj",&re,&im); faz alguma diferença? É que se eu colocar um complexo do tipo 5j-4, o 5 será considerado parte real incorrectamente. Para o calculo do módulo não fará qualquer diferença. Mas agora que começo a criar as funções para calcular multiplicações e conjugado entre 2 numeros acho que vou ter problemas. Não terei neste caso que usar o complexo( const complexo& c );? Usar como operando da direita para os numeros imaginários? Tendo em conta a classe dada, acho que será para isso que esta função serve creio. A minha classe está assim de acordo com o exercicio: #pragma once class complexo { private: float re, im; public: complexo(); complexo( float r, float i = 0 ); complexo( const complexo& c ); float modulo(); float soma();//teste float argumento(); complexo conjugado(); complexo simetrico(); complexo operator +( const complexo& c ); complexo operator -( const complexo& c ); complexo operator *( const complexo& c ); complexo operator /( const complexo& c ); complexo potencia( float exp ); complexo operator *( float f ); complexo operator /( float f ); float parteReal(); float parteImaginaria(); void imprimir(); }; Supostamente o numero complexo será sempre na forma algébrica porque não existem somas na forma trigonometrica e não vejo nada que indique para se converter de uma para outra e vice versa.
HappyHippyHippo Posted April 7, 2012 at 09:01 AM Report #448004 Posted April 7, 2012 at 09:01 AM Usar como operando da direita para os numeros imaginários class complexo { ... float parteReal() const; float parteImaginaria() const; } complexo operator +(float f, const complexo& c) { return complexo(c.parteReal() + f, c.parteImaginaria()); } ... int main() { complexo c(3.0, 3.0); float f = 3.0; complexo result = f + c; // 6.0 + 3.0i result 0; } IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
HappyHippyHippo Posted April 7, 2012 at 09:19 AM Report #448007 Posted April 7, 2012 at 09:19 AM ideia para leitura do complexo de uma string bool complexo::read(char * string) { float re = this->re, im = this->im; if (sscanf(string, "%f+%f", &this->re, &this->im) == 2) return true; if (sscanf(string, "%f%*c+%f", &this->im, &this->re) == 2) return true; this->re = re; this->im = im; return false; } IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Baderous Posted April 7, 2012 at 02:51 PM Report #448039 Posted April 7, 2012 at 02:51 PM markusmetal vê como postar código aqui.
markusmetal Posted April 8, 2012 at 05:04 AM Author Report #448091 Posted April 8, 2012 at 05:04 AM Agradeço imenso a sugestão HappyHippyHippo. Como estava com dificuldades em meter o utilizador a inserir os valores, vou deixar para o fim visto que o mais importante são as operações. Avancei com todas as operações básicas mas como eu temia, bloqueei na divisão. Sei que de alguma maneira vou ter que usar o conjugado mas não estou a encontrar a maneira certa de calcular isto. Já pensei em várias possibilidades mas estou a ter alguma dificuldade. Será que isto vai fazer o que penso: complexo operator *( float f ); complexo operator /( float f ); Estas funções recebem um numero real certo? Então isto irá servir para fazer operações quando por exemplo z1=3 e z2=-i ? Acho estranho aparecer novamente a mesma coisa ou então não estou a perceber o que é para fazer neste caso especifico. O meu código está assim actualmente complexo.h #pragma once class complexo { private: float re, im; public: complexo(); complexo( float r, float i = 0 ); complexo( const complexo& c ); float modulo();//feito float argumento();//feito complexo conjugado();//feito complexo simetrico();//feito complexo operator +( const complexo& c );//feito complexo operator -( const complexo& c );//feito complexo operator *( const complexo& c );//feito complexo operator /( const complexo& c ); complexo potencia( float exp ); complexo operator *( float f ); complexo operator /( float f ); float parteReal(); float parteImaginaria(); void imprimir(); }; complexo.cpp #include "complexo.h" #include <math.h> #include <stdio.h> #define PI 3.141592654 complexo::complexo() { re=0; im=0; } complexo::complexo( float r, float i) { re=r; im=i; } complexo::complexo( const complexo& c ) { re=c.re; im=c.im; } float complexo::modulo() { return sqrt((float)re*re+im*im); } float complexo::argumento() { float res; res=((atan2(im, re)*180)/PI); if(res<0) { res=res+360; return res; } else res=((atan2(im, re)*180)/PI); return res; } complexo complexo::conjugado() { complexo res(re, -im); return res; } complexo complexo::simetrico() { complexo res(-re, -im); return res; } complexo complexo::operator +( const complexo& c ) { complexo res(re+c.re, im+c.im); return res; } complexo complexo::operator -( const complexo& c ) { complexo res(re-c.re, im-c.im); return res; } complexo complexo::operator *( const complexo& c ) { complexo res(re*c.re - im*c.im, re*c.im + im*c.re); return res; } complexo complexo::operator /( const complexo& c ) { } void complexo::imprimir() { if(im>=0) { printf("[%.1f+%.1fi]\n",re,im); } else printf("[%.1f%.1fi]\n",re,im); } prog.cpp #include <stdio.h> #include <stdlib.h> #include "complexo.h" #include <math.h> int main() { complexo z1(7, -3); complexo z2(3, 2); complexo z3; z3=z1.operator/(z2); z3.imprimir(); printf("Argumento= %.2f graus\n\n",z1.argumento()); system("pause"); }
HappyHippyHippo Posted April 8, 2012 at 09:11 AM Report #448094 Posted April 8, 2012 at 09:11 AM Estas funções recebem um numero real certo? Então isto irá servir para fazer operações quando por exemplo z1=3 e z2=-i ? Acho estranho aparecer novamente a mesma coisa ou então não estou a perceber o que é para fazer neste caso especifico. as funções declaram o que a classe faz quando se depara com esta situação : complexo c; c * 3.0; isto é, a multiplicação com um número em |R ... não faz sentido significar : c * 3.0i IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
markusmetal Posted April 8, 2012 at 03:56 PM Author Report #448113 Posted April 8, 2012 at 03:56 PM complexo complexo::operator /( const complexo& c ) { complexo resNumerador(re*c.re - im*(-(c.im)), re*(-(c.im)) + im*c.re); complexo resDenominador(c.re*c.re - c.im*(-(c.im)), c.re*(-(c.im)) + c.im*c.re); return res; //divisão entre resNumerador e res Denominador } É possivel dentro desta função dividir o resultado de resNumerador e resDenominador? Foi a unica maneira que consegui para calcular o conjugado. O que fiz foi fazer as multiplicaçoes todas e só depois fazer a divisão. Não sei se será possivel.
HappyHippyHippo Posted April 8, 2012 at 04:31 PM Report #448118 Posted April 8, 2012 at 04:31 PM http://en.wikipedia.org/wiki/Complex_number conjugado : a+bi => a-bi complexo complexo::conjugado() { return complexo(this->re, -this->im); } divisão : (a+bi)/(c+di) = (ac + bd)/(c*c + d*d) + ((bc + ad)/(c*c + d*d))i complexo complexo::operator/(const complexo& c) { float denom = c->parteReal()*c->parteReal() + c->parteImaginaria()*c->parteImaginaria(); return complexo((this->re * c->parteReal() + this->im * c->parteImaginaria()) / denom, (this->im * c->parteReal() + this->re * c->parteImaginaria()) / denom); } IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
ap27 Posted April 10, 2012 at 01:31 PM Report #448376 Posted April 10, 2012 at 01:31 PM Boas.. Alguém sabe implementar o complexo potencia( float exp );? Obrigado
HappyHippyHippo Posted April 10, 2012 at 02:20 PM Report #448385 Posted April 10, 2012 at 02:20 PM http://en.wikipedia.org/wiki/Complex_number a solução de complexo^n dá duas soluções (visto pela raiz quadrada do número complexo, porque raiz quadrada é a mesma coisa que potência de 0.5) IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
ap27 Posted April 10, 2012 at 02:26 PM Report #448387 Posted April 10, 2012 at 02:26 PM Então o que será que é pedido nesta situação..?
ap27 Posted April 10, 2012 at 03:39 PM Report #448399 Posted April 10, 2012 at 03:39 PM Pensei em implementar desta forma mas não estou a conseguir.. Alguém me dá uma sugestão? complexo complexo::potencia( float exp) { for(int i=0; i<=exp; i++) { complexo = operator *( const complexo& c ); } return complexo; }
markusmetal Posted May 6, 2012 at 05:54 PM Author Report #453427 Posted May 6, 2012 at 05:54 PM Boa tarde. O programa anterior que fazia operações entre numeros complexos está concluido 🙂 O que estou a fazer agora é um programa que realiza algumas operações entre duas matrizes que serão do tipo complexo. Estou a usar a classe complexo do programa que acabei anteriormente. Estive a confirmar e tudo na classe complexo está correcto. Na classe matriz, estou a tentar implementar os métodos da atribuiçao, soma e multiplicação mas algo não está bem. O da atribuição (em que o conteudo da matriz da direita é passado para a a matriz da esquerda) não o sei implementar. Isto porque tenho dificuldades em compreender a criação de arrays dinamicos de duas dimensoes, bem como apagar os dados desses arrays. É que a matriz da esquerda, caso tenha dados, estes terão que ser apagados antes de receber então os dados da outra matriz. A soma e a multiplicação creio que tenho tudo correcto. Só que ao correr o programa, dá-me um erro de execução e encerra o programa logo depois de eu inserir os dados do tipo complexo na segunda matriz. Não sei onde poderei estar a cometer algum erro 😄 matriz.h #pragma once #include "complexo.h" class matriz { private: complexo ** elem; int col, lin; public: matriz(); matriz(int l, int c); void lerMatriz(); void escreverMatriz(); float podeSomar(const matriz & m); float podeMultiplicar(const matriz & m); /*matriz operator =( const matriz & m );*/ matriz operator +( const matriz & m ); matriz operator *( const matriz & m ); ~matriz(); }; matriz.cpp #include "matriz.h" #include "complexo.h" #include <stdio.h> #include <stdlib.h> matriz::matriz() { lin=0; col=0; } matriz::matriz(int l, int c) //função que recebe a ordem da matriz { lin=l; col=c; elem = new complexo *[lin]; for(int i=0; i<lin; i++) { elem[i]=new complexo[col]; } } matriz::~matriz() { for(int i=0; i<lin; i++) { delete[] elem[i]; } delete[] elem; } void matriz::lerMatriz() //funçao que para cada posiçao da matriz irá pedir ao utilizador para inserir um numero complexo { for(int i=0; i<lin; i++) for(int k=0; k<col; k++) { printf("Posicao da matriz [%dX%d]:",i+1,k+1); elem[i][k].lerComplexo(); } } void matriz::escreverMatriz() { for(int i=0; i<lin; i++) { for(int k=0; k<col; k++) { elem[i][k].imprimir(); } printf("\n");//com este printf, escreve na forma de matriz no ecrã } } float matriz::podeSomar(const matriz & m)//função devolve verdadeiro ou falso se a ordem da 1ªmatriz é ou não igual ao da 2ªmatriz { if( (lin==m.lin) && (col==m.col) ) return true; else return false; } float matriz::podeMultiplicar(const matriz & m)//funão devolve verdadeiro ou falso se o nº de colunas da 1ªmatriz é ou não igual { //ao numero de linhas da 2ªmatriz if(col==m.lin) return true; else return false; } /* matriz matriz::operator =(const matriz & m) { for(int i=0; i<lin; i++)//colocar a matriz da esquerda a zeros { delete[] elem[i]; } delete[] elem; }*/ matriz matriz::operator +(const matriz & m) { matriz res(lin,col); if(! podeSomar(m)) return res; int i, j; for(i=0; i<lin; i++) { for(j=0; j<col; j++) { res.elem[i][j]=elem[i][j]+m.elem[i][j]; } } return res; } matriz matriz::operator *(const matriz & m) { matriz res(lin,col); if(! podeMultiplicar(m)) return res; int i, j; for(i=0; i<lin; i++) { for(j=0; j<col; j++) { res.elem[i][j]=elem[i][j]*m.elem[i][j]; } } return res; } main.cpp #include <stdio.h> #include <stdlib.h> #include "complexo.h" #include "matriz.h" #include <math.h> int main() { matriz Z1(2,2), Z2(2,2), Z3; Z1.lerMatriz(); Z1.escreverMatriz(); Z2.lerMatriz(); Z2.escreverMatriz(); Z3=Z1.operator +(Z2); Z3.escreverMatriz(); system("pause"); }
markusmetal Posted May 6, 2012 at 05:59 PM Author Report #453429 Posted May 6, 2012 at 05:59 PM Boas.. Alguém sabe implementar o complexo potencia( float exp );? Obrigado complexo complexo::potencia(float exp) { float z, ang, rad; z=pow(modulo(), exp); ang=argumento()*exp; rad=(ang*PI)/180; re=z*cos(rad); im=z*sin(rad); complexo res(re,im); return res; } PI foi definido como 3.14. Espero que compreendas 😄
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now