La respuesta seleccionada de Adam Rosenfield es incorrecta. La respuesta de Coobird también. Por esa razón, he votado ambas respuestas.
La interpretación de Adam Markowitz de *lineptr++
es correcta, pero no responde la pregunta principal si este es el código legal C99. Solo Tom Future lo hace; desafortunadamente él no explica *lineptr++
. Les concedí un punto cada uno.
Así que para abreviar, lineptr
es una variable y se puede manipular como un puntero. Por lo tanto, es legal incrementar el puntero.
lineptr
es un puntero en una secuencia de punteros a secuencias de caracteres. En otras palabras, es un puntero a la primera cadena de una matriz de cadenas. Según el código, podemos suponer que las cadenas son secuencias de caracteres terminadas nulas ('\ 0'). nlines
es el número de cadenas en la matriz.
La expresión de prueba while es nlines-- > 0
. nlines--
es una disminución posterior (porque --
está a la derecha de la variable). Por lo tanto, se ejecuta después de la prueba se ha realizado e independientemente del resultado de la prueba, por lo que en cualquier caso.
Por lo tanto, si el valor nlines
dado como argumento fue 0
, la prueba se realiza primero y devuelve false
; las instrucciones en el ciclo no se ejecutan. Tenga en cuenta que dado que nlines
se decrementa de todos modos, el valor de nlines
después del while
será -1
.
Si nlines == 1
, la prueba devolverá true
y nlines
se reducirá; las instrucciones en el ciclo se ejecutarán una vez. Tenga en cuenta que mientras se ejecutan estas instrucciones, el valor de nlines
es 0
. Cuando la prueba se realiza nuevamente, volvemos al caso cuando nlines == 0
.
La instrucción printf
utiliza la expresión *lineptr++
. Es un incremento posterior del puntero (++
está a la derecha de la variable). Esto significa que la expresión se evalúa primero y el incremento se realiza después de su uso. Por lo tanto, en la primera ejecución, printf
recibe una copia del primer elemento de la matriz de cadenas, que es un puntero al primer carácter de las cadenas. El lineptr
se incrementa solo después de eso. La próxima vez que se ejecute printf
, lineptr
apunta al segundo elemento y se moverá al tercero cuando se haya impreso la segunda cadena. Esto tiene sentido porque obviamente queremos imprimir la primera cadena. Si Adam Rosenfield estaba en lo cierto, la primera cuerda se habría omitido y al final trataríamos de imprimir la cuerda más allá de la última, lo que obviamente es algo malo de hacer.
Por lo tanto, la instrucción printf
es una forma concisa de las dos instrucciones siguientes
printf("%s\n", *lineptr);
++lineptr; // or lineptr++, which is equivalent but not as good. lineptr += 1; is ok too.
señalar, como regla general, que cuando pre- y post-incremento son equivalentes en su acción, la pre el incremento es preferible por razones de rendimiento. Los compiladores se encargarán de cambiarlo por usted. bueno, la mayoría del tiempo. Es mejor para el operador previo, siempre que sea posible, por lo que se usa siempre. La razón se vuelve más explícita una vez que implemente un post- y un incremento previo en C++.
Gracias por aclarar ... Me preguntaba si me estaba volviendo loco o no :) –