Programiranje

Programiranje u C++-u - pitanja i odgovori

captain_soap_McTawish čet 5.5.2011 17:34

Otvaram ovu temu po uzoru na Programiranje u C-u - od svega pomalo. Ovdje pitajte što želite i što vas zanima o c++-u.

 

Evo moje pitanje:

Pravim određenu funkciju sa neodređenim argumentima. Funkcija uglavnom radi nešto sa unesenm brojevima. Prvi argument je koliko će se unijeti brojeva, a zatim slijede brojevi(onoliko koliko ih je navedeno u prvom argumentu). Tim argumentima pristupam putem makro naredbi va_list. Kako ću provjeriti ima točno onoliko argumenata koliko je navedeno u prvome argumentu? Tj. želim se osigurati da je unešeno točno onoliko brojeva koliko je navedeno. Primjer aplikacije je:

 

  #include <iostream>
#include <cstdarg>

using namespace std;

int zbroji(int a,...){
    va_list broj;
    int b=0,c=0;
    va_start(broj,b);
    for(int x=0;x<a;x++){
      c+=va_arg(broj,int);
      b++;
    }
    va_end(broj);
    return c;
}

int main()
{
  cout<<zbroji(3,1,2,3)<<endl;
return 0;
}

Ovo je primjer jednostavne funkcije za zbrajanje unešenih brojeva. Dakle kako ću ja saznati da nema više argumenata?

 

captain_soap_McTawish čet 5.5.2011 20:11
TracerCPP kaže...

U ovom slučaju prevoditelj ne može direktno provjeriti ispravnost poziva funkcije pa je najviše na programeru odgovornost oko cijele stvari. Isto kao i kod npr. printf-a.

 

  Ok, Hvala. No mogu li ja ručno nekako znati kad je ponestalo argumenata. Dakle ja u funkciji želim sam provjeriti koliko ima argumenata ili kad je zadnji argument. Nisam siguran jeli to moguće.

Tom69 čet 5.5.2011 20:23
captain_soap_McTawish kaže...

  Ok, Hvala. No mogu li ja ručno nekako znati kad je ponestalo argumenata. Dakle ja u funkciji želim sam provjeriti koliko ima argumenata ili kad je zadnji argument. Nisam siguran jeli to moguće.

Nikako osim ako se nije nešto promijenilo. Možeš npr. pozivati s brojem argumenata kao prvim parametrom. Ili možeš kao zadnji parametar koristiti neku poznatu vrijednost npr. 0, -1, NULL i slično.

Burs čet 12.5.2011 08:51

U C# se za takve stvari koristi keyword params u signaturu funkcije. Jako dobra stvar. Možda nešto slično postoji i u C++?

 

public class Test {
   public static int Zbroji(params int[] brojevi) {
     int suma = 0;
     foreach (int broj in brojevi)
       suma += broj;
     return suma;
   }

   public static void Main(string[] args) {
     Console.WriteLine(Zbroji(2,4,6,8));
     Console.WriteLine(Zbroji(1,3,5,7,9));
   }
}

captain_soap_McTawish pon 16.5.2011 15:40

Imam određeni problem

#include <iostream>
#include <fstream>

using namespace std;

int br_znam(int x){
    int br=1;
    while(x){
      x/=10;
      br++;
    }
    return br;
}

int main(){
    int n;
    cin>>n;
    int al=br_znam(n*n);
    int b;
    int mode=ios::trunc | ios::app;
    fstream ispis("izlaz.txt", mode);
    for(int x=1;x<=n;x++){
      for(int y=1;y<=n;y++){
        int k=x*y;
        for(int m=0;m<al-br_znam(k);m++){
          ispis<<" ";
        }
        ispis<<k<<" ";
      }
      ispis<<endl;
    }
    return 0;
}

  Kod linije koja je podcrtana žuto kompajler mi dojavljuje grešku:


enja.cpp||In function 'int main()':|
enja.cpp|21|error: invalid conversion from 'int' to 'std::_Ios_Openmode'|
enja.cpp|21|error: initializing argument 2 of 'std::basic_fstream<_CharT, _Traits>::basic_fstream(const char*, std::_Ios_Openmode) [with _CharT = char, _Traits = std::char_traits<char>]'|
||=== Build finished: 2 errors, 0 warnings ===|

Ovakav način rada sam vidio u knjizi po kojoj radim i nije mi jasno u čemu je problem. Unaprijed se zahvaljujem na pomoći.

 

Luuka pon 16.5.2011 15:47

probaj staviti

 

std::_Ios_Openmode mode=ios::trunc | ios::app;

 

u liniju iznad žute. Kaže da ne zna pretvoriti int u taj tip koji treba. Ili jednostavno nemoj ni raditi varijablu tog tipa, samo stavi unutar konstruktora za fstream ono što ti treba.

malak pet 20.5.2011 22:18

