Jump to content

Ajuda na iniciação em C++


markusmetal
 Share

Recommended Posts

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.

Link to comment
Share on other sites

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."

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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");
}
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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");
}
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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;
}
Link to comment
Share on other sites

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");
}
Link to comment
Share on other sites

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  😄

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.