» »

[C++] for {}

[C++] for {}

BigWhale ::

V kaj bi se tole moralo prevesti? ANSI C++

#include <stdio.h>
int main()
{
  int i = 2;
  int hit = 3;

  printf("I: %d, H: %d\n", i, hit);
  for(int i = 0, hit = 0; i < 3; i++)
  {
     printf("I: %d, H: %d\n", i, hit);
  }
  printf("I: %d, H: %d\n", i, hit);

  return 0;
}


MS VisualStudio z Service pack 5, mi zadeve ne prebavi, nisem se pa spuscal v moznost iskanja te opcije...

g++ na linuxu in aCC (z opcijo -Aa) tole prevedeta, ven dobim pa tole:

I: 2, H: 3
I: 0, H: 0
I: 1, H: 0
I: 2, H: 0
I: 2, H: 3

Vse lepo in prav ampak vendar, v cem je tezava?

Tezava je v tistem (int i = 0, hit = 0).

Zakaj? Compiler tole prevede v (int i = 0, int hit = 0) (kar se seveda, ce user to sam napise ne prevede)

zed 5.0 ::

Hmm.. tole je v vsakem primeru grda koda. In za moje pojme zelo slabo doreceno podrocje v C compilerjih... To da MSjev compiler tega ne prevede se mi zdi skor bolj prav kot to da ga g++ prevede. Na Solarisu npr. (Sun Workshop), se niti deklaracija spremenljivke v for loopu ne prevede (int i = 0, int hit = 0), spremenljivke je potrebno deklarirati in sele nato jih lahko uporabis... Ceprav nebi zdaj o Sun-ovem compilerju. Sem ga ze preveckrat klel... Poleg tega so pri taksni deklaraciji pri MS-jevem in tudi npr. pri HP-UX-ovem compilerju spremenljivke vidne tudi izven for loopa, medtem ko so na Solarisu vidne samo znotraj. Primer:


for (int i = 0; i < 5; i++) // MS: Ok, HP-UX: Ok, Solaris: Error
{
printf("%d", i);
}

printf("%d", i); // MS: i visible, HP-UX: i visible, Solaris: i unknown

Kakorkoli ze, za moje pojme grda in vprasljiva koda (ceprav za dolocene compilerje legalna).

BigWhale ::

Khm, ne, ne..

(int i = 0, int hit = 0)

se nima kaj prevest v for zanki, to je sintakticna napaka.

Ce napises for(int i = 0, hit = 0....)

To compiler obravnava kot, da si na novo deklariral dve spremenljivki.

Vse kar sem hotel narest je to, da bi v for zanki uporabil en int kot counter in sem ga tam deklariral, hkrati pa en int, ki je bil iz drugega scope-a, scope-a funkcije, postavit na nulo... :)

No compiler mi je oba inta deklariral v scopu zanke... :)

McAjvar ::

umm, se opravicujem, ce bom kaj mimo bleknil, ker so moji casi c-ja ze dalec dalec, ampak ce se prav spomnim, je kar prav naredil.
afaik je cisto v redu, ce deklariras variable recimo
int a, i, piskot = 3, maslo = 0;

in v for stavku imas int i=0, hit = 0; po mojem smatra, kot si rekel, da hoces na novo deklarirati dve spremenljivki.

kaj pa, ce bi poskusil hit = 0, int i = 0;?

nimam c-ja pri roki nikjer, tako da ne morem preizkusit. no... to bi bla moja 2 stotina :)

[edit] sem nasel nekaj, kjer sem lahko sprobal... njah :8) to mu sploh ni vsec. kar je po svoje cist v redu in logicno... ampak kot je ze zed rekel, je grda koda :D
"[...] the advance of civilization is nothing
but an exercise in the limiting of privacy."
- Isaac Asimov

Zgodovina sprememb…

  • spremenil: McAjvar ()

64202 ::

g++ ti je prevedel pravilno.

