Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++ tyhmä kysymys

Sivun loppuun

Opiskelija [15.02.2006 01:35:37]

#

Oompas tässä muutaman tunnin yrittänyt opetella C++, mutta ongelmaksi muodostu MySQL kysely, allaoleva tulostaa näytölle mitä haluan, mutta mitenkäs tuo sama tehdään itse kyselyyn?

....
int x;
  cout << "x" << endl;
  cin >> x;
  cout << "SELECT.... LIMIT " << x << ", 50";


if (mysql_query(&mysql, "SELECT.... LIMIT (x tieto tähän), 50 "))

Hörpeli [15.02.2006 07:25:18]

#

#include <sstream>

std::ostringstream ss;
ss << "SELECT .. LIMIT " << x << ", 50";
mysql_query(&mysql, ss.str().c_str());

Opiskelija [16.02.2006 10:45:06]

#

Kiitoksia tuolla toimiipi.

Opiskelija [17.02.2006 18:23:18]

#

Lisää tyhmiä kysymyksiä.

1) Miten määritellään moniulotteinen taulukko?

2) Miten lasketaan monta alkiota on?

Juice [17.02.2006 18:32:38]

#

1)

int jees[2][2];

2) Et mitenkään. Kannattaa varmaan joko
a) käyttää vektoreita
b) keksiä alkioitten määrä jotenkin muuten (ottaa ylös taulukoita luodessa)
c) laittaa null-arvo viimeiseen alkioon ja forrilla käydä sitten läpi

Deewiant [17.02.2006 19:08:11]

#

Juice kirjoitti:

1) int jees[2][2];

Joka ei ole moniulotteinen taulukko, vaan taulukoita sisältävä taulukko. Ei ihan sama asia.

T.M. [17.02.2006 19:11:53]

#

o_O? mikäs on sitten moniulotteinen taulukko jos ei tuo?

Jos nyt viilataan vielä pilkkua, niin oikeastihan taulukkoja ei ole olemassakaan, sehän on vain harhaa :P

Metabolix [17.02.2006 19:18:04]

#

Joissakin kääntäjissä tuo kuulemma vieläpä kieltäytyy toimimasta samalla tavalla kuin dynaamisesti varattu taulukollinen taulukkoja.

Ceez [17.02.2006 19:32:09]

#

Kyllähän sen moniulotteisen taulukon koon saa selville siinä missä yksiulotteisenkin.

T t[n][m];
size_t koko = sizeof(t)/sizeof(T);

Jokaisen blokin koko on sizeof(T), ja koko härpäkkeen koko nm*sizeof(T) joten tietty koko saada selville.

Mitä MySQL-kirjastoa muuten käytät opisklelija?

Opiskelija [19.02.2006 13:44:48]

#

Jälleen oppimisessa päästy eteenpäin kiitos auttajien.

Ceez: Käytän MySQL omaa kirjastoa, http://wiki.mureakuha.com/wiki/Libmysql_-_tuki_Dev-Cpp:lle tuon ohjeen mukaan sain toimimaan.

Deewiant [19.02.2006 13:50:50]

#

T.M. kirjoitti:

o_O? mikäs on sitten moniulotteinen taulukko jos ei tuo?

Tässä tapauksessa eroa ei hirveästi ole, koska taulukoiden koko on määritelty etukäteen.

Moniulotteinen taulukko on suorakulmion mallinen, kun taas taulukko, joka sisältää taulukoita, voi olla minkä mallinen tahansa: jokainen taulukko "päätaulukon" sisällä voi olla eripituinen.

Opiskelija [20.02.2006 20:18:29]

#

Jälleen tyhmä kysymys.

G++ sisältää jonkinmoisen koodin optimoijan, joka kyllä nopeuttaa melkoisesti. Mutta mitä moiset optimoijat koodille tekee?

Metabolix [20.02.2006 20:31:53]

#

Jonkin verran löytyy Applen GCC-sivuilta: http://developer.apple.com/documentation/DeveloperTools/gcc-3.3/gcc/Optimize-Options.html
Luulen kuitenkin, että tuolla on jo jonkin verran Mac-spesifistä tavaraa. -O2 kuitenkin näytti melko samalta kuin GCC:n lähdekoodissa, ja tuolta tosiaan löytyy tiiviit selitykset asioista.

Opiskelija [23.02.2006 17:08:29]

#

Kiitoksia. Vielä olis muutamia kysymyksiä.

Noita C++ kääntäjiä on monia, mutta onko niiden tuottamassa koodissa mitään eroa, kuten nopeudessa, toimivuudesa? Vai onko ihan sama mitä käyttää.


Mitenkäs muuttujat saa ohjelmaan eri tiedostosta? Siis, että ne haetaan joka kerta kun ohjelmaa suoritetaan.

Metabolix [23.02.2006 17:18:09]

#

