Verdien til s++
er den opprinnelige verdien av s
, før inkrement, skjer inkrementet på et uspesifisert tidspunkt før neste sekvenspunkt.
Derfor *s++
og *(s++)
er ekvivalente:de refererer begge til den opprinnelige verdien av s
. Et annet ekvivalent uttrykk er *(0, s++)
og ikke for sarte sjeler, slik er denne:0[s++]
Vær imidlertid oppmerksom på at funksjonen din bør bruke typen size_t
for i
og dens returtype:
size_t str_len(const char *s) {
size_t i = 0;
while (*s++) {
i++;
}
/* s points after the null terminator */
return i;
}
Her er en potensielt mer effektiv versjon med ett enkelt trinn per sløyfe:
size_t str_len(const char *s) {
const char *s0 = s;
while (*s++) {
/* nothing */
}
return s - 1 - s0;
}
For de som lurer på de rare uttrykkene i andre avsnitt:
-
0, s++
er en forekomst av kommaoperatoren,
som vurderer dens venstre del, deretter dens høyre del som utgjør dens verdi. derav(0, s++)
tilsvarer(s++)
. -
0[s++]
tilsvarer(s++)[0]
og*(0 + s++)
eller*(s++ + 0)
som forenkles som*(s++)
. Transponering av pekeren og indeksuttrykkene i[]
uttrykk er ikke veldig vanlig eller spesielt nyttig, men samsvarer med C-standarden.
I det eksemplet, s
peker på 'a'
i "a"
. Deretter økes den og i
er også økt. Nå s
pek på nullterminatoren, og i
er 1
. Så i neste løp gjennom løkken, *(s++)
er '\0'
(som er 0
), så løkken slutter, og gjeldende verdi på i
(det er 1
) returneres.
Vanligvis kjører løkken én gang for hvert tegn i strengen, og stopper deretter ved nullterminatoren, så det er slik den teller tegnene.
Det gir perfekt mening:
int str_len(const char* s) {
int i = 0;
while(*(s++)) { //<-- increments the pointer to char till the end of the string
//till it finds '\0', that is, if s = "a" then s is 'a'
// followed by '\0' so it increments one time
i++; //counts the number of times the pointer moves forward
}
return i;
}
Det er nettopp derfor pekeren økes og ikke tegnet, la oss si at du har (*s)++
, i dette tilfellet vil tegnet økes og ikke pekeren. Derereferansen betyr at du nå arbeider med verdien referert av pekeren, ikke pekeren i seg selv.
Siden begge operatorene har samme forrang, men assosiativitet fra høyre til venstre, kan du til og med bruke *s++
uten parentes for å øke pekeren.