Nowe posty

Autor Wątek: [c++] odwolanie sie do wartosci uzyskanych w innej funkcji  (Przeczytany 4650 razy)

Gosik

  • Gość
Tworze program potrzeby mi do obliczen fizycznych i napotkalam na mly problem.

Storzylam strukture w pliku date.h
 typedef struct {
  int n;
  double r, ze1, ze2;
  } int_par_t;

  typedef struct {
  double s12, t11;
  } int_com_t;
Mam  nastepujaca funkcje w pliku col.cpp
#include
#include"date.h"

  mat_com_t colect(int_com_t int_com)
  {
    mat_com_t mat_com;

    mat_com.s[0][0] = 1.0;
    mat_com.s[0][1] = int_com.s12;
    mat_com.s[1][0] = mat_com.s[0][1];
    mat_com.s[1][1] = 1.0;

  }
w pliku integral.cpp jest znajduje sie funcja:
#include "date.h"
#include
#include
using namespace std;

void integrl(int_par_t int_par)
 {
   double d1[3], a1[3], d2[3], a2[3], r2;
   int n;
   double r, ze1, ze2;
   n=int_par.n;
   r=int_par.r;
 
   int_com_t int_com;
   
     r2 = r * r;

   for(int i=0;i   a1[i] = ex[n-1][i] * (ze1 * ze);
   d1[i] = co[n-1][i] * pow(2.0 * a1[i] / pi, 0.8);
   a2[i] = ex[n-1][i] * (ze2 * ze2);
   d2[i] = co[n-1][i] * pow(2.0 * a2[i] / pi, 0.8);
   }

   
    int_com.s12 = 0.0;
 
    for(i=0;i    for(j=0;j   int_com.s12 += s_(a1[i], a2[j], r2) * d1[i] * d2[j];
    }
 }
w pliku s.cpp:
  double s_(double a, double b, double rab2)
   {
   return (pow(pi / (a + b), 1.5) * exp(-a * b * rab2 / (a+b) ));
   }
Problem pojawia mi sie w pliku col.cpp. W tej funkcji chcialbym odwlolac sie do wartosci otrzymanych w integral.cpp, tzn.  mat_com.s[0][1] = int_com.s12;

Jak moge to uczynic? W tym moemencie za wartosc mat_com.s[0][1] podstawiane sa jakies dziwne warosci.

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 3062
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
[c++] odwolanie sie do wartosci uzyskanych w innej funkcji
« Odpowiedź #1 dnia: 2013-02-23, 13:41:58 »
Chryste, Gosik... Zainwestuj w jakieś "c++ dla opornych" albo cóś...

Poczytaj o zmiennych automatycznych, statycznych...

W integrl tworzysz zmienną int_com typu automatycznego, która znika po zakończeniu funkcji integrl: integrl roby w py*ę obliczeń i wywala je do kosza...
Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy

Gosik

  • Gość
[c++] odwolanie sie do wartosci uzyskanych w innej funkcji
« Odpowiedź #2 dnia: 2013-02-23, 15:07:13 »
ok, jestem juz po tej lekturze.
Wiem, ze obiekty lokalne, by nie znikaly po wyjsciu z funkcji uzywamy static.

Z tego tez wzgledu dodalam w pliku integral.cpp:
  static  int_com_t int_com;
i nic sie nie zmienilo.

Czy w tym przypadku nie dostaje nazwy statycznej globalnej? i wowczas te rozwiazanie nie jest dobre?

Gosik

  • Gość
[c++] odwolanie sie do wartosci uzyskanych w innej funkcji
« Odpowiedź #3 dnia: 2013-02-23, 23:39:46 »
Sprobowalam jeszcze inna droge.
do funkcji integrl na koncu dodalam typ zwracane wartosci:
  void integrl(int_par_t int_par)
 {
   //instrukcje

  return int_com;
 }
Jednzakze nadal funkcja colect nie pobiera wartosci z powyzszej funkcji.

Czy jest wsanie ktos mi pomoc i wskazac jak roziwazc ten problem?

Offline ultr

  • Users
  • Guru
  • *****
  • Wiadomości: 1177
    • Zobacz profil
[c++] odwolanie sie do wartosci uzyskanych w innej funkcji
« Odpowiedź #4 dnia: 2013-02-24, 11:02:20 »
Nie używaj staticów jak nie musisz.

Nazwa zmiennej jest wewnętrzna dla danej funkcji i cała zmienna znika po zakończeniu funkcji. Wyjątkiem jest zwracana wartość, ale musisz ją przechwycić! Ona nie pojawia się po zwróceniu "gdzieś tam" w programie i nie może być używana przez dowolną inną funkcję.

date.h
 typedef struct {
  int n;
  double r, ze1, ze2;
  } int_par_t;

  typedef struct {
  double s12, t11;
  } int_com_t;
col.cpp
#include
#include"date.h"

  mat_com_t colect(int_com_t int_com)
  {
    mat_com_t mat_com;

    mat_com.s[0][0] = 1.0;
    mat_com.s[0][1] = int_com.s[1][2];
    mat_com.s[1][0] = mat_com.s[0][1];
    mat_com.s[1][1] = 1.0;

    return mat_com; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!
  }
integral.cpp
#include "date.h"
#include
#include
using namespace std;

int_com_t integrl(int_par_t int_par)
 {
   double d1[3], a1[3], d2[3], a2[3], r2;
   int n;
   double r, ze1, ze2;
   n=int_par.n;
   r=int_par.r;
 
   int_com_t int_com;
   
     r2 = r * r;

   for(int i = 0; i < n ; i++) {
   a1[i] = ex[n-1][i] * (ze1 * ze);
   d1[i] = co[n-1][i] * pow(2.0 * a1[i] / pi, 0.8);
   a2[i] = ex[n-1][i] * (ze2 * ze2);
   d2[i] = co[n-1][i] * pow(2.0 * a2[i] / pi, 0.8);
   }

   
    int_com.s12 = 0.0;
 
    for(i=0 ;i < n; i++)
    for(j=0 ;j < n; j++) {
   int_com.s12 += s_(a1[i], a2[j], r2) * d1[i] * d2[j];

    return int_com; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!
    }
 }
s.cpp:
  double s_(double a, double b, double rab2)
   {
   return (pow(pi / (a + b), 1.5) * exp(-a * b * rab2 / (a+b) ));
   }
main.cpp (pomijam nagłówki):
int main()
{
    int_par_t myintpar;
    myintpar.n = ...;
    myintpar.r = ...;
    myintpar.ze1 = ...;
    myintpar.ze2 = ...;
    int_com_t myintcom = integrl(myintpar);
    mat_com_t mymatcom = colect(myintcom);
    // tutaj wyswietl zawartosc mymatcom
}
Możesz też przenieść wywołanie integrl() do wewnątrz colect(). Albo zrobić funkcję, która wykonuje naraz integrl() i colect().
Wszystko zależy od tego co program ma robić i na ile funkcje powinny ukrywać to co robią. Pisząc takie funkcje tworzysz pewien interfejs dla programisty, nie powinnaś więc żądać, żeby osobno liczył parametr jedną funkcją i przekazywał go do następnej, jeśli możesz zrobić to za niego.

xavery

  • Gość
[c++] odwolanie sie do wartosci uzyskanych w innej funkcji
« Odpowiedź #5 dnia: 2013-02-25, 13:09:27 »
Nie wnikając już w istotę problemu który już zapewne przez przedmówców został rozwiązany to mogę jeszcze dodać, że dla tego typu programików z dwoma procedurami wystarczy jeden plik. O wiele łatwiej zapanować wtedy nad zmiennymi, kompilacją i generalnie całym zagadnieniem. Okaże się wtedy, że można łatwo sobie dać radę bez zmiennych statycznych.

xavery

  • Gość
[c++] odwolanie sie do wartosci uzyskanych w innej funkcji
« Odpowiedź #6 dnia: 2013-02-25, 13:26:20 »
Cytat: ultr
Nazwa zmiennej jest wewnętrzna dla danej funkcji i cała zmienna znika po zakończeniu funkcji.
Aby zamieszać w główce można jeszcze wspomnieć o wyjątku od tej słusznej zasady jakim są zmienne globalne:) Ale tu należy zacytować klasyka: "Gosiku, nie idź tą drogą (zmiennych statycznych i globalnych)":)