VC++ 6.0 pa se uporablja starejsi standard za for scope (pred ANSI C++ 96, ce me spomin ne vara). Kaj cisto tocno dela v razlicnih primerih, ne vem. Novejsi VC++ ima opcijo, da vklopis tanov for scope handlanje (/Zc:forScope ali nekaj takega). Po defaultu je vklopljen ta star, zaradi backward kompatibilnosti za kodo jasno :).

zed 5.0 ::

Ce napises for(int i = 0, hit = 0....)

To compiler obravnava kot, da si na novo deklariral dve spremenljivki.


Hja, res... Tole sem spregledal. :) No, ampak hotel sem reci to, da se compilerji - kar se tice for loop-ov - obnasajo precej nekonsistentno. Imam kar nekaj izkusenj pri portanju C/C++ kode na HP-UX in Solaris - lahko recem, da sem ravno taksne situacije ze veckrat klel. Zato zdej rajsi pisem cimbolj nedvoumno kodo, pa je. Drugac bi pa omenjeni problem mogoce lahko resil z eno tako grdobo:

for (int i = hit = 0; i < 3; i++) ... :P

BigWhale ::

Ajvar, ma saj imas prav...

int a, b, v, c... in tako naprej..

Ma saj 'problem' sem resil ampak se mi je pa zdelo zanimivo...

No ja..

:)

Ghero0 ::

Lep pozdrav!

Ni cisto na to temo, ampak je blizu. tale scope spremenljivk me zanima. Ce mas neko spremenljivko definirano zunaj for zanke, kako naredis da je vidna tudi znotraj zanke?

npr:

int zunaj=0;

for(...)
{
if(zunaj ...)
}

ta "zunaj" znotraj zanke ne obstaja ne?
Banging your head against a wall uses 150 calories an hour.

Zgodovina sprememb…

  • spremenil: Ghero0 ()

OwcA ::

Vidiš vse zunanje, v kolikor jih nisi povozil. V tem primeru spremembe veljajo le znotraj danega bloka, torej se ne odražajo v "zunanjejših" tokenih (sicer nisem povsem prepričan, ampak verjetno bi se dalo packati tudi po funkcijah).
Otroška radovednost - gonilo napredka.

Zgodovina sprememb…

  • spremenilo: OwcA ()

Ghero0 ::

Mam tako situacijo:

v headerju mam definiran nstframe tko:
const int nstframe;

pol mam pa v mainu tole:

for(i=0; i < npix; i++)
{
for(int j=0; j < nstframe; j++)
cmedian[j] = cbuffer[j*npix+noffset];
.....
}

pa mi med debugiranjem jav:
Error: Simbol nstframe not found!
Banging your head against a wall uses 150 calories an hour.

OwcA ::

Lahko, da moraš malo packariti z extern.

Kjer se da, se izogibaj globalnim spremenljivkam.
Otroška radovednost - gonilo napredka.

Ghero0 ::

Sem ga prestavil v main in zdej ga pa vid... hm...

Tenx Owca!
Banging your head against a wall uses 150 calories an hour.

BigWhale ::

Vcasih so globali nuja... oziroma so bolj prikladna resitev, kot pingponganje spremenljivk med funkcijami... Ne pa vedno in niso pravilo. Sem enkrat delal z enim programom, kjer se je tudi po deset funkcij klicalo en za drugim in vse so kegljale z globalnimi spremenljivkami in strukturami. Za videt je bilo grozno, za debugirat se toliko bolj.

:P

Sergio ::

Bognedaj globalne spremenljivke. Pac pingpongas stvar med funkcijami in je...

IMHO
Tako grem jaz, tako gre vsak, kdor čuti cilj v daljavi:
če usoda ustavi mu korak,
on se ji zoperstavi.

Gundolf ::

Global variables are bad m'kay! Sploh take, ki si jih deli vec datotek. Fuj!

BigWhale ::

Mnjah, pri meni bo DB_CONN in defaultDB vedno globalna zadeva, taka, ki si jo deli vec datotek in OMG tudi vec razlicnih libov. Na bazo se povezes enkrat in to je to.

