Zkrácení kódu – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Zkrácení kódu – C / C++ – Fórum – Programujte.comZkrácení kódu – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené.
oxidián0
Grafoman
27. 3. 2015   #1
-
0
-

Dal by se nějak zkrátit tento zápis?

http://paste.ofcode.org/MH236TZH9gRSDWYKkVnyVn

Je to v podstatě se třikrát opakuje jedno a to samé ale pokaždé pro jiného člena:

if (col==HCol) {
switch(attribute){
    case min_fc:
        w->color_files[file_no].color_sets[color_set].H.min=atoi(colTok);
    break;
    case max_fc:
        w->color_files[file_no].color_sets[color_set].H.max=atoi(colTok);
    break;
    case avg_fc:
        w->color_files[file_no].color_sets[color_set].H.max=atof(colTok);
    break;
    case fuzz_fc:
        w->color_files[file_no].color_sets[color_set].H.fuzz=atof(colTok);
    break;
    case no_attr_fc:
        printf("Color file: no attribute present for H.\n");
    break;
}
}
typedef enum {
    min_fc,
    max_fc,
    avg_fc,
    fuzz_fc,
    no_attr_fc
} COLORFILE_ATTR_t;
typedef struct COLORS_CF_ {
    uint16_t class;
    uint16_t group;
    uint16_t color;
    uint16_t attr;
    ATTRIBUTES_t H;
    ATTRIBUTES_t S;
    ATTRIBUTES_t V;
} COLORS_CF_t;
typedef struct COLOR_FILE_
{
    COLORS_CF_t * color_sets;

}

Existuje něco jako řešení pomocí pointeru? Nastavit pointer na člena a pak použít na to pointer? Jestli to jde jak ukažte jak.

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
27. 3. 2015   #2
-
+1
-
Zajímavé

   

// Jedna uroven zprehledneni je neco jako (ale otestovat to nemuzu, tak je to mozna blbe):
COLORS_CF_t*  item = &(w->color_files[file_no].color_sets[color_set]);
ATTRIBUTES_t* attr = NULL;
switch (col) {
  case HCol: attr = &(item->H); break;
  case SCol: attr = &(item->S); break;
  case VCol: attr = &(item->V); break;
}
if (attr != NULL) {
  uint16_t 
  switch (attribute) {
    case min_fc:  attr->min  = atoi(colTok); break;
    case max_fc:  attr->max  = atoi(colTok); break;
    case avg_fc:  attr->avg  = atof(colTok); break; // nebo tam melo byt opravdu znova max?
    case fuzz_fc: attr->fuzz = atof(colTok); break;
  }
}

Dalsi uroven uz bude trosku narocnejsi, mozna bude potreba prvni spocitat offsety tech promennych.

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
27. 3. 2015   #3
-
0
-

Správně si to pochopil, že tam mělo být avg místo max. Asi to zkusím zítra, dneska jsem už unavený. A ještě dotaz k tomu atof, existuje i nějaká obdoba která by číslo převedla na float místo double?

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
27. 3. 2015   #4
-
0
-

 A uplne ultimatni reseni (ted aspon testovano):

#include <stdint.h>
#include <stdio.h>
#include <stddef.h>     /* offsetof */

typedef struct {
  int16_t        min;
  int16_t        max;
  float          avg;
  float         fuzz;
} ATTRIBUTES_t; 

typedef struct {
  uint16_t     class;
  uint16_t     group;
  uint16_t     color;
  uint16_t      attr;
  ATTRIBUTES_t     H;
  ATTRIBUTES_t     S;
  ATTRIBUTES_t     V;
} COLORS_CF_T;

typedef enum {
    min_fc,
    max_fc,
    avg_fc,
    fuzz_fc,
    no_attr_fc
} COLORFILE_ATTR_t;

typedef enum {
    HCol,
    SCol,
    VCol
} COLORFILE_COL_t;

int col_offsets[] = {
    offsetof(COLORS_CF_T, H),
    offsetof(COLORS_CF_T, S),
    offsetof(COLORS_CF_T, V)
};