Voi olla minimaalisia eroja, ainakin optimointien jälkeen, mutta käytännössä hyvin vähän. Kuitenkin yleisesti ehkä käytetyin kääntäjä löytyy GCC-paketista, joten voisi olettaa, ettei se ainakaan ole muita huonompi. Ja kun se kerran on avointa lähdekoodia, niin tuskinpa muutkaan silloin ovat kovin paljon sitä huonompia. Tietenkin sitten eri alustoille käännettäessä alkaa erojakin tulla, ymmärrettävistä syistä.

Merkkikääntäjät (VC++, Borland) tukevat toisinaan hieman omia virityksiään, ja lisäksi niiden standardikirjastot voivat olla hieman erilaisia. Microsoftin standardikirjastosta löytyy tunnetusti erinnäisiä bugeja, joiden ansiosta VC++ saa aikaan hieman toisin toimivan ohjelman kuin muut kääntäjät. Onneksi en itse ole törmännyt noihin.

Tiedostojen lukemisesta kertovat monet oppaat, esimerkiksi tämä: http://www.cplusplus.com/doc/tutorial/files.html

FooBat [23.02.2006 19:54:07]

#

Itse olen havainnut, että toisinaan gcc/g++:llä ja Microsoftin cl-kääntäjällä käännettyjen koodien välillä on paikoin jopa noin 20% nopeuseroja puoleen tai toiseen. Eli jos tarvitsee jotain todella nopeaa, kannattaa kokeilla eri kääntäjiä ennen kuin siirtyy kirjoittamaan asmseblya.

Itselläni ei ole tullut vastaan tilannetta, jossa molemmista kääntäjistä läpi mennyt koodi olisi toiminut jotenkin eri tavalla. Toki kannattaa olla varovainen käytettäessä kääntäjien eksoottisimpia optimointioptiota, jotka eivät välttämättä tuota oikeaa tai kaikilla koneilla toimivaa ohjelmaan.

koo [24.02.2006 19:16:09]

#

Koodin optimoija analysoi ja virittää generoitua konekielikoodia. Tyypillisiä temppuja ovat pikkufunktioiden inlinetys, silmukoitten oikominen, rekisterien merkityksettömien muistilukujen/kirjoitusten poistelu ja toisistaan riippumattomien operaatioiden uudelleenjärjestely ja rinnakkaistus peruslohkojen sisällä. Ei ihan tavallisen koodipuoskarin hommaa, vaan vaatii aika paljon analyysiä ja taustatietoa koodista ja prosessoriarkkitehtuurista (ja konetehoa käännösaikana). Varsinkin kireimmillä asetuksilla optimointi saattaa mennä myös vikaan, kun optimoija tekee liian pitkälle meneviä oletuksia tai sekoaa omiin laskelmiinsa.

Kääntäjiä on erilaisia ja se on periaatteessa ihan hyvä, sillä silloin on kilpailua, valinnanvaraa ja kehitystä. Standardin mukaan kirjoitetun koodin pitäisi wörkkiä ihan samalla tavalla kääntäjästä riippumatta, vaikka exen koko ja ajoaika voivat vaihdella.

Usein on ihan sama, mitä kääntäjää käyttää, kunhan kääntäjä on riittävän uusi eikä rupea sotkemaan eri kääntäjillä tehtyjä juttuja keskenään. Kannattaa myös lukea lähinnä tällä vuosituhannella kirjoitettuja C++-kirjoja. Kaiken maailman DJGPP-purkkaviritykset ja ikivanhat C++ Builder -versiot yhdessä vanhojen opaskirjojen kanssa eivät oikein edistä <iostream>- ja int main()-juttujen perillemenoa, puhumattakaan ihan oikeista kirjastoasioista ja ohjelmointikäytännöistä.

Gnu-kääntäjillä käännösajat ovat yleensä melko pitkiä eikä lopputuloskaan yleensä ole nopein mahdollinen. Siirrettävyys on kuitenkin ollut hyvä, sillä jokseenkin samat temput ja kirjastot ovat olleet saatavissa ja toimineet ompelukoneista superkompuuttereihin. G++:n kolmosversion aikoihin kirjastopaketti meni remonttiin ja oli aika epämääräisessä kunnossa. Viimeisintä tilannetta en ole ihan tarkkaan seurannut.

Microsoftin vanhemmat kääntäjät (erityisesti MSVC++6) eivät eri syistä ole olleet ihan standardin tasalla. Intelin kääntäjä on ollut optimoinnin huippua pc-ympäristössä, mutta jos nyt ottaa tuoreen MS:n kääntäjän (vähintään 2003 kun 2005:kin on saatavilla ja ilmaiseksi), niin ero nopeudessa ei ole enää kovinkaan suuri. Nykyään MSVC++ on parhaimmasta päästä myös standardinmukaisuutensa puolesta.

Itse en olisi ottamassa assemblyä käyttöön nopeuttaakseni koodia, vaan miettisin algoritmipuolta uudelleen. Kääntäjä optimoi koodin (konekieleksi) usein ihmeen paljon paremmin kuin mitä koodaaja itse luulee assemblyllä pystyvänsä.

Opiskelija [03.03.2006 23:57:09]

#

