stringtranslate.com

Operadores en C y C++

Esta es una lista de operadores en los lenguajes de programación C y C++ . Todos los operadores (excepto typeof ) enumerados existen en C++; la columna "Incluido en C" indica si un operador también está presente en C. Tenga en cuenta que C no admite la sobrecarga de operadores .

Cuando no está sobrecargado, para los operadores &&, ||y ,(el operador de coma ), hay un punto de secuencia después de la evaluación del primer operando.

C++ también contiene los operadores de conversión de tiposconst_cast , static_cast, dynamic_casty reinterpret_cast. El formato de estos operadores implica que su nivel de precedencia no es importante.

La mayoría de los operadores disponibles en C y C++ también están disponibles en otros lenguajes de la familia C, como C# , D , Java , Perl y PHP , con la misma precedencia, asociatividad y semántica.

Mesa

Para los fines de estas tablas, a, b, y crepresentan valores válidos (literales, valores de variables o valor de retorno), nombres de objetos o valores l, según corresponda. R, Sy Trepresentan cualquier tipo y Kun tipo de clase o tipo enumerado. Algunos de los operadores tienen ortografías alternativas que utilizan dígrafos y trígrafos o sinónimos de operador.

Operadores aritméticos

Todos los operadores aritméticos existen en C y C++ y pueden sobrecargarse en C++.

Operadores de comparación/operadores relacionales

En C++, todos los operadores de comparación se pueden sobrecargar. Desde C++20 , el operador de desigualdad se genera automáticamente si operator==se define y los cuatro operadores relacionales se generan automáticamente si operator<=>se define. [1]

Operadores lógicos

Todos los operadores lógicos existen en C y C++ y pueden sobrecargarse en C++, aunque no se recomienda la sobrecarga de los operadores lógicos AND y OR, porque como operadores sobrecargados se comportan como llamadas de función ordinarias, lo que significa que ambos operandos se evalúan, por lo que pierden su propiedad de evaluación de cortocircuito, tan utilizada y esperada . [2]

Operadores bit a bit

Todos los operadores bit a bit existen en C y C++ y pueden sobrecargarse en C++.

Operadores de asignación

Todas las expresiones de asignación existen en C y C++ y pueden sobrecargarse en C++.

Para los operadores dados, la semántica de la expresión de asignación combinada incorporada a ⊚= bes equivalente a a = a ⊚ b, excepto que ase evalúa solo una vez.

Operadores de miembro y puntero

Otros operadores

Notas:

  1. ^ El operador de módulo funciona sólo con operandos enteros, para números de punto flotante se debe utilizar una función de biblioteca (como fmod).
  2. ^ Acerca de la comparación de tres vías en C++20
  3. ^ ab En el contexto de iostreams en C++, los escritores a menudo se referirán a <<y >>como los operadores "put-to" o "inserción de flujo" y "get-from" o "extracción de flujo", respectivamente.
  4. ^ ab Según el estándar C99, el desplazamiento a la derecha de un número negativo está definido por la implementación. La mayoría de las implementaciones, por ejemplo, GCC, [3] utilizan un desplazamiento aritmético (es decir, extensión de signo), pero es posible un desplazamiento lógico .
  5. ^ La dirección real de un objeto con una sobrecarga operator &se puede obtener con std::addressof
  6. ^ El tipo de retorno de debe ser un tipo para el cual se pueda aplicar la operación, como un tipo de puntero. Si es del tipo donde se sobrecarga , se expande a .operator->()->xCCoperator->()x->yx.operator->()->y
  7. ^ Meyers, Scott (octubre de 1999), "Implementación del operador->* para punteros inteligentes" (PDF) , Dr. Dobb's Journal , Aristeia.
  8. ^ Aunque existe un ::signo de puntuación en C a partir de C23, no se utiliza como operador de resolución de alcance.
  9. ^ Acerca de los literales definidos por el usuario de C++11
  10. ^ Los paréntesis no son necesarios cuando se toma el tamaño de un valor, solo cuando se toma el tamaño de un tipo. Sin embargo, se suelen utilizar de todas formas. [ cita requerida ]
  11. ^ C++ define alignofel operador, mientras que C define _Alignof(C23 define ambos). Ambos operadores tienen la misma semántica.
  12. ^ El nombre del tipo también se puede inferir (por ejemplo new auto) si se proporciona un inicializador.
  13. ^ El tamaño de la matriz también se puede inferir si se proporciona un inicializador.

Precedencia de operadores

La siguiente es una tabla que enumera la precedencia y asociatividad de todos los operadores en los lenguajes C y C++ . Los operadores se enumeran de arriba a abajo, en orden de precedencia descendente. La precedencia descendente se refiere a la prioridad de la agrupación de operadores y operandos. Considerando una expresión, un operador que está enumerado en alguna fila se agrupará antes que cualquier operador que esté enumerado en una fila más abajo. Los operadores que están en la misma celda (puede haber varias filas de operadores enumerados en una celda) se agrupan con la misma precedencia, en la dirección dada. La precedencia de un operador no se ve afectada por la sobrecarga.

La sintaxis de las expresiones en C y C++ se especifica mediante una gramática de estructura de frase . [7] La ​​tabla que se proporciona aquí se ha inferido de la gramática. [ cita requerida ] Para el estándar ISO C 1999, la nota 71 de la sección 6.5.6 establece que la gramática de C proporcionada por la especificación define la precedencia de los operadores de C, y también establece que la precedencia de los operadores resultante de la gramática sigue de cerca el orden de las secciones de la especificación:

" La sintaxis [es decir, la gramática] [C] especifica la precedencia de los operadores en la evaluación de una expresión, que es la misma que el orden de las subcláusulas principales de esta subcláusula, la precedencia más alta primero". [8]

Una tabla de precedencia, aunque en su mayor parte es adecuada, no puede resolver algunos detalles. En particular, observe que el operador ternario permite cualquier expresión arbitraria como su operando intermedio, a pesar de estar listado como de mayor precedencia que los operadores de asignación y coma. Por lo tanto , a ? b, c : dse interpreta como a ? (b, c) : d, y no como el sin sentido (a ? b), (c : d). Por lo tanto, la expresión en el medio del operador condicional (entre ?y :) se analiza como si estuviera entre paréntesis. Además, observe que el resultado inmediato, sin paréntesis, de una expresión de conversión de C no puede ser el operando de sizeof. Por lo tanto, sizeof (int) * xse interpreta como (sizeof(int)) * xy no como sizeof ((int) * x).

[9] [10] [11]

Notas

La tabla de precedencia determina el orden de enlace en expresiones encadenadas, cuando no se especifica expresamente mediante paréntesis.

Precedencia y vinculaciones

A muchos de los operadores que contienen secuencias de múltiples caracteres se les asignan "nombres" construidos a partir del nombre del operador de cada carácter. Por ejemplo, +=y -=se suelen llamar plus equal(s) y minus equal(s) , en lugar de los más verbosos "asignación por adición" y "asignación por sustracción". La vinculación de operadores en C y C++ se especifica (en los estándares correspondientes) mediante una gramática de lenguaje factorizada, en lugar de una tabla de precedencia. Esto crea algunos conflictos sutiles. Por ejemplo, en C, la sintaxis para una expresión condicional es:

expresión lógica - OR - expresión ? expresión : expresión condicional    

Mientras que en C++ es:

expresión lógica - OR - expresión ? expresión : asignación - expresión    

De ahí la expresión:

e = a < d ? a++ : a = d

se analiza de forma diferente en los dos lenguajes. En C, esta expresión es un error de sintaxis, porque la sintaxis para una expresión de asignación en C es:

unario - expresión '=' asignación - expresión  

En C++, se analiza como:

e = ( a < d ? a ++ : ( a = d ))          

lo cual es una expresión válida. [12] [13]

Si desea utilizar una coma como operador dentro de un único argumento de función, asignación de variable u otra lista separada por comas, debe utilizar paréntesis, [14] [15] por ejemplo:

int a = 1 , b = 2 , variableRara = ( ++ a , b ), d = 4 ;             

Crítica de la precedencia de operadores bit a bit y de igualdad

Se ha criticado la precedencia de los operadores lógicos bit a bit. [16] Conceptualmente, & y | son operadores aritméticos como * y +.

La expresión se analiza sintácticamente como mientras que la expresión se analiza como . Esto requiere que los paréntesis se utilicen con más frecuencia de lo que se haría de otra manera.a & b == 7a & (b == 7)a + b == 7(a + b) == 7

Históricamente, no había distinción sintáctica entre los operadores lógicos y de bits. En BCPL , B y principios de C, los operadores no existían. En cambio, tenían un significado diferente según se usaran en un "contexto de valor verdadero" (es decir, cuando se esperaba un valor booleano, por ejemplo, en se comportaba como un operador lógico, pero en se comportaba como un operador de bits). Se mantuvo para mantener la compatibilidad con versiones anteriores de las instalaciones existentes. [17]&& ||& |if (a==b & c) {...}c = a & b

Además, en C++ (y versiones posteriores de C) las operaciones de igualdad, con la excepción del operador de comparación de tres vías, producen valores de tipo bool que conceptualmente son un solo bit (1 o 0) y, como tales, no pertenecen propiamente a operaciones "bit a bit".

Sinónimos de operadores de C++

C++ define [18] ciertas palabras clave que actúan como alias para varios operadores:

Estos pueden usarse exactamente de la misma manera que los símbolos de puntuación que reemplazan, ya que no son el mismo operador bajo un nombre diferente, sino más bien simples reemplazos de tokens para el nombre (cadena de caracteres) del operador respectivo. Esto significa que las expresiones (a > 0 and not flag)y (a > 0 && !flag)tienen significados idénticos. También significa que, por ejemplo, la bitandpalabra clave puede usarse para reemplazar no solo al operador y bit a bit sino también al operador de dirección de , e incluso puede usarse para especificar tipos de referencia (por ejemplo, int bitand ref = n). La especificación ISO C permite estas palabras clave como macros de preprocesador en el archivo de encabezado iso646.h. Para compatibilidad con C, C++ también proporciona el encabezado iso646.h, cuya inclusión no tiene efecto. Hasta C++20, también proporcionaba el encabezado correspondiente ciso646que tampoco tenía efecto.

Véase también

Referencias

  1. ^ "Sobrecarga de operadores§Operadores de comparación". cppreference.com .
  2. ^ "C++ estándar".
  3. ^ "Implementación de números enteros", GCC 4.3.3, GNU.
  4. ^ "Especificación ISO/IEC 9899:1999, TC3" (PDF) . p. 64, § 6.4.6 Ponctuators párr. 3.
  5. ^ "conversión definida por el usuario" . Consultado el 5 de abril de 2020 .
  6. ^ Conversión de tipos explícita en C++
  7. ^ Lenguajes de programación ISO/IEC 9899:201x - C . open-std.org – El Comité de Normas C. 19 de diciembre de 2011. p. 465.
  8. ^ Norma ISO C 1999, apartado 6.5.6 nota 71 (Informe técnico). ISO. 1999.
  9. ^ "Precedencia de operadores C - cppreference.com". en.cppreference.com . Consultado el 16 de julio de 2019 .
  10. ^ "Operadores integrados de C++, precedencia y asociatividad". docs.microsoft.com . Consultado el 11 de mayo de 2020 .
  11. ^ "Precedencia de operadores de C++ - cppreference.com". en.cppreference.com . Consultado el 16 de julio de 2019 .
  12. ^ "Precedencia de operadores C - cppreference.com". en.cppreference.com . Consultado el 10 de abril de 2020 .
  13. ^ "¿El operador ternario de C/C++ tiene realmente la misma precedencia que los operadores de asignación?". Stack Overflow . Consultado el 22 de septiembre de 2019 .
  14. ^ "Otros operadores - cppreference.com". es.cppreference.com . Consultado el 10 de abril de 2020 .
  15. ^ "c++ - Cómo funciona el operador de coma". Desbordamiento de pila . Consultado el 1 de abril de 2020 .
  16. ^ Historia de C § Neonatal C, Laboratorios Bell.
  17. ^ "Re^10: siguiente a menos que se cumpla la condición". www.perlmonks.org . Consultado el 23 de marzo de 2018 .
  18. ^ ISO/IEC 14882:1998(E) Lenguaje de programación C++ . open-std.org – El Comité de estándares C++. 1 de septiembre de 1998. págs. 40–41.

Enlaces externos