Pa marsiktera druga opcija iz 'Tools | Options' menija tudi... Branje user settings iz datoteke na 15 mestih v 15 razlicnih filetkih je trapast. Prav tako vsakic sproti kreirat nov printer objekt, ko hoces printat.

Bi se nasla se kaksna malenkost, ki jo je pametno imeti dostopno kot globalno spremenljivko, ime uporabnika recimo in njegov naslov.

Globalne variable so cisto ok, ce so pametno uporabljene. No, v vecini niso ampak ce so, en extern ni se nikogar ubil...

Zgodovina sprememb…

  • spremenil: BigWhale ()

OwcA ::

Meni se zdi precej lepša rešitev kot globalne spremenljivke ali konstante igranje s statičnimi metodami. Rezultat je enak, težav precej manj.
Otroška radovednost - gonilo napredka.

Gundolf ::

Branje user settings iz datoteke na 15 mestih v 15 razlicnih filetkih je trapast.

Sej noben ne pravi da moras 15x brat. Preberi enkrat in nato poslji vsem objektom ze prebrano strukturo. Je pa drugo, ce ne programiras objektno...

Problem globalnih spremenljivk je, da kazejo na slabo kodo. Sori, ampak tako je. Zdele se res nebi spomnu nobenga primera, kjer se ne da elegantno znebit globalne spremenljivke.

Je pa res da niso nikogar ubile :D Samo njihova uporaba mi je pa se vseeno ogabna.

degen ::

elegantna resitev za globalne spremenljivke je uporaba singleton vzorca...

priblizno nekaj takega kot pravi owca - imas nek razred, ki ima private constructor in staticne metode, ki skrbijo za to, da imas samo eno (ali pool) instanc nekega razreda

must read za vse oo programerje je knjiga design patterns
"It don't mean a thing if you can't get that Ping...."
Duke Ellington, 1932

kopernik ::

Singleton je anti-pattern :))

Sem zasledil že na več koncih tole trditev.

Zgodovina sprememb…

  • spremenil: kopernik ()

BigWhale ::

Naj da nekdo en primer, kako vsem objektom posljem eno strukturo, karkoli pac ze...

Se to naredi ob kreaciji objekta, ko se klice konstruktor?


(in ja, OOP je pri meni doma tri mesece recimo ;>)

Zgodovina sprememb…

  • spremenil: BigWhale ()

kopernik ::

Lahko malo bolj obrazložiš ?

Ti hočeš:
1. vsem objektom poslati/posredovati nek podatek (ali objekt) ?
2. da je nek podatek(ali objekt) dostopen vsem ostalim objektom ?

Zgodovina sprememb…

  • spremenil: kopernik ()

BigWhale ::

2.

Z dodatkom, da so nekateri objekti v executable knjiznici, vecina jih je pa pluginov v obliki knjiznic, ki se on demand nalagajo, ko jih user potrebuje.

Zgodovina sprememb…

  • spremenil: BigWhale ()

kopernik ::

Sklepam, da imajo plugini nek skupen interface. Potem uporabiš Factory pattern - narediš nek razred, ki skrbi za kreiranje instanc pluginov.
V takem razredu lahko tudi omejuješ število instanc teh tvojih pluginov (magari samo eno instanco, kar te pripelje do nekakšnega singletona).

Ok, primer. Vsa koda je v Javi, samo je tako enostavna, da jo ni problem prekodirati v kateri drugi prog. jezik. Najprej interface-i :


/*
 * Filename: Plugin.java
 * 
 * Created on 2004.12.5
 */
package com.bigwhale;

/**
 * Skupen interface za vse plugine.
 * 
 * @author Jan
 */
public interface Plugin
{
  /**
   * Izmislimo si eno metodo ...
   */
  public String getPluginName();
}



/*
 * Filename: Factory.java
 * 
 * Created on 2004.12.5
 */
package com.bigwhale;

/**
 * @author Jan
 */
public interface Factory
{
  public Plugin getPluginInstance();
}




Nato primer implementacije obeh inetrface-ov:


/*
 * Filename: DatabaseConnectionPlugin.java
 * 
 * Created on 2004.12.5
 */
package com.bigwhale;

import java.sql.Connection;