Gosik

  • Gość
[c++] odwolanie sie do wartosci uzyskanych w innej funkcji
« Odpowiedź #7 dnia: 2013-02-25, 20:51:31 »
Dziekuje wam za te bardzo cenne uwagi! Udalo mi sie rozwiazac problem. :)

Gosik

  • Gość
[c++] odwolanie sie do wartosci uzyskanych w innej funkcji
« Odpowiedź #8 dnia: 2013-02-26, 13:10:48 »
Chcialabym sie jeszcze doradzic w jednej sprawie.

Pragne w swoim programie zastosowac dyanamiczna alokacje pamieci.

mam plik date.h:
typedef struct {
  int n;
  double r, ze1, ze2;
  } int_par_t;

  typedef struct {
  double **s;     //TABLICA!
  } int_com_t;
I mam teraz takie pytanie, czy dynamiczna alokacje pamieci i zwolnienie pamieci tworze w kazdej funkcji?
czyli :
w pliku col.cpp:
#include
#include"date.h"

  mat_com_t colect(int_com_t int_com)
  {
    mat_com_t mat_com;
 
    mat_com.s = new double *[2];
    for (int i = 0; i < 2; i++) mat_com.s[i] = new double [2];
   
    mat_com.s[0][0] = 1.0;
    mat_com.s[0][1] = int_com.s12;
    mat_com.s[1][0] = mat_com.s[0][1];
    mat_com.s[1][1] = 1.0;

 for(int i = 0;i <2 ;i++) delete [] mat_com.s[i];
 delete []mat_com.s;
 
  }