Evo i od mene jedno pitanje, po meni bi ovo trebalo raditi ali rezultat nije dobar ? Moze pomoc ? U pitanju je sortiranje bubblesortom

 

#include <iostream>

using namespace std;

int main()
{
    int niz[5], temp;
    for (int i=0; i<5;i++)
    cin >> niz[i];
    for (int i=0;i<4;i++)
    {
        for (int j=i+1; j<5;j++)
        {
            if (niz[j+1]>niz[j])
            {
                temp = niz[j];
                niz[j]=niz[j+1];
                niz[j+1]=temp;
            }
        }
    }
    for (int i=0;i<5;i++)
    cout << niz[i] << endl;


    return 0;
}


Floki pet 20.5.2011 22:50

Evo pa proanaliziraj gdje je bila greška - malo sam preuredio algoritam da skužiš kako radi: 

 

 

#include <iostream>

using namespace std;

int main()
{
    int* niz, temp, broj;
    cout<< "Unesi broj elemenata u nizu: ";
    cin>> broj;
    niz = new int[broj];          // alokacija niza proizvoljne veličine broj elemenata
    for (int i=0; i<broj; i++)
    {
       cout<< "Unesi " << i+1 << ". broj: ";      // unos elemenata niza
       cin >> niz[i];
    }
    for (int i=0;i<broj-1;i++)
    {
        for (int j=0; j<broj - 1 - i;j++)    // bubble sort algoritam
        {
            if (niz[j+1] < niz[j])
            {
                temp = niz[j];
                niz[j]=niz[j+1];
                niz[j+1]=temp;
            }
        }
    }
    for (int i=0;i<broj;i++)      // ispis poredanog niza
       cout << niz[i] << " ";
    cout<< endl;
    delete [] niz;   // brisanje alociranog niza


    return 0;
}
trebalo bi još malo srediti upis elemenata - ali sorry - žurim nešto.

 

p.s. evo sad je preglednije

jurluk pet 3.6.2011 16:19

zašto kad projekt koji savršeno radi u codeblocksu prebacim u visual studio izbacuje hrpetinu grešaka?

 

evo npr ovo u codeblocksu radi, a u vs-u ne radi

 

struct Formats{
    string format;
    string soft;
}menu[19] = {
    { format: "MPC", soft: "Soft00Cmt" },
    { format: "SkyMap", soft: "Soft01Cmt" },
    { format: "Guide", soft: "Soft02Cmt" },
    { format: "xephem", soft: "Soft03Cmt" },
    { format: "Home Planet", soft: "Soft04Cmt" },
    { format: "MyStars!", soft: "Soft05Cmt" },
    { format: "TheSky", soft: "Soft06Cmt" },
    { format: "Starry Night", soft: "Soft07Cmt" },
    { format: "Deep Space", soft: "Soft08Cmt" },
    { format: "PC-TCS", soft: "Soft09Cmt" },
    { format: "Earth Centered Universe", soft: "Soft10Cmt" },
    { format: "Dance of the Planets", soft: "Soft11Cmt" },
    { format: "MegaStar V4.x", soft: "Soft12Cmt" },
    { format: "SkyChart III", soft: "Soft13Cmt" },
    { format: "Voyager II", soft: "Soft14Cmt" },
    { format: "SkyTools", soft: "Soft15Cmt" },
    { format: "Autostar", soft: "Soft16Cmt" },
    { format: "Celestia (SSC)", soft: "empty" },
    { format: "Stellarium", soft: "empty" }
};

 

(...).hpp(46): error C2065: 'format' : undeclared identifier
(...).hpp(46): error C2143: syntax error : missing '}' before ':'
(...).hpp(46): error C2143: syntax error : missing '}' before ':'
(...).hpp(46): error C2143: syntax error : missing ';' before ':'
(...).hpp(46): error C2059: syntax error : ':'
(...).hpp(46): error C2059: syntax error : 'string'
(...).hpp(46): error C2059: syntax error : 'string'
(...).hpp(46): error C2143: syntax error : missing ';' before '}'
(...).hpp(46): error C2059: syntax error : '}'
itd itd

 

 

za ovo mi isto izbacuje greške

 

double compute_period (float q, float e){

    double P;

    if (e <  1) P = pow((q/(1-e)),1.5);
    if (e >  1) P = pow((q/(e-1)),1.5);
    if (e == 1) P = pow((q/(1-0.999999)),1.5);

    return P;
}

 

 

(...).cpp(2235): error C2666: 'pow' : 6 overloads have similar conversions
1>          d:\program files\microsoft visual studio 10.0\vc\include\math.h(583): could be 'long double pow(long double,int)'
1>          d:\program files\microsoft visual studio 10.0\vc\include\math.h(581): or       'long double pow(long double,long double)'
1>          d:\program files\microsoft visual studio 10.0\vc\include\math.h(535): or       'float pow(float,int)'
1>          d:\program files\microsoft visual studio 10.0\vc\include\math.h(533): or       'float pow(float,float)'
1>          d:\program files\microsoft visual studio 10.0\vc\include\math.h(497): or       'double pow(double,int)'
1>          d:\program files\microsoft visual studio 10.0\vc\include\math.h(122): or       'double pow(double,double)'

 

 

 