/**
 * Ta plugin skrbi za kreiranje konekcij na bazo,
 *  njihov recikliranje, ipd.
 * 
 * @author Jan
 */
public class DatabaseConnectionPlugin implements Plugin
{
  public DatabaseConnectionPlugin()
  {
    //TODO : logika za vzpostavitev driverja na 
    doloceno bazo, kreiranje pool-a konekcij, ipd.
  }
  
  public String getPluginName()
  {
    return DatabaseConnectionPlugin.class.getName();
  }

  public Connection obtainConnection()
  {
    //TODO : logika za kreiranje konekcij
    return null;
  }
  
  public void recycleConnection(Connection conn)
  {
    //TODO : logika za recikliranje konekcij
  }
}



/*
 * Filename: DatabaseConnectionFactory.java
 * 
 * Created on 2004.12.5
 */
package com.bigwhale;

/**
 * @author Jan
 */
public class DatabaseConnectionFactory implements Factory
{
  //sledeci podatek se lahko dobi iz nastavitev
  private static final int NUMBER_OF_ALLOWED_INSTANCES = 1; 
  private DatabaseConnectionPlugin plugin;
  
  public Plugin getPluginInstance()
  {
    return getAvailablePlugin();
  }

  /**
   * Ker vemo, da bomo imeli le eno instanco plugina, 
   * se ne obremenjujemo s posebno logiko
   * kreiranja in vzdrezavanja instanc nasega plugina. 
   * Torej ignoriramo prej deklarirano
   * konstanto NUMBER_OF_ALLOWED_INSTANCES.
   */
  private Plugin getAvailablePlugin()
  {
    if(this.plugin == null)
    {
      this.plugin = new DatabaseConnectionPlugin();
    }
    
    return this.plugin;
  }
}




Nato naredimo en registry oz. manager nasih tovarn :


/*
 * Filename: PluginRegistry.java
 * 
 * Created on 2004.12.5
 */
package com.bigwhale;

import java.util.HashMap;

/**
 * Nekaksen register vseh factory razredov.
 * 
 * @author Jan
 */
public abstract class PluginFactoryRegistry
{
  /**
   * Imejmo hash tabelo vseh nasih tovarn; 
   * kljuci naj bodo imena razredov, 
   * vrednosti pa instance tovarn.
   */
  private static HashMap factories; // { String, Factory }
  
  /**
   * Preko te metode bodo clienti dostopali do instanc tovarn.
   * 
   * TODO : potrebno je vnesti logiko za ravnajne 
   * ob napakah (npr. da hoce client
   * naloziti tak factory, za katerega ne obstaja razred)  
   */
  public static Factory getFactory(String className) 
      throws Exception
  {
    if(factories.containsKey(className))
    {
      return (Factory) factories.get(className);
    }
    else
    {
      Factory newFactory = (Factory) Class.forName(className).newInstance();
      factories.put(className, newFactory);
      
      return newFactory;
    }
  }
} 




Na koncu se primer clienta:


/*
 * Filename: ClientClass.java
 * 
 * Created on 2004.12.5
 */
package com.bigwhale;

/**
 * @author Jan
 */
public class ClientClass
{
  //sledeci podatek se obicajno prebere iz nastavitev
  private static final String FACTORY_NAME = 
    "com.bigwhale.DatabaseConnectionFactory"; 
  
  public ClientClass()
  {
    try
    {
      Plugin myPlugin = 
        PluginFactoryRegistry.getFactory(FACTORY_NAME).getPluginInstance();
      //TODO : karkoli zelimo delati z nasim pluginom ...
    } 
    catch (Exception e)
    {
      //prislo je do napake ...
      e.printStackTrace();
    }
  }
}




S pomočjo interface-ov dosežemo fleksibilnost (dodajanje novih pluginov piece of cake), s pomočjo factory patterna :
1. ločimo konkretne implementacije pluginov od client-a (zato lahko kasneje brez vednosti clienta zamenjamo implementacijo)
2. kontroliramo število instanc posameznega plugina.