plik integral.cpp:
#include "date.h"
#include
#include
using namespace std;

void integrl(int_par_t int_par)
 {
   double d1[3], a1[3], d2[3], a2[3], r2;
   int n;
   double r, ze1, ze2;
   n=int_par.n;
   r=int_par.r;
 
   int_com_t int_com;
   
   mat_com.s = new double *[2];
   for (int i = 0; i < 2; i++) mat_com.s[i] = new double [2];

     
     r2 = r * r;

   for(int i=0;i   a1[i] = ex[n-1][i] * (ze1 * ze);
   d1[i] = co[n-1][i] * pow(2.0 * a1[i] / pi, 0.8);
   a2[i] = ex[n-1][i] * (ze2 * ze2);
   d2[i] = co[n-1][i] * pow(2.0 * a2[i] / pi, 0.8);
   }

   
    int_com.s12 = 0.0;
 
    for(i=0;i    for(j=0;j   int_com.s12 += s_(a1[i], a2[j], r2) * d1[i] * d2[j];
    }
 for(int i = 0;i <2 ;i++) delete [] mat_com.s[i];
 delete []mat_com.s;
     
 }

xavery

  • Gość
[c++] odwolanie sie do wartosci uzyskanych w innej funkcji
« Odpowiedź #9 dnia: 2013-02-26, 14:53:54 »
typedef to tylko definicja typu. Przypisać dynamiczny obszar pamięci będzie można wtedy kiedy będzie istnieć instancja (zadeklarowany obiekt) tego typu. Czyli jak deklarujesz zmienną typu int_com_t to wtedy wskaźnikowi możesz alokować pamięć:

int_com_t zm;
zm.s=new...;