Warning: Illegal string offset 'name' in [path]/includes/functions.php on line 6439
C++ -
+
1 2 3

thread: C++

  1. #11
    Senior Member
    Nov 2009
    Jēkabpils
    2,055

    OK, paldies par skaidrojumu. Priekšā ļoti plašs darbalauks, kur izvērsties. Ar to c++ kā ar kvantu fiziku... jo dziļāk lien, jo vairāk jautājumu.

  2. #12
    Senior Member
    Nov 2009
    Jēkabpils
    2,055

    Nu re, radās kārtējais jautājums. Pašlaik šķirstu gūgli, bet, nu, uzjautāšu.
    Kods:
    :
    class SPIClass
    {
        public:
        SPIClass()
        {
            PORTB |= (1<<MISO)|(1<<MOSI)|(1<<SCK)|(1<<SS);
            DDRB |= (1<<MOSI)|(1<<SCK)|(1<<SS);
            SPCR = (1<<SPE)|(1<<MSTR);
            SPSR = (1<<SPI2X);
        }
        uint8_t transaction(uint8_t data)
        {
            SPDR = data;
            while(!(SPSR & (1<<SPIF))) continue;
            return SPDR;
        }
        inline void ss_low(void)
        {
            PORTB &= ~(1<<SS);
        }
        inline void ss_high(void)
        {
            PORTB |= (1<<SS);
        }
    };
    divas pēdējās funkcijas gribu, lai būtu "inline", jo kāda vella pēc dēļ vienas assemblera komandas lēkt uz apakšprogrammu un tad atkal atpakaļ. Bet kompilatoram mīkstais uz manu vēlēšanos. Kāpēc?

  3. #13
    Senior Member
    Apr 2007
    2,088

    Šis ir bieži pārprasts un nevietā lietots gadījums. Kā raksta http://stackoverflow.com/questions/1...nction-method:

    It is said that inline hints to the compiler that you think the function should be inlined. That may have been true in 1998, but a decade later the compiler needs no such hints. Not to mention humans are usually wrong when it comes to optimizing code, so most compilers flat out ignore the 'hint'.
    Respektīvi - necepies Un lieto atbilstošus optimizācijas uzstādījumus - vai nu -Os vai nu -O2 vai -O3 (mikrokontrolieru kompilatoriem gan parasti ir nosacītas iespējas optimizēt un nav atšķirības starp O2/O3, cik esmu novērojis).

  4. #14
    Senior Member
    Apr 2007
    2,088

    Ja DIKTI vajag, lai kods tiešām vienmēr būtu inline, tad to var panākt ar makro definīciju, jo tā brutāli ieraksta kodu tajā vietā.

    :
    #define SS_LOW  PORTB &= ~(1<<SS);

  5. #15
    Senior Member
    Nov 2009
    Jēkabpils
    2,055

    Paldies! Vakar vēlu vakarā pārdomu rezultātā nonācu pie tā, ka ar -O1 šis ieliek kā apakšprogrammu, bet ar -O2 un -O3 viss notiekās.
    Karoče, sasipos meistarībā Toč, tak ar makro šo lietu vienkāršāk izdarīt.

  6. #16
    Senior Member
    Nov 2009
    Jēkabpils
    2,055

    Labs rīts visiem!

    :
    enum mType
     {     
        CONT,     
        MEMB,     
        APPL, 
    };
    
    uint8_t function_1(uint8_t val);
    uint8_t function_2(uint8_t val);  
    
    struct menuItem 
    {    
        mType type;     
        //void (*function_1)(uint8_t val);   
        char* title;
         void* child;
         uint8_t count;
    };  
    
    const char mon[] = "Pirmdiena"; 
    const char tue[] = "Otrdiena"; 
    
    menuItem item1 = {MEMB, (char*)mon, (void*)&function_1, 5}; 
    menuItem item2 = {MEMB, (char*)mon, (void*)&function_2, 3}; 
    
    int main() 
    {
        menuItem *currentItem = &item1;
        cout << (int) (*currentItem->child)(currentItem->count) << endl;
        cout << (int) (*function_1)(currentItem->count) << endl;
         currentItem = &item2;
        cout << (int) (*currentItem->child)(currentItem->count) << endl;
        cout << (int) (*function_2)(currentItem->count) << endl;
    } 
    
    uint8_t function_1(uint8_t val) { return --val; }
    uint8_t function_2(uint8_t val) { return ++val; }
    Tātad situācija. Ir struktūra, kuras vienam elementam (void* child) gribu iebarot pointeri uz fukciju. Vispārīgi, ko šim elementam iebarot, ir atkarīgs no tā , kāds ir mType type. Vienā gadījumā man tur vajag iebarot pointeri uz citu šādu pašu struktūru. Tur viss iet bez problēmām. Bet šeit kompilators saka, ka;
    45:32: error: 'void*' is not a pointer-to-object type
    49:32: error: 'void*' is not a pointer-to-object type
    Es pat saprotu , ka šis ir malacis, ka tā saka, un kāpēc šis tā saka. Bet kā šajā gadījumā "pievest" *currentItem->child tipu? Jeb es jau no sākuma kaut ko daru nepareizi, un to "iebarošanu" vajag veikt kaut kā citādi. Gūgles tantes dotajās pamācībās, struktūrā vienmēr ir pointeris uz konkrētu funkciju, kā aizkomentētajā rindā. Bet tas neder .

    Iepriekš paldies, par Jūsu laiku un sapratni par manu c++ nevīžibu

    edit: būtībā vajadzētu varēt to izdarīt, jo pointers tak, rupji sakot, ir norāde uz adresi, kura tādam AVR ir vārds, vienalga, vai tas pointers norāda uz baitu vai struktūru vai funkciju.

    edit2: atradu variantu "vienādām" funkcijām - kam ir vienāda tipa un skaits parametru un kas atgriež vienādu tipu.
    :
    uint8_t func1(uint8_t val){return ++val;}
    ...
    uint8_t func10(uint8_t val){return --val;}
    
    typedef uint8_t(*ptr)(uint8_t);
    
    ptr pf1 = &func1;
    ...
    ptr pf10 = &func10;
    bet, vienalga, ja šos pointeros iebaro struktūrai kā (void*), tad atpakaļ ar (ptr*) nesanāk "pievest".

  7. #17
    Senior Member
    Apr 2007
    2,088

    Brr, vispirms mēs te īsti nezinām, kura rindiņa tev ir 45. un kura 49. Bet iekšējais kompilators aptuveni nojauš, kur pinies.

    Nekā tāda jau tur nav, mazas kļūdas. Pieeja ir lietojama, taču, lai strādātu, vajag drusku stingrāku tipāžu. Tātad, ja zini, ka tev tur tajā child reizēm var būt konkrēta tipa funkcija, kaut kur vajadzētu aprakstīt šo tipu, lai pēc tam var šo child konvertēt uz tādu pointeri. Tātad, vajag rindiņu

    :
    typedef uint8_t(*MyCleverFunctionType)(uint8_t);
    Un tad, kad zini un esi pārliecināts, ka currentItem->child ir interpretējams kā funkcija, tad vienkārši nokāsto:

    :
    MyCleverFunctionType menuFunc = (MyCleverFunctionType) currentItem->child;
    Tālāk jau vienkārši var izsaukt menuFunc(), kompilators zinās, kas jādara. Protams, es te izvērsti uzrakstīju, var arī vienā rindiņā.

    BET, ja gribi pro līmenī šo risināt, tad bārdainie vīri par to iedomājās jau sākumā un ieviesa tādu jēdzienu kā union - palasi, baigais haks, bet šajā situācijā noder, jo nav lieki jāskaidro kompilatoram, ka jā, es zinu, ko daru, jā, tā ir funkcija, tagad interpretē to šādi.

  8. #18
    Senior Member
    Apr 2007
    2,088

    Cita lieta - drusku nesaprotami, ko tu tur veido ar šo nepareizo rindu:

    :
    cout << (int) (*function_2)(currentItem->count) << endl;
    ja pietiktu (un būtu pareizi) vienkārši ar
    :
    cout << function_2(currentItem->count) << endl;
    function_1 taču ir joprojām vienkārši visparastākā funkcija, nekādu tur pointeru!

  9. #19
    Senior Member
    Nov 2009
    Jēkabpils
    2,055

    Velns, toč, rindu numuri tak neiekopējās. Atvainojos.

    Jā, nu tā ir, ka šitajā rindiņā rāda kļūdu
    :
    cout << (int) (*currentItem->child)(currentItem->count) << endl;
    Ja uzrakstu
    :
    ptr2func *tmpFunc = (ptr2func*)currentItem->child;
    cout << (int) (*tmpFunc)(currentItem->count) << endl;
    tad viss notiek. Vienā rindiņā gan nesanāk uzrakstīt. Gan jau iekavas ieliek ne tur vai neielieku, kur vajag.
    Sliktums ir tas, ka ja tiek padotas dažādas funkcijas, nevar zināt, kura kurā gadījumā ir īstā.
    Ar union mēģināju iepriekš. Acīmredzot, darīju kaut ko šķersām. Kamēr struktūrās ir parasti datu tipi, mani union strādā lieliski, līdzko sākas pointeri uz funkcijām un struktūrām, tā apmaldos kaut kur. Jā, bet nu union ir forša manta. Vispār, vēl nedēļu atpakaļ ieraugot izteiksmi ar daudzām iekavām, daudzām zvaigznītēm un ampersandiem, uznāca mazvērtības un bezcerības sajūtas - Visums tik liels, bet es tik mazs....

    Liels paldies, karloslv. Jāsaka, klusībā cerēju, ka Tu būsi tas, kas atbildēs.

    p.s smieklīgi sanāca
    :
    cout << (int) sizeof(ptr2func) << endl;
    rezultāts 8. Kāda vella pēc??? Struktūrai (tā kas kodā) reultāts 32. Kas par...??? Kamēr pielēca, ka rakstu iekš webiskās IDEs un uzrakstīju
    :
    cout << (int) sizeof(size_t) << endl;

  10. #20
    Senior Member
    Nov 2009
    Jēkabpils
    2,055

    Cita lieta - drusku nesaprotami, ko tu tur veido ar šo nepareizo rindu:

    :
    cout << (int) (*function_2)(currentItem->count) << endl;
    Ai, tā rinda ir vienkārši pārbaudei, ka tas iet cauri, ja funkcijas vietā lieto pointeri uz funkciju. Tas lai pats saprastu.

+