Elementtien lukumäärä taulukon sarakkeessa

Millaista toimintoa voin tietää, kuinka monta elementtiä taulukon sarjassa on?

sizeof () antaa käytettävissä olevien ”välilyöntien” määrän, joten se ei toimi minulle.

Kommentit

  • Voitteko antaa esimerkin? esim. char foo [100] = "bar"; – tarkoitatko sitä? Haluatko vastauksen: 3?
  • kyllä, että ' s oikea

vastaus

Haluat strlen.

 char foo [100] = "bar"; Serial.println (strlen (foo)); // --> prints 3  

Kommentit

  • Jos Vastaus toimi sinulle napsauttamalla " accept " -painiketta (se näyttää rasti). Tällä tavoin muut ihmiset tietävät, että ratkaisu toimi.
  • Minun oli odotettava muutama minuutti tehdäksesi niin
  • Huomaa, että tämä toimii vain vain, jos sisältää ascii-merkkijonon, ja se on lopetettu oikein. Lisäksi, jos char[] -kohdassa on pitkä merkkijono ja kirjoitat sen lyhyemmällä merkkijonolla lisäämättä nolla-päättymistä, saat vanhemman merkkijonon koon.
  • Aivan oikein. Vastaukseni oli esitettyyn kysymykseen. Mainitsemasi asiat on otettava huomioon nollapäätteisissä C-merkkijonoissa.

Vastaa

Tunnen sinut saat vastauksesi @NickGammonilta, mutta haluaisin vain lisätä hieman syvällisempää tietoa kaiken tämän toiminnasta.

sizeof() ei ole toiminto sanan normaalissa merkityksessä.Se on operaattori, joka antaa sinulle tavuisen määrän tavuja muistia, mitä sille välität. Jos välität matriisin, se palauttaa matriisin käytettävissä olevan tavujen määrän. Jos välität sille osoittimen taulukkoon, se palauttaa osoittimen koon, ei matriisin kokoa.Jos välität sille kokonaislukumuuttujan, se palauttaa kyseisen kokonaismuuttujan käyttämän tavujen määrän (2 8-bittisellä) järjestelmä, kuten AVR, 4 32-bittisessä järjestelmässä, kuten Due).

Joten esimerkkejä:

char array[50] = "hello"; // sizeof(array) = 50. char *array_p = array; // sizeof(array_p) = 2 or 4 depending on architecture. char single = "a"; // sizeof(single) = 1. char string[] = "hello"; // sizeof(string) = 6 (5 letters plus \0) - it allocates the memory at compile time to fit the string 

Nyt strlen(). Kuinka tämä tarkalleen eroaa kohdasta sizeof()? Yksinkertaisesti sanottuna laskee merkkiryhmän merkkien lukumäärän, kunnes se saavuttaa merkin \0, joka on C-merkkijonon NULL-päätemerkki. Otetaan esimerkit aikaisemmin, mutta käytetään sen sijaan strlenia:

char array[50] = "hello"; // strlen(array) = 5. char *array_p = array; // strlen(array_p) = 5. char single = "a"; // strlen(single) = ERROR! strlen() doesn"t operate on single characters. char string[] = "hello"; // strlen(string) = 5. 

Huomaa, että se palauttaa merkkijonossa aina merkkimäärä, mutta ei, perässä oleva \0 -merkki.

Yksinkertaisimmassa muodossaan funktio strlen() saattaa näyttää tältä:

int strlen(const char *data) { int c = 0; const char *p = data; while (*p) { c++; p++; } return c; } 

Periaatteessa se alkaa merkkijonon ensimmäisestä merkistä (*p = data) ja tutkii, onko se ”sa \0 tai ei (while (*p)), lisää merkkien määrää (c++) ja siirtyy seuraavaan merkkiin merkkijonossa (p++).

