una traductor termino que programacion lenguaje lectura expresión expresiones expresion ejemplos algebraico algebraicas algebraica c++ unsigned-integer

c++ - traductor - Una advertencia: comparación entre expresiones enteras con signo y sin signo



termino algebraico (5)

Ayer tuve exactamente el mismo problema trabajando con el problema 2-3 en Accelerated C ++. La clave es cambiar todas las variables que comparará (utilizando operadores booleanos) a tipos compatibles. En este caso, eso significa string::size_type (o unsigned int , pero dado que este ejemplo está usando el primero, string::size_type con eso aunque los dos sean técnicamente compatibles).

Tenga en cuenta que en su código original hicieron exactamente esto para el contador c (página 30 en la Sección 2.5 del libro), como ha señalado correctamente.

Lo que hace que este ejemplo sea más complicado es que las diferentes variables de relleno (padsides y padtopbottom), así como todos los contadores, también deben cambiarse a string::size_type .

Para llegar a tu ejemplo, el código que publicaste terminaría así:

cout << "Please enter the size of the frame between top and bottom"; string::size_type padtopbottom; cin >> padtopbottom; cout << "Please enter size of the frame from each side you would like: "; string::size_type padsides; cin >> padsides; string::size_type c = 0; // definition of c in the program if (r == padtopbottom + 1 && c == padsides + 1) { // where the error no longer occurs

Observe que en el condicional anterior, obtendría el error si no inicializara la variable r como una string::size_type en el bucle for . Así que necesitas inicializar el bucle for usando algo como:

for (string::size_type r=0; r!=rows; ++r) //If r and rows are string::size_type, no error!

Entonces, básicamente, una vez que introduce una variable string::size_type en la mezcla, cada vez que desee realizar una operación booleana en ese elemento, todos los operandos deben tener un tipo compatible para que se compile sin advertencias.

Actualmente estoy trabajando a través de Accelerated C ++ y he encontrado un problema en el ejercicio 2-3.

Una descripción general rápida del programa : el programa básicamente toma un nombre y luego muestra un saludo dentro de un marco de asteriscos, es decir, ¡Hola! Rodeado enmarcado por * ''s.

El ejercicio : en el programa de ejemplo, los autores utilizan const int para determinar el relleno (espacios en blanco) entre el saludo y los asteriscos. Luego le piden al lector, como parte del ejercicio, que le pida al usuario información sobre qué tan grande quiere que sea el relleno.

Todo esto parece bastante fácil, sigo pidiéndole al usuario dos enteros ( int ) y los guardo y cambio el programa para que use estos enteros, eliminando los utilizados por el autor, al compilar, aunque obtengo la siguiente advertencia;

Ejercicio2-3.cpp: 46: advertencia: comparación entre expresiones enteras con signo y sin signo

Después de algunas investigaciones parece ser que el código intenta comparar uno de los enteros anteriores ( int ) con una string::size_type , lo cual está bien. Pero me preguntaba: ¿significa esto que debo cambiar uno de los enteros a unsigned int ? ¿Es importante indicar explícitamente si mis enteros están firmados o no?

cout << "Please enter the size of the frame between top and bottom you would like "; int padtopbottom; cin >> padtopbottom; cout << "Please enter size of the frame from each side you would like: "; unsigned int padsides; cin >> padsides; string::size_type c = 0; // definition of c in the program if (r == padtopbottom + 1 && c == padsides + 1) { // where the error occurs

Arriba se muestran los bits relevantes del código, la c es de tipo string::size_type porque no sabemos cuánto tiempo puede string::size_type el saludo, pero ¿por qué obtengo este problema ahora, cuando el código del autor no tuvo el problema cuando lo usó? const int ? Además, a cualquier persona que haya completado C ++ acelerado , ¿se explicará más adelante en este libro?

Estoy en Linux Mint usando g ++ a través de Geany, si eso ayuda o hace una diferencia (como leí que podría al determinar qué string::size_type ).


En los rangos extremos, un int sin signo puede llegar a ser más grande que un int.
Por lo tanto, el compilador genera una advertencia. Si está seguro de que esto no es un problema, no dude en enviar los tipos al mismo tipo para que desaparezca la advertencia (use C ++ cast para que sean fáciles de detectar).

Alternativamente, haga que las variables sean del mismo tipo para evitar que el compilador se queje.
Quiero decir, ¿es posible tener un relleno negativo? Si es así, mantenlo como un int. De lo contrario, probablemente debería usar int sin signo y dejar que la transmisión detecte las situaciones en las que el usuario escribe un número negativo.


La diferencia importante entre los ints firmados y no firmados es la interpretación del último bit. El último bit en los tipos con signo representa el signo del número, es decir, por ejemplo:

0001 es 1 firmado y sin firmar 1001 es -1 firmado y 9 sin firmar

(¡Evité toda la cuestión del complemento por claridad de explicación! ¡Esto no es exactamente cómo se representan los ints en la memoria!)

Puede imaginar que es importante saber si se compara con -1 o con +9. En muchos casos, los programadores son demasiado perezosos para declarar contando ints como sin firmar (hinchando la cabeza de bucle for). Por lo general, no es un problema porque con ints tienes que contar hasta 2 ^ 31 hasta que tu bit de signo te muerda. Por eso es solo una advertencia. Porque somos demasiado perezosos para escribir ''unsigned'' en lugar de ''int''.


Por lo general, es una buena idea declarar las variables como unsigned o size_t si se compararán con los tamaños, para evitar este problema. Siempre que sea posible, use el tipo exacto con el que comparará (por ejemplo, use std::string::size_type cuando se compara con la longitud de un std::string ).

Los compiladores dan advertencias sobre la comparación de tipos con y sin signo porque los rangos de los ints con y sin signo son diferentes, y cuando se comparan entre sí, los resultados pueden ser sorprendentes. Si tiene que hacer una comparación de este tipo, debe convertir explícitamente uno de los valores a un tipo compatible con el otro, tal vez después de verificar que la conversión sea válida. Por ejemplo:

unsigned u = GetSomeUnsignedValue(); int i = GetSomeSignedValue(); if (i >= 0) { // i is nonnegative, so it is safe to cast to unsigned value if ((unsigned)i >= u) iIsGreaterThanOrEqualToU(); else iIsLessThanU(); } else { iIsNegative(); }


o usa esta biblioteca de encabezado y escribe:

// |notEqaul|less|lessEqual|greater|greaterEqual if(sweet::equal(valueA,valueB))

y no importa los tamaños firmados / no firmados o diferentes