int attr_offsets[] = {
    offsetof(ATTRIBUTES_t,min),
    offsetof(ATTRIBUTES_t,max),
    offsetof(ATTRIBUTES_t,avg),
    offsetof(ATTRIBUTES_t,fuzz)
};


void atoi_extra(char * base, uint32_t offset, const char * colTok) {
  *((int16_t *)(base+offset)) = atoi(colTok);
}

void atof_extra(char * base, uint32_t offset, const char * colTok) {
  *((float *)(base+offset)) = atof(colTok);
}

void empty_extra(char * base, uint32_t offset, const char * colTok) {
}

void (*attr_functions[5])(char*, uint32_t, const char*) = {
  atoi_extra,
  atoi_extra,
  atof_extra,
  atof_extra,
  empty_extra // dummy - for not to crash on no_attr_fc
};


int main() {
  COLORS_CF_T  test = {0,0,0,0,{0,0,0.0,0.0},{0,0,0.0,0.0},{0,0,0.0,0.0}};

  printf("%f\n", test.S.fuzz);
  attr_functions[fuzz_fc](((char *)& test) + col_offsets[SCol], attr_offsets[fuzz_fc], "123");
  printf("%f\n", test.S.fuzz);
}
Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
27. 3. 2015   #5
-
0
-

Proč v tom prvním kódu je typ před switch?

uint16_t switch (attribute)
Co to znamená?

Ten druhý kód už mi přijde dost složitý. Já bych se vyhnul zbytečným voláním funkcí.

Co znamená toto:

void (*attr_functions[5])(char*, uint32_t, const char*) = {
  atoi_extra,
  atoi_extra,
  atof_extra,
  atof_extra,
  empty_extra // dummy - for not to crash on no_attr_fc
};
Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
27. 3. 2015   #6
-
0
-

#5 oxidián
ten typ je chybka, nejaka naznacena ale nedokoncena myslenka :)

To druhe je pole pointeru na funkce. Jelikoz pouzivas ruzne funkce pro ruzne polozky, tak je to poresene stejnym prototypem funkci a ruznou funkcionalitou.

A slozity neni, mel bys to pak zkracene na jeden radek.. (+ par statickych predem definovanych poli)

(jo jeste mi tam chybelo #include <stdlib.h> aby fungovalo i to atof)

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
KIIV
~ Moderátor
+43
God of flame
27. 3. 2015   #7
-
0
-

No a kdyz bys nechtel tak moc akutne volat zadnou funkci (switch taky skace, jen nemusi ukladat nektery promenny na stacku), tak:

  const char *        colTok = "2342";
  COLORFILE_COL_t        col = HCol;
  COLORFILE_ATTR_t attribute = min_fc; 
  switch (attribute) {
    case min_fc:
    case max_fc:
      *((int16_t *)(((char*)&test) + col_offsets[col] + attr_offsets[attribute])) = atoi(colTok);
      break;
    case avg_fc:
    case fuzz_fc:
      *((float *)(((char*)&test) + col_offsets[col] + attr_offsets[attribute])) = atof(colTok);
      break;
  }

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
28. 3. 2015   #8
-
0
-

Trochu to trvalo protože jsem ještě odstraňoval bugy.

Zatím jsem zkoušel ten první kód a ten se zdá funkční. Ještě musím iniciovat počáteční hodnoty, což jak vidím ty si udělal v tom druhém kódu. Tenhle způsob iniciace* je velmi zajimavý, ale dá se to tak udělat i když tam mám ampersand &?

// color_set reference:
COLORS_CF_t*  item = &(w->color_files[file_no].color_sets[color_set]);
ATTRIBUTES_t* attr = NULL;
attr=col==HCol?&(item->H): // set color_set member (attribute)
    col==SCol?&(item->S):&(item->V);
if (attr != NULL) {
      switch (attribute) {
        case min_fc:  attr->min  = atoi(colTok); break;
        case max_fc:  attr->max  = atoi(colTok); break;
        case avg_fc:  attr->avg  = atof(colTok); break; // nebo tam melo byt opravdu znova max?
        case fuzz_fc: attr->fuzz = atof(colTok); break;
      } // switch
    } // attr != null

Pozn. * - myšleno COLORS_CF_T test = {0,0,0,0,{0,0,0.0,0.0},{0,0,0.0,0.0},{0,0,0.0,0.0}};

Mělo by to být takto?

COLORS_CF_t  * item = {0,0,0,0,{0,0,0.0,0.0},{0,0,0.0,0.0},{0,0,0.0,0.0}};

Zdá se mi že se to vyluřuje. První deklarace používá ampersand jako odkaz na něco. A druhá deklarace už tam být nemůže, jak bych teda mohl vytvořit odkaz na něco a zároveň to vynulovat?

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
28. 3. 2015   #9
-
0
-

#8 oxidián
nema to byt pointer, potreboval jsem jednnu realnou strukturu s tema podstrukturama ... patri to k tomu ukazkovymu prikladu kde je i funkce main a tak.

Ty bys samozrejme musel zneuzit pointer

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
28. 3. 2015   #10
-
0
-

Tak jo, zneužil jsem ten pointer:

if (col==0) {
    /** Initiate attributes **/
    COLORS_CF_t*  item = &(w->color_files[file_no].color_sets[color_set]);
    ATTRIBUTES_t* attr;
    attr = &(item->H);
    attr->min=0; attr->max=0; attr->avg=0.0; attr->fuzz=0.0;
    attr = &(item->S);
    attr->min=0; attr->max=0; attr->avg=0.0; attr->fuzz=0.0;
    attr = &(item->V);
    attr->min=0; attr->max=0; attr->avg=0.0; attr->fuzz=0.0;
    }
Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
28. 3. 2015   #11
-
0
-

Jelikož atof akceptuje pouze anglické číslice s tečkou, jak to udělat když potřebuju zaměnit čárku uvnitř stringu za tečku?

Nahlásit jako SPAM
IP: 78.45.199.–
28. 3. 2015   #12
-
0
-

Trochu vlastní tvořivosti by nebylo? Trochu prasárna: pomocí strchr získám ukazatel na des. čárku a nahradím ji jakýmkoliv znakem.

hu

Nahlásit jako SPAM
IP: 193.86.81.–
oxidián0
Grafoman
28. 3. 2015   #13
-
0
-

večer už mi žádná tvořivost nezbývá

tak jo, už to mám:

char * p; // converts comma to point
p=strchr(colTok,',');
if (p)
  p[0]='.';


Dík

Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
29. 3. 2015   #14
-
0
-

Když potřebuju překonvertovat int, je lepší to udělat takto:

item->H.min=(item->H.min*1.0)/360*255;

nebo takto:

item->H.min=((float) item->H.min)/360*255;

je to výkonnostně stejné?

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
29. 3. 2015   #15
-
0
-

nech si to prelozit do assembleru a podivej se (samozrejme se zaplejma optimalizacema, defaultne se to moc neoptimalizuje)

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
30. 3. 2015   #16
-
0
-

Chceš říct, že si to mám nechat přeložit asemblerem...

Exaktní česká terminologie vychází z toho, že assembler označuje pouze překladač, zatímco programovací jazyk označuje výhradně jako jazyk symbolických adres (JSA), kterýžto výraz popisuje základní nabízenou výhodu – odstranění nutnosti ručně propočítávat veškeré adresy při překladu programu.

V praxi se ovšem velmi často (a zcela nesprávně) pro označení JSA používá termín assembler.

http://cs.wikipedia.org/wiki/Jazyk_symbolick%C3%BDch_adres

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
30. 3. 2015   #17
-
0
-

prelozit pomoci gcc do assembleru... (kazdopadne tu nebudu vypisovat pokazdy "do jazyka symbolickych instrukci")

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
30. 3. 2015   #18
-
0
-

#17 KIIV
A proč prostě neřekneš do jazyka asembleru? Jinak mám ještě dotaz k tomu převodu zaokrouhlování (přičíst 0.5) se má dělat kde? To má být hned za dělením nebo až po vynásobení?

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
30. 3. 2015   #19
-
0
-

Zaokrouhleni se dela jednoduse:

(int)(cislo+0.5)

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 121 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý