¿Qué hace el ,
operador en C?
c
operators
comma-operator
lillq
fuente
fuente
Respuestas:
La expresion:
Primero se evalúa la expresión1, luego se evalúa la expresión2 y se devuelve el valor de la expresión2 para toda la expresión.
fuente
i
los valores 5, 4, 3, 2 o 1. Es simplemente 0. Es prácticamente inútil a menos que las expresiones tengan efectos secundarios.i = b, c;
es equivalente a(i = b), c
porque porque la asignación=
tiene mayor prioridad que el operador de coma,
. El operador de coma tiene la precedencia más baja de todas.expression1, expression2;
primeroexpression1
se evalúa, presumiblemente por sus efectos secundarios (como llamar a una función), luego hay un punto de secuencia, luegoexpression2
se evalúa y se devuelve el valor ...He visto más utilizado en
while
bucles:Hará la operación, luego hará una prueba basada en un efecto secundario. La otra forma sería hacerlo así:
fuente
while (read_string(s) && s.len() > 5)
. Obviamente, eso no funcionaría siread_string
no tiene un valor de retorno (o no tiene un valor significativo). (Edit: Lo siento, no se dio cuenta qué edad tenía este post.)while (1)
con unabreak;
declaración en el cuerpo. Intentar forzar la parte de ruptura del código hacia arriba en la prueba while o hacia abajo en la prueba do-while, a menudo es un desperdicio de energía y hace que el código sea más difícil de entender.while(1)
ybreak
;El operador de coma evaluará el operando izquierdo, descartará el resultado y luego evaluará el operando derecho y ese será el resultado. El uso idiomático como se señala en el enlace es al inicializar las variables utilizadas en un
for
bucle, y da el siguiente ejemplo:De lo contrario, no hay muchos usos excelentes del operador de coma , aunque es fácil abusar de generar código que es difícil de leer y mantener.
Del borrador del estándar C99, la gramática es la siguiente:
y el párrafo 2 dice:
La nota a pie de página 97 dice:
lo que significa que no puede asignar el resultado del operador de coma .
Es importante tener en cuenta que el operador de coma tiene la prioridad más baja y, por lo tanto, hay casos en los que el uso
()
puede marcar una gran diferencia, por ejemplo:tendrá el siguiente resultado:
fuente
El operador de coma combina las dos expresiones a cada lado en una sola, y las evalúa en orden de izquierda a derecha. El valor del lado derecho se devuelve como el valor de toda la expresión.
(expr1, expr2)
es como,{ expr1; expr2; }
pero puede usar el resultado deexpr2
una llamada de función o asignación.A menudo se ve en
for
bucles para inicializar o mantener múltiples variables como esta:Aparte de esto, solo lo he usado "enfadado" en otro caso, al concluir dos operaciones que siempre deben ir juntas en una macro. Teníamos código que copiaba varios valores binarios en un búfer de bytes para enviarlos a una red, y manteníamos un puntero donde habíamos llegado a:
Donde los valores fueron
short
s oint
s lo hicimos:Más tarde leemos que esto no era realmente válido C, porque
(short *)ptr
ya no es un valor l y no se puede incrementar, aunque a nuestro compilador en ese momento no le importó. Para solucionar esto, dividimos la expresión en dos:Sin embargo, este enfoque se basó en que todos los desarrolladores recordaran poner ambas declaraciones todo el tiempo. Queríamos una función en la que pudieras pasar el puntero de salida, el valor y el tipo de valor. Siendo C, no C ++ con plantillas, no podíamos tener una función que tomara un tipo arbitrario, por lo que nos decidimos por una macro:
Al usar el operador de coma pudimos usar esto en expresiones o como declaraciones como deseábamos:
¡No estoy sugiriendo que ninguno de estos ejemplos tenga buen estilo! De hecho, me parece recordar el Código Completo de Steve McConnell que aconseja incluso no usar operadores de coma en un
for
bucle: para facilitar la lectura y la mantenibilidad, el bucle debe estar controlado por una sola variable y las expresiones en lafor
línea solo deben contener código de control de bucle, no otros bits adicionales de inicialización o mantenimiento de bucle.fuente
Provoca la evaluación de múltiples declaraciones, pero usa solo la última como valor resultante (valor, creo).
Entonces...
debería dar como resultado que x se establezca en 8.
fuente
Como han dicho las respuestas anteriores, evalúa todas las declaraciones pero usa la última como el valor de la expresión. Personalmente, solo lo he encontrado útil en expresiones de bucle:
fuente
El único lugar que he visto que es útil es cuando escribes un bucle funky donde quieres hacer varias cosas en una de las expresiones (probablemente la expresión init o la expresión de bucle. Algo así como:
Disculpe si hay algún error de sintaxis o si mezclé algo que no es estricto C. No estoy argumentando que el operador es una buena forma, pero para eso podría usarlo. En el caso anterior, probablemente usaría un
while
bucle en su lugar, por lo que las múltiples expresiones en init y loop serían más obvias. (E inicializaría i1 e i2 en línea en lugar de declarar y luego inicializar ... bla, bla, bla.)fuente
Estoy reviviendo esto simplemente para responder las preguntas de @Rajesh y @JeffMercado, que creo que son muy importantes, ya que este es uno de los principales éxitos del motor de búsqueda.
Tome el siguiente fragmento de código, por ejemplo
Imprimirá
El
i
caso se maneja como se explica en la mayoría de las respuestas. Todas las expresiones se evalúan en orden de izquierda a derecha, pero solo se asigna la últimai
. El resultado de la(
expresión )is
1`.El
j
caso sigue diferentes reglas de precedencia ya que,
tiene la precedencia de operador más baja. Debido a esas reglas, el compilador ve asignación de expresión, constante, constante ... . Las expresiones se evalúan nuevamente en orden de izquierda a derecha y sus efectos secundarios permanecen visibles, por lo tanto,j
es el5
resultado dej = 5
.Interesantemente,
int j = 5,4,3,2,1;
no está permitido por la especificación del idioma. Un inicializador espera una expresión de asignación, por lo,
que no se permite un operador directo .Espero que esto ayude.
fuente