‘++’ múltiple trabajando en variables, y punteros

Esto es lo que creo que hace el operador ++

  1. a++; // a+=1 after calculating this line
  2. ++a; // a+=1 before calcuating this line

Estoy tratando de estudiar los indicadores, y creo que entendí mal algo.

 int a=10; int arr[3]={0,1,2}; int *ptr; ptr=arr; printf("%d,%d,%d,%d\n",a++,a++,++a,++a); printf("%d,%d,%d\n", ptr[0],ptr[1],ptr[2]); printf("%d,%d,%d,%d,%d,%d", * ptr++, ( * ptr)++, ++ * ptr, ++( * ptr), *++ptr, * ptr); 

Esperaba que la salida fuera:

 12, 12, 12, 12 0,1,2 3,3,3,3,3,3,3 

Pero no fue así. Fue este:

 13,12,14,14 0,1,2 4,3,2,2,2,2 

¿Por qué es esto?

No se supone que haga más de un incremento en los argumentos de una función … porque el orden en el que se pueden evaluar es ambiguo. El resultado de dicho código es indefinido.

Significado: printf("%d,%d,%d,%d\n",a++,a++,++a,++a); Debe ser escrito como

 a++; a++; ++a; ++a; printf("%d, %d, %d, %d\n", a, a, a, a); 

Pruebe y arregle eso primero y vea si los resultados siguen siendo confusos.

Más generalmente, solo debe tener un incremento entre un par de puntos de secuencia.

Edit: Chris tiene razón, no tiene sentido escribir cuatro incrementos en el medio de la nada. Para responder mejor a su pregunta: Para una función void f(int) y void g(int) , con int a=0 ,

 f(++a) = f(1); f(a++) = f(0); g(++a, ++a) = g(???); // undefined! 

Entonces, incrementa como máximo una vez en el argumento a una función.

No hagas esto El comportamiento es indefinido.

De la especificación C (sección 6.5) …

Entre el punto de secuencia anterior y el siguiente, un objeto tendrá su valor almacenado modificado a lo sumo una vez por la evaluación de una expresión. Además, solo se debe acceder al valor anterior para determinar el valor que se almacenará.

Excepto lo indicado por la syntax o especificado de otra manera más adelante (para los operadores de llamada de función (), &&, ||,?:, Y operadores de coma), el orden de evaluación de las subexpresiones y el orden en que se producen los efectos secundarios son no especificado

En otras palabras, si actualiza el valor de una variable varias veces en los argumentos de una función, no está escribiendo el código C legal.

Ver 3.2 en la C Preguntas frecuentes:

3.2: Bajo mi comstackdor, el código

  int i = 7; printf("%d\n", i++ * i++); 

impresiones 49. Independientemente del orden de evaluación, ¿no debería imprimir 56?

R: Aunque los operadores de postincremento y postdecrement ++ y – realizan sus operaciones después de obtener el valor anterior, la implicación de “después” a menudo se malinterpreta. No se garantiza que un incremento o decremento se realice inmediatamente después de abandonar el valor anterior y antes de que se evalúe cualquier otra parte de la expresión. Simplemente se garantiza que la actualización se realizará en algún momento antes de que la expresión se considere “terminada” (antes del siguiente “punto de secuencia”, en la terminología de ANSI C; consulte la pregunta 3.8). En el ejemplo, el comstackdor eligió multiplicar el valor anterior por sí mismo y realizar ambos incrementos más tarde.

El comportamiento del código que contiene múltiples efectos secundarios ambiguos siempre ha sido indefinido. (En términos generales, por “efectos secundarios ambiguos y múltiples” nos referimos a cualquier combinación de operadores de incremento, decremento y asignación en una sola expresión que haga que el mismo objeto se modifique dos veces o se modifique y luego se inspeccione. Esta es una definición aproximada; vea la pregunta 3.8 para una pregunta precisa y la pregunta 11.33 para el significado de “indefinido”.) Ni siquiera intente averiguar cómo su comstackdor implementa tales cosas (al contrario de los ejercicios mal aconsejados en muchos libros de texto en C); como K&R señala sabiamente, “si no sabe cómo se hacen en varias máquinas, la inocencia puede ayudar a protegerlo”.

Referencias: K & R1 Sec. 2.12 p. 50; K y R2 Sec. 2.12 p. 54; ISO Sec. 6.3; H&S Sec. 7.12 pp. 227-9; CT&P Sec. 3.7 p. 47; PCS Sec. 9.5 pp. 120-1.

No es “por línea”, es “por punto de secuencia” que es similar a “por expresión” lo que parece ocurrir el resultado de pre y post incremento.

De hecho, el incremento siempre ocurre inmediatamente. La única variación es si el valor del término resultará en el valor inicial o posterior.

Para comprender completamente que C no está orientado a líneas, consulte el estándar y lea las partes sobre “puntos de secuencia”.

Las líneas que comienzan con ‘#’ son entradas de preprocesador. El preprocesador para C está orientado a la línea, pero, de lo contrario, C considera que los caracteres de salto de línea son iguales a los de cualquier otro espacio en blanco, como la pestaña o el espacio.