Torej lahko z malo truda dosežemo veliko fleksibilnost našega API-ja.

Zgodovina sprememb…

  • spremenil: kopernik ()

kopernik ::

En majhen popravek:
seveda ni nobene potrebe po tem, da bi bil PluginFactoryRegistry abstrakten ...

In še to: zaradi možnosti dostopa do PluginFactoryRegistry iz večih threadov je potrebno nekaj stvari sinhronizirati ... ampak to naj bo vaja za drugič.

Vesoljc ::

no, pa dodamo še ref counting pa smart ptr-je, pa smo na konju 8-)

[ps, tema ja rahlo zablodila, neee? spremenimo naslov v kej bolj primernega?]
Abnormal behavior of abnormal brain makes me normal...

Nerdor ::

// #include #<stdio.h&#gt;
#include #<stdafx.h&#gt;

int main()
{
int i = 2;
int hit = 3;
int i;

printf("I: %d, H: %d\n", i, hit);
for(i = 0, hit = 0; i < 3; i++)
{
printf("I: %d, H: %d\n", i, hit);
}
printf("I: %d, H: %d\n", i, hit);

return 0;
}

Če odgovrim, čisto na začetku posta. Finta je v temu, da MS compiler ne pusti deklariranja spremenjivke v for zanki.
Po MS je pravilno:
int i;
for ( i=0; i< .. in ne for ( int i=0; i< .. Ta stavek je dovoljen samo v javi in C#. To je tudi razlog zakaj programiram, v javi in C#. Ker sta jezika last firme , pač firma bdi nad doslednostjo jeziko in prevajalnikov. Kar je tudi prav! Drugače je samo zmeda, kot pri C in C++.

kopernik ::

Vesoljc:
Se strinjam, da bi morali narediti novo temo. A ti imaš možnost forkanja ?

Nerdor ::

Sorry, sem spregledal, da je bilo vprašanju že odgovorjeno ;) . Zanima me, kako je C in VS.Net 2003. Ker ko sem se igral z Console app., mi je veselo ponujal C++. C primer, ki sem ga napisal en post višje VS.Net 2003 ne prebavi :O .
Drugače me pa prav zanima, ali v VS.Net 2003, seveda poleg Dx9, kaj programirate v C++. In če programirate v C++, kakšen framework uporabljate? ATL, WTL, MFC ? Unmanaged ali Managed ? Kako je kaj s temi zadevami.
Sedaj uporabljam samo C# in VB.Net za WinForm-e in Asp.Net.

Gundolf ::

Nerdor:
for (int i=0; i<10; ++i)

je cisto legalen C++ stavek in mislim da nelegalen C stavek.
Kar se pa zmede tice, je pa v primeru C ni, v C++ pa tudi vecina prevajalnikov lepo podpira ANSI C++ standard (MS VS 6 je eden zadnjih, ki se je kregal s standardom).

Za pisanje kode pa uporabljaj [ st.koda c ] koda-tu [ /st.koda c ], pa brez presledkov pred oz .za oklepaji.

Sam programiram v VS .net in ne uporabljam nobenega windows APIja, vecinoma delam v SDL + OpenGL. Unmanaged se razume samop po sebi, managed le ce zelis .net kodo. Mislim pa da lahko C kodo normalno pises, le file moras poimenovati neki.c. Drugace imas pa za vsak file nastavitve - kako oz. s cim naj se prevede in tam verjetno lahko eksplicitno dolocis C namesto C++. Ceprav ne vem zakaj bi se rad programiral v C ...


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

[Java] Zagon appleta v HTML

Oddelek: Programiranje
161540 (1362) Bela01
»

[JAVA] branje iz datoteke

Oddelek: Programiranje
242406 (2041) Bela01
»

[NALOGA][Java] Težave pri pisanju slikarja

Oddelek: Programiranje
202290 (1932) l0g1t3ch
»

[C++] dinamicna alokacija iz subrutine

Oddelek: Programiranje
171186 (1036) spin
»

[ OOP ] Global vs. Not Global

Oddelek: Programiranje
141239 (1034) noraguta

Več podobnih tem