void bla_bla (string import_format, string soft){
    //bla bla
    cout << "\n  nesto " << import_format << " (" << soft << ") nesto\n\n";
    //bla bla
}

 

(...).cpp(2857): error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::string' (or there is no acceptable conversion)
1>          d:\program files\microsoft visual studio 10.0\vc\include\ostream(679): could be 'std::basic_ostream<_Elem,_Traits> &std::operator <<<char,std::char_traits<char>>(std::basic_ostream<_Elem,_Traits> &,const char *)'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>
1>          ]

 

dok sam piso ovaj post, skužio sam da trebam na kraj imena objekta dodat .c_str() (import_format.c_str() itd). znam da to pretvara objekt tipa string u polje charova sa null znakom na kraju, al zanima me zašto to isto radi u codeblocksu, a ne i u vs-u Neodlucan

jurluk pet 3.6.2011 20:42

a vidi zbilja, ja sam mjenjao u settings, a ne u project - build options. kad promjenim u build options onda ne mogu ni s jednim drugim buildati, piše  " 'ime porjekta' uses an invalid compiler. Probably the toolchain path within the compiler options is not setup correctly?! Skipping..."

 

 

anyway, kako onda napraviti da ono gore radi u vs-u?

captain_soap_McTawish čet 9.6.2011 18:44

Pišem program u kojem mi je potrebna izuzetna preciznost, posebno što se tiče broja decimala. Float i dobule nisu za to prikladni i koliko vidim njih se ne preporučuje koristiti pri proračunima gdje se traži preciznost. Zanima me postoji li išta standardno u c++ za takve proračune ili ima li neka open-source bibloteka sa takvim tipovima? U javi postoji klasa BigDecimal za tekve slučajeve. Ima li nešto slično c++-u?

rustweaver čet 9.6.2011 18:50

long double?

 

Ali ozbiljno, sto to radis da ti double nije dovoljno precizan? Inace bi se floating point broj mogao emulirati nizom integera, i brojem koji govori na kojem bi se mjestu nalazila decimalna tocka. Nije bas IEEE standard, ali tako bi mogao nanizati jako jako dugacke brojeve...

 

Imas i ovo:

http://en.wikipedia.org/wiki/Quadruple_precision

 

Problem je samo sto su to nestandardni tipovi podataka, tako da podrska kod kompajlera varira...

captain_soap_McTawish čet 9.6.2011 18:57
rustweaver kaže...

long double?

 

Ali ozbiljno, sto to radis da ti double nije dovoljno precizan? Inace bi se floating point broj mogao emulirati nizom integera, i brojem koji govori na kojem bi se mjestu nalazila decimalna tocka. Nije bas IEEE standard, ali tako bi mogao nanizati jako jako dugacke brojeve...

 

Imas i ovo:

http://en.wikipedia.org/wiki/Quadruple_precision

 

Problem je samo sto su to nestandardni tipovi podataka, tako da podrska kod kompajlera varira...

Meni je problem kod float tipova što mi kompajler automatski zaokruži na 4 decimale. Kako ću specifirati da mi toliko ne zaokružuje.

captain_soap_McTawish čet 9.6.2011 19:02
rustweaver kaže...

Jesi li siguran da ti bas zaokruzuje, a ne da ti samo ispisuje prve 4 decimale?

Da prvo zaokruži na 4 decimale pa ispiše:

 

#include <iostream>

 

using namespace std;

 

int main()

{

   long double alpha=1.576897;

   cout<<alpha<<endl;

   return 0;

}

Ispis
  

rustweaver čet 9.6.2011 19:20

Neki brojevi se u floating point formatu uopce ne mogu tocno spremiti nego se aproksimiraju. Smanji preciznost da ne ispisuje toliko decimalnih mjesta i trebao bi dobiti 1.7687

 

Btw. kad si pisao svoj problem mislio sam da radis sa nekim kilometarskim decimalama, ali za ovo tvoje dovoljan je i obican float...

captain_soap_McTawish čet 9.6.2011 19:27
rustweaver kaže...

Neki brojevi se u floating point formatu uopce ne mogu tocno spremiti nego se aproksimiraju. Smanji preciznost da ne ispisuje toliko decimalnih mjesta i trebao bi dobiti 1.7687

 

Btw. kad si pisao svoj problem mislio sam da radis sa nekim kilometarskim decimalama, ali za ovo tvoje dovoljan je i obican float...

Hvala na pomoći.

 

Ovo sa manjim brojem decimala je bilo samo za primjer. Inače radit zasada ću raditi sa najviše 15 decimala i do veličine nekih 100 milijardi.