Jos haluat toistaa merkkijonon ohjelmassa, voit soittaa strlen() ensin saadaksesi merkkijonon merkkijonon, käytä sitten arvoa silmukassa. Se on vähän tuhlaavaa, koska strlen() toistuu ensin merkkijonon läpi, joten pääset iteroimaan sen läpi kahdesti. On paljon tehokkaampaa oppia kuinka käydä parhaiten läpi merkkijonon jokainen merkki, kunnes löydät lopetettavan merkin, kuten miten strlen() -funktio käyttää osoitinta liikkua muistissa. Voit myös nähdä, kuinka tärkeää on varmistaa, että \0 -merkki on merkkijonon lopussa, muuten miten se toimii kuten strlen() tietää milloin lopettaa? He eivät voi tietää, kuinka kauan merkkijono on (sizeof() palauttaa välitetyn osoittimen koon, ei matriisin kokoa), joten heillä on oltava jonkinlainen manuaalinen merkki, ja C: n käytäntö on käyttää \0.

Huomaa, että Arduino ”s print() toimii todella tee se hyvin tehottomasti. Jos teet jotain seuraavista:

char message[] = "Hello"; Serial.println(message); 

Se tekee itse asiassa melko paljon työtä, jota sen ei tarvitse todella tarvita. askel askeleelta se:

  1. kutsuu println (viesti)
  2. joka kutsuu kirjoita (viesti)
  3. joka saa merkkijonon pituuden strlen (viesti)
  4. ja kutsuu kirjoitus (viesti, pituus)
  5. joka sitten silmukkaa 0: sta pituus-1: een ja lähettää viestin jokaisen merkin vuorotellen. lopulta tulostaa \r\n uudelle riville.

Joten se todella loppuu sisäkkäin noin 4 funktion syvyydessä ja toistaa koko merkkijonon kahdesti. klassinen esimerkki käsittelyajan tuhlaamisesta.Iteroimalla merkkijonon läpi etsimällä \0 -merkkiä funktiossa write(message) (vaihe 2), se toimisi vähintään kaksi kertaa nopeammin. Vanha hyvä Arduino …

Kommentit

  • Re ”Yksinkertaisimmassa muodossa strlen () -funktio saattaa näyttää tältä”, lyhyemmässä muodossa ( ehkä yksinkertaisempi?) muoto voi näyttää tältä: int strlen(const char *data) { const char *p = data; while (*p++); return p-data-1; }
  • @ jwpat7 sanoin " yksinkertaisin ", ei " lyhin ja pienin ". Tätä muotoa, vaikka se onkin pienempi ja tehokkaampi, OP: lle (joka ei tietenkään ole ohjelmoija) ole paljon vaikeampaa ymmärtää.
  • Hyväksytty 🙂 On myös helpompaa tehdä virheitä Ja jos \0 on segmentin viimeinen tavu, *p++ vikaa. Mutta int strlen(const char *data) { const char *p = data; while (*p) ++p; return p-data; } välttää ongelman.
  • Itse asiassa *p++ voitti ' t-vika, vaikka \0 on viimeinen käytettävissä oleva tavu segmentissä; *p osa käyttää viimeistä tavua; ++ -osa asettaa p virheelliseen osoitteeseen; mutta koska virheelliseen osoitteeseen ei ' ei viitata, tyypillisessä koneessa ei tapahdu vikaa.
  • Se on kääntöajan makro … Se ' ei ole makro , se ' on operaattori (kuten " + " ja " – " ovat operaattoreita). Ne ovat matalampia kuin makrot, jotka ovat asioita, jotka tehdään ennen prosessoria. Katso operaattorin koko . Myös operaattorit C ++: ssa

Vastaa

 use sizeof char nnn[10]; for(int i=0; i< sizeof(nnn)/sizeof(char); i++){ } 

kommentit

  • Luitko kysymyksen oikein?
  • OP kertoi sizeof " ei toimi ' t minulle " ja ehdotat sitten sizeofin käyttämistä.
  • ei voi vastata kysymykseen käytettäessä samaa tuntematonta

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *