Kazalčne C uganke

Vse o programiranju na in za PC

Moderatorji: Kroko, tilz0R

Kazalčne C uganke

OdgovorNapisal/-a s54mtb » 28 Sep 2016, 23:19

Kako kaj kazalci?

Koda: Izberi vse
#include <stdio.h>

int main(void) {
    int a[3] = {111,222,333};
   
   printf("Zakaj je %d enako %d ?\n", a[2], 2[a]);
   
   return 0;
}



Pa še primer, kdaj so pointerji koristni. Katera koda se izvaja hitreje?
Koda: Izberi vse
#include <stdio.h>

int main(void) {
    int cifre[100], i;
    // ....... tu nekaj naredi s poljem .......
    for(i=0; i,100; i++){
      printf("%d\n",cifre[i]);
    }
     
   return 0;
}


ali tale:
Koda: Izberi vse
#include <stdio.h>

int main(void) {
    int cifre[100], i;
   
    int* num = cifre;
    for(i=0;i<100;i++){
       printf("%d\n",*num++);
    }
     
   return 0;
}
Uporabniški avatar
s54mtb
 
Prispevkov: 11488
Pridružen: 15 Jan 2015, 01:10
Zahvalil se je: 1588 krat
Prejel zahvalo: 4192 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 120

Re: Kazalčne C uganke

OdgovorNapisal/-a Kroko » 29 Sep 2016, 00:45

printf("Zakaj je %d enako %d ?\n", a[2], 2[a]);


Dobra. [] je subscript operator. Definiran je takole:
Koda: Izberi vse
E1[E2] is identical to (*((E1)+(E2)))
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4877
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 690 krat
Prejel zahvalo: 1704 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: Kazalčne C uganke

OdgovorNapisal/-a S53DZ » 29 Sep 2016, 10:23

Hm, odgovor je "raztresen", namreč z gcc na različnih mašinah/OS je rezultat zelo različen:
od povprečno -0,8% na win7
do povprečno -8% na linux

Izsek testne kode:
Koda: Izberi vse
    // test Mare
   t1 = clock();
    for(i=0; i<100000; i++){
        num = cifre;
        for(j=0; j<10000; j++) {
          cifre[j] = j+1;
       }
    }
   t2 = clock();
   
   for(i=0; i<100000; i++) {
       num = cifre;
       for(j=0; j<10000; j++) {
          *num++ = j+1;
       }
    }
    t3 = clock();
    printf("\n tick = %d, %d = %5.2f%%", t2-t1, t3-t2, 100.0*(1.0-((double)t2-t1)/((double)t3-t2)));
Tisti odvečni num = cifre je samo zaradi primerljivosti.
Uporabniški avatar
S53DZ
 
Prispevkov: 1175
Pridružen: 18 Jan 2015, 10:58
Kraj: Ljubljana
Zahvalil se je: 204 krat
Prejel zahvalo: 392 krat
Uporabnika povabil: S52O
Število neizkoriščenih povabil: 42

Re: Kazalčne C uganke

OdgovorNapisal/-a S53DZ » 29 Sep 2016, 11:27

Hm, malo se moram popraviti, namreč, ko sem pogledal povprečje odstopanja v zanki za 20 ponovitev, so rezultati (vsakokrat) drugačni.
Tako kaže, da je razlika zanemarljiva.

Koda: Izberi vse
 tick = 607, 586 = -3.58%
 tick = 586, 588 =  0.34%
 tick = 589, 596 =  1.17%
 tick = 602, 605 =  0.50%
 tick = 596, 590 = -1.02%
 tick = 593, 588 = -0.85%
 tick = 589, 587 = -0.34%
 tick = 588, 586 = -0.34%
 tick = 589, 585 = -0.68%
 tick = 587, 592 =  0.84%
 tick = 587, 586 = -0.17%
 tick = 588, 593 =  0.84%
 tick = 588, 584 = -0.68%
 tick = 586, 587 =  0.17%
 tick = 586, 586 =  0.00%
 tick = 586, 586 =  0.00%
 tick = 586, 584 = -0.34%
 tick = 588, 586 = -0.34%
 tick = 584, 585 =  0.17%
 tick = 587, 585 = -0.34%
 delta/20 = -0.23%
Uporabniški avatar
S53DZ
 
Prispevkov: 1175
Pridružen: 18 Jan 2015, 10:58
Kraj: Ljubljana
Zahvalil se je: 204 krat
Prejel zahvalo: 392 krat
Uporabnika povabil: S52O
Število neizkoriščenih povabil: 42

Re: Kazalčne C uganke

OdgovorNapisal/-a S53DZ » 04 Okt 2016, 08:25

Ker je zgornja koda precej neprimerna za ta test, sem se nanjo vrnil in jo dopolnil, da je rezultat bolj odvisen od željene razlike gcc kode polje/kazalec. Tako sem dobil razliko, ko sem že mislil, da je ni, haha. Sicer pa nanjo vpliva OS in po moje arhitektura.

Koda: Izberi vse
// work1.c - uporaba kazalcev v C-ju

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>

int main(void) {

   int i = 0, j = 0, n = 0;
   int k = 0;

   //test Mare
    int cifre[200000];
    int* num = cifre;
    int nMajor, nMinor;
    double deltaR, deltaS1, deltaS2;
    clock_t t1a, t1b, t2a, t2b;

    n = 18; nMajor = 19400; nMinor = 10000;
    deltaS1 = 0; deltaS2 = 0;
   printf("\nStart test Mare (n=%d) polje / kazalec ...", n);
    for(k=0; k<n; k++) {
      t1a = clock();
      for(i=0; i<nMajor; i++) {
         num = cifre;
         for(j=0; j<nMinor; j++) {
            cifre[j+0] = j;
            cifre[j+1] = j;
            cifre[j+2] = j;
            cifre[j+3] = j;
            cifre[j+4] = j;
            cifre[j+5] = j;
            cifre[j+6] = j;
            cifre[j+7] = j;
            cifre[j+8] = j;
            cifre[j+9] = j;
         }
      }
      t1b = clock();
      deltaR = ((double)(t1b-t1a))/CLOCKS_PER_SEC;
      deltaS1 += deltaR;
      printf("\n%4d: %5.3fs", k+1, deltaR);
      t2a = clock();
      for(i=0; i<nMajor; i++) {
         num = cifre;
         for(j=0; j<nMinor; j++) {
            *num++ = j;
            *num++ = j;
            *num++ = j;
            *num++ = j;
            *num++ = j;
            *num++ = j;
            *num++ = j;
            *num++ = j;
            *num++ = j;
            *num++ = j;
         }
      }
      t2b = clock();
      deltaR = ((double)(t2b-t2a))/CLOCKS_PER_SEC;
      deltaS2 += deltaR;
      printf(" / %5.3fs", deltaR);
    }
   deltaS1 /= n;
   deltaS2 /= n;
   printf("\n\n pov: %5.3fs", deltaS1);
   printf(" / %5.3fs", deltaS2);

   return 1;
}

Rezultat je zanimiv:
Koda: Izberi vse
Start test Mare (n=18) polje / kazalec ...
   1: 0.628s / 0.647s
   2: 0.611s / 0.647s
   3: 0.614s / 0.647s
   4: 0.614s / 0.644s
   5: 0.612s / 0.644s
   6: 0.610s / 0.645s
   7: 0.613s / 0.648s
   8: 0.614s / 0.646s
   9: 0.611s / 0.647s
  10: 0.610s / 0.645s
  11: 0.613s / 0.645s
  12: 0.611s / 0.646s
  13: 0.612s / 0.649s
  14: 0.613s / 0.646s
  15: 0.614s / 0.646s
  16: 0.612s / 0.645s
  17: 0.614s / 0.651s
  18: 0.612s / 0.645s

 pov: 0.613s / 0.646s  5.11%
Uporabniški avatar
S53DZ
 
Prispevkov: 1175
Pridružen: 18 Jan 2015, 10:58
Kraj: Ljubljana
Zahvalil se je: 204 krat
Prejel zahvalo: 392 krat
Uporabnika povabil: S52O
Število neizkoriščenih povabil: 42

Re: Kazalčne C uganke

OdgovorNapisal/-a zanka » 08 Okt 2016, 10:40

Večkrat mi koda (npr. funkcija, ki želi char *) ni delovala pravilno, če sem
Koda: Izberi vse
char str[10]

uporabil kot
Koda: Izberi vse
str
. Če sem pisal
Koda: Izberi vse
&str[0]
, potem pa je. :shock:

Ampak tudi printf je funkcija, ki ima argument tipa char *, a ta vedno deluje.

Razlage?
Uporabniški avatar
zanka
 
Prispevkov: 2693
Pridružen: 17 Mar 2016, 01:16
Zahvalil se je: 116 krat
Prejel zahvalo: 268 krat
Uporabnika povabil: DusanK
Število neizkoriščenih povabil: 53

Re: Kazalčne C uganke

OdgovorNapisal/-a tilz0R » 08 Okt 2016, 11:10

Ni razlag. Enostavno mora delat.

Prevajalnik in ostale nastavitve imaš katere?
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1855
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 231 krat
Prejel zahvalo: 528 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255


Vrni se na Programski jeziki

Kdo je na strani

Po forumu brska: 0 registriranih uporabnikov in 1 gost