El valor de s++
es el valor original de s
, antes del incremento, el incremento ocurre en un tiempo no especificado antes del siguiente punto de secuencia.
Por lo tanto *s++
y *(s++)
son equivalentes: ambos desreferencian el valor original de s
. Otra expresión equivalente es *(0, s++)
y, no para los débiles de corazón, tal es esta:0[s++]
Sin embargo, tenga en cuenta que su función debe usar type size_t
for i
y su tipo de retorno:
size_t str_len(const char *s) {
size_t i = 0;
while (*s++) {
i++;
}
/* s points after the null terminator */
return i;
}
Aquí hay una versión potencialmente más eficiente con un solo incremento por ciclo:
size_t str_len(const char *s) {
const char *s0 = s;
while (*s++) {
/* nothing */
}
return s - 1 - s0;
}
Para aquellos que se preguntan sobre las expresiones extrañas en el segundo párrafo:
0, s++
es una instancia del operador de coma ,
que evalúa su parte izquierda, luego su parte derecha que constituye su valor. por lo tanto, (0, s++)
es equivalente a (s++)
.
0[s++]
es equivalente a (s++)[0]
y *(0 + s++)
o *(s++ + 0)
que se simplifica como *(s++)
. La transposición del puntero y las expresiones de índice en []
expresiones no es muy común ni particularmente útil, pero se ajusta al estándar C.
, s++
y sucederán cosas malas:)
En ese ejemplo,
s
apunta a'a'
in"a"
. Luego se incrementa yi
también se incrementa. Ahoras
señale el terminador nulo, yi
es1
. Entonces, en la próxima ejecución a través del ciclo,*(s++)
es'\0'
(que es0
), entonces el ciclo termina y se devuelve el valor actual dei
(eso es1
).Generalmente, el ciclo se ejecuta una vez para cada carácter en la cadena, y luego se detiene en el terminador nulo, así es como cuenta los caracteres.
fuente
s
realizado antes del incremento. Lo que está describiendo es el comportamiento de++s
(que de hecho sería menos que uno e invocaría a UB si se pasa una cadena vacía).Tiene mucho sentido:
Es exactamente por eso que el puntero se incrementa y no el carácter, digamos que sí
(*s)++
, en este caso el carácter se incrementará y no el puntero. La desreferenciación significa que ahora está trabajando con el valor referido por el puntero, no el puntero en sí.Dado que ambos operadores tienen la misma precedencia pero asociatividad de derecha a izquierda, incluso puede usar simplemente
*s++
sin corchetes para incrementar el puntero.fuente
El operador posterior al incremento aumenta el valor del operando en 1, pero el valor de la expresión es el valor original del operando antes de la operación de incremento.
Suponga que el argumento pasado a
str_len()
es"a"
. En elstr_len()
, el punteros
apunta al primer carácter de la cadena"a"
. En elwhile
bucle:aunque
s
se incrementará, pero el valor des
en la expresión será el puntero al carácter al que apunta antes del incremento, que es el puntero al primer carácter'a'
. Cuando el punteros
se desreferencia, dará carácter'a'
. En la próxima iteración, els
puntero apuntará al siguiente carácter, que es el carácter nulo\0
. Cuandos
se desreferencia, se dará0
y el bucle se cerrará. Tenga en cuenta ques
ahora apuntará a un elemento más allá del carácter nulo de la cadena"a"
.fuente