Vielä semmoista, että miks G++ tekee hello worldista yli 400kt suuremman tiedoston kuin Microsoftin kääntäjä?

koo [04.03.2006 00:37:16]

#

Voisiko olla niin, että Microsoftin kääntäjä linkkaa ohjelman dynaamisen kirjaston kanssa, mitä Gnu-kääntäjä ei sitten Windows-ympäristössä teekään. Ero voisi syntyä myös siitä, että käytetään erilaisia optimointi- ja debug-vipuja.

Pienehköt erot exen koossa ovat ihan odotettaviakin, kyseessähän on eri "tuotteet".

A-P [04.03.2006 13:34:33]

#

Juuri tuosta linkittämisestä on kyse. Solariksessa dynaaminsta linkitystä käyttäen käännetty Hello world -ohjelma vie 5 kt ja staattisesti (eli kirjastot mukaan linkitettynä) 376 kt (ilman debuggaustietoja 240 kt).

Hörpeli [04.03.2006 14:20:19]

#

Opiskelija kirjoitti:

Vielä semmoista, että miks G++ tekee hello worldista yli 400kt suuremman tiedoston kuin Microsoftin kääntäjä?

Se sisältää debuggaustavaraa. Siitä lähtee muutama sata kilotavua kun ajat strip.exe ohjelmasi.exe. Strip.exe löytyy sieltä missä g++.exekin sijaitsee.

Metabolix [05.03.2006 15:19:34]

#

Kun käännät sen lipulla -s, tuo tehdään automaattisesti.

Opiskelija [05.03.2006 18:22:39]

#

Mitäs kaikkia lippuja kääntämisessä kannattaa käyttää jotta exen suoritus olis nopeaa ja muutenkin yleisesti ottaen?
Tähän mennessä lähinnä iso ja pikku o ovat olleet mukana, ja nyt tuo s.

Opiskelija [07.03.2006 21:37:32]

#

Mites pystyy käyttämään isohkoja lukuja kun long long ei riitä?

Jaska [07.03.2006 21:58:17]

#

Logaritmeillä tai jollain suuren tarkkuuden aritmeettisella kirjastolla, vaikkapa GMP:llä

Opiskelija [08.03.2006 14:51:05]

#

Täytyypä illemmalla katsella tuota GMP:tä joskos sillä onnistus.

Entäs miten double muuttuja tyyppinen tulostetaan bitteinä?

Jaska [08.03.2006 15:33:15]

#

Mitä tarkoitat "tulostetaan bitteinä"? Tietokoneessahan kaikki muuttujat ovat bittejä, joten eikös se tapahdu komennolla

std::cout << d;

missä d on double-tyyppinen muuttuja? Haitko kenties jotain muuta, kerropa selkeämmin mitä haluat.

Deewiant [08.03.2006 15:53:47]

#

Jaska kirjoitti:

Mitä tarkoitat "tulostetaan bitteinä"? Tietokoneessahan kaikki muuttujat ovat bittejä, joten eikös se tapahdu komennolla

std::cout << d;

missä d on double-tyyppinen muuttuja? Haitko kenties jotain muuta, kerropa selkeämmin mitä haluat.

Tarkoittanee, että tulostetaan bitit, joista muuttuja koostuu. Eli esimerkiksi muuttujan ollessa nolla tulostuisi 64 nollaa (olettaen, että double on 64-bittinen liukuluku).

Heikki [08.03.2006 16:32:23]

#

Siinä tapauksessa pitää muuntaa luku 2-lukujärjestelmään. Tässä joku vanha koodini joka muuntaa 10-järjestelmän luvun toiseen järjestelmään:

 int luku=1234;	// Muunnettava luku

 // Vektori johon muunnetut luvut tallennetaan
vector<short int>muunnettu;

 // Muunto
 bool run=true;
 int kanta=2;	// Kantaluku

 while(luku!=0) {
     muunnettu.push_back(luku%kanta);
     luku/=kanta;
 }

Koodi on aika vanha ja en mene takuuseen että se toimii (en jaksa testata vaikka vähän siistinkin).

Deewiant [08.03.2006 19:16:40]

#

Ongelma tuossa tekniikassa on, että se ei taida toimia liukuluvuille. Niiden bittikoostumus kun on vähän kiinnostavaa lajia, ja riippuu vielä järjestelmästä. Asiaan liittyvä linkki: http://docs.sun.com/source/806-3568/ncg_goldberg.html

Metabolix [08.03.2006 20:08:21]

#

Osoitinkikkailuilla tuokin onnistuu. Tässä C-tyylinen esimerkki, C++ tietenkin tykkää enemmän omista tyypinmuunnoksistaan (reinterpret_cast jne.)

void tulosta(double luku)
{
  void * osoitin = &luku;
  int i, j;
  for (i = 0; i < sizeof(double); ++i)
    for (j = 0; j < 8; ++j)
      printf("%i", ((((unisgned char *)osoitin)[i] >> j) & 1));
}

En testannut, mutta tuolla idealla. Tuosta voi vielä suuntaa käännellä halunsa mukaan oikeammaksi.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta