Una buena regla general es para cualquier cosa que necesite comparar en la condición de bucle contra algo que es naturalmente un std::size_tsí mismo.
std::size_tes el tipo de cualquier sizeofexpresión y, como se garantiza, puede expresar el tamaño máximo de cualquier objeto (incluida cualquier matriz) en C ++. Por extensión, también se garantiza que sea lo suficientemente grande para cualquier índice de matriz, por lo que es un tipo natural para un bucle por índice sobre una matriz.
Si solo cuenta hasta un número, entonces puede ser más natural usar el tipo de la variable que contiene ese número o un into unsigned int(si es lo suficientemente grande) ya que estos deberían ser de un tamaño natural para la máquina.
size_tcuando debería puede conducir a errores de seguridad .ssize_tvalores firmados.size_tes el tipo de resultado delsizeofoperador.Se usa
size_tpara variables que modelan el tamaño o el índice en una matriz.size_ttransmite semántica: inmediatamente sabe que representa un tamaño en bytes o un índice, en lugar de simplemente otro entero.Además, usar
size_tpara representar un tamaño en bytes ayuda a hacer que el código sea portátil.fuente
El
size_ttipo está destinado a especificar el tamaño de algo, por lo que es natural usarlo, por ejemplo, obtener la longitud de una cadena y luego procesar cada carácter:Usted no tiene que estar atento a las condiciones de contorno, por supuesto, ya que es un tipo sin signo. El límite en el extremo superior no suele ser tan importante ya que el máximo suele ser grande (aunque es posible llegar allí). La mayoría de las personas simplemente usan un
intpara ese tipo de cosas porque rara vez tienen estructuras o matrices que se vuelven lo suficientemente grandes como para exceder la capacidad de esoint.Pero ten cuidado con cosas como:
lo que causará un bucle infinito debido al comportamiento de ajuste de los valores sin signo (aunque he visto que los compiladores advierten sobre esto). Esto también puede ser aliviado por el (un poco más difícil de entender pero al menos inmune a los problemas de envoltura):
Al cambiar el decremento a un efecto secundario posterior a la verificación de la condición de continuación, esto verifica la continuación del valor antes del decremento, pero aún usa el valor decrementado dentro del bucle (por lo que el bucle se ejecuta en
len .. 1lugar delen-1 .. 0).fuente
strlena cada iteración de un bucle. :) Puedes hacer algo como esto:for (size_t i = 0, len = strlen(str); i < len; i++) ...for (size_t i = strlen (str); i --> 0;)-->operador "va a" (ver stackoverflow.com/questions/1642028/… ). Han incorporado su sugerencia en la respuesta.if (i == 0) break;al final del bucle (por ejemplo,for (size_t i = strlen(str) - 1; ; --i)(I como la suya mejor sin embargo, pero sólo me preguntaba si esto funcionaría igual de bien)..Por definición,
size_tes el resultado delsizeofoperador.size_tfue creado para referirse a los tamaños.La cantidad de veces que haces algo (10, en tu ejemplo) no se trata de tamaños, entonces ¿por qué usarlo
size_t?intounsigned intdebería estar bien.Por supuesto, también es relevante lo que haces
identro del bucle. Si lo pasa a una función que tomaunsigned int, por ejemplo, pickunsigned int.En cualquier caso, recomiendo evitar las conversiones de tipo implícito. Haga explícitas todas las conversiones de tipo.
fuente
size_tes una forma muy legible de especificar la dimensión de tamaño de un elemento: longitud de una cadena, cantidad de bytes que ocupa un puntero, etc. También es portátil en todas las plataformas: encontrará que 64 bits y 32 bits se comportan bien con las funciones del sistema ysize_t- algo queunsigned intpodría no hacer (por ejemplo, cuándo debe usarunsigned longfuente
respuesta corta:
casi nunca
respuesta larga:
Siempre que necesite tener un vector de carbón más grande que 2 gb en un sistema de 32 bits. En cualquier otro caso de uso, usar un tipo con signo es mucho más seguro que usar un tipo sin signo.
ejemplo:
El equivalente firmado de
size_tesptrdiff_t, noint. Pero el usointsigue siendo mucho mejor en la mayoría de los casos que size_t.ptrdiff_testálongen sistemas de 32 y 64 bits.Esto significa que siempre debe convertir ay desde size_t cada vez que interactúa con un std :: container, lo que no es muy bonito. Pero en una conferencia nativa en curso, los autores de c ++ mencionaron que diseñar std :: vector con un size_t sin signo fue un error.
Si su compilador le da advertencias sobre conversiones implícitas de ptrdiff_t a size_t, puede hacerlo explícito con la sintaxis del constructor:
si solo desea iterar una colección, sin límites, utilice el rango basado en:
aquí algunas palabras de Bjarne Stroustrup (autor de C ++) al volverse nativo
Para algunas personas, este error de diseño firmado / no firmado en el STL es motivo suficiente para no utilizar el std :: vector, sino una implementación propia.
fuente
for(int i = 0; i < get_size_of_stuff(); i++). Ahora, claro, es posible que no quieras hacer muchos bucles sin procesar, pero, vamos, también los usas.x + 1 < yequivalente ax < y - 1, pero no están con enteros no genéricos. Eso puede introducir errores fácilmente cuando se transforman cosas que se supone que son equivalentes.Use std :: size_t para indexar / contar matrices de estilo C.
Para los contenedores STL, tendrá (por ejemplo)
vector<int>::size_type, que debe usarse para indexar y contar elementos vectoriales.En la práctica, generalmente son ints sin signo, pero no está garantizado, especialmente cuando se usan asignadores personalizados.
fuente
std::size_tgeneralmente esunsigned long(8 bytes en sistemas de 64 bits) en lugar deunisgned int(4 bytes).size_tembargo, las matrices de estilo C no están indexadas , ya que los índices pueden ser negativos. Sin embargo, se podría usarsize_tpara la propia instancia de dicha matriz si no se quiere ser negativo.+en punteros, parece queptrdiff_tes el que se debe usar para los índices.vector<T>::size_type(y lo mismo ocurre con todos los otros contenedores), en realidad es bastante inútil, porque está garantizado efectivamente que essize_t- está tipificadoAllocator::size_type, y para restricciones sobre eso con respecto a los contenedores, ver 20.1.5 / 4 - en particular,size_typedebe sersize_tydifference_typedebe serptrdiff_t. Por supuesto, el valor predeterminadostd::allocator<T>cumple esos requisitos. Así que usa el más cortosize_ty no te molestes con el resto del lote :)Pronto, la mayoría de las computadoras serán arquitecturas de 64 bits con SO de 64 bits que ejecutan programas que operan en contenedores de miles de millones de elementos. A continuación, se debe utilizar
size_ten lugar deintcomo índice del bucle, de lo contrario su índice va a envolver alrededor de la 2 ^ 32: ésimo elemento, tanto en sistemas de 32 y 64 bits.¡Prepárate para el futuro!
fuente
long intlugar de unint. Sisize_tes relevante en un sistema operativo de 64 bits, era igual de relevante en un sistema operativo de 32 bits.Cuando use size_t tenga cuidado con la siguiente expresión
Obtendrá falso en la expresión if, independientemente del valor que tenga para x. Me tomó varios días darme cuenta de esto (el código es tan simple que no hice la prueba de la unidad), aunque solo me llevó unos minutos determinar el origen del problema. No estoy seguro de que sea mejor hacer un lanzamiento o usar cero.
Ambas formas deberían funcionar. Aquí está mi prueba de funcionamiento
La salida: i-7 = 18446744073709551614 (int) (i-7) = - 2
Me gustaría los comentarios de otros.
fuente
(int)(i - 7)trata de un flujo inferior que se convierteintdespués, mientrasint(i) - 7que no es un flujo inferior ya que primero convierteia anint, y luego resta7. Además, encontré su ejemplo confuso.size_t es devuelto por varias bibliotecas para indicar que el tamaño de ese contenedor no es cero. Lo usas cuando regresas: 0
Sin embargo, en el ejemplo anterior, hacer un loop en size_t es un error potencial. Considera lo siguiente:
El uso de enteros sin signo tiene el potencial de crear este tipo de problemas sutiles. Por lo tanto, prefiero usar size_t solo cuando interactúo con contenedores / tipos que lo requieren.
fuente
size_tes un tipo sin signo que puede contener el valor entero máximo para su arquitectura, por lo que está protegido contra desbordamientos de enteros debido al signo (el signo int0x7FFFFFFFincrementado en 1 le dará -1) o el tamaño corto (el signo corto sin signo int 0xFFFF incrementado en 1 le dará 0).Se utiliza principalmente en indexación de matrices / bucles / aritmética de direcciones, etc. Funciones como
memset()y por igualsize_tsolo aceptan , porque teóricamente puede tener un bloque de memoria de tamaño2^32-1(en la plataforma de 32 bits).Para tales bucles simples, no se moleste y use solo int.
fuente
size_t es un tipo integral sin signo, que puede representar el número entero más grande en su sistema. Úselo solo si necesita matrices muy grandes, matrices, etc.
Algunas funciones devuelven un size_t y su compilador le avisará si intenta hacer comparaciones.
Evite eso utilizando el tipo de datos firmado / sin firmar apropiado o simplemente escribiendo para un hack rápido.
fuente
size_t es unsigned int. así que cuando quieras int sin firmar puedes usarlo.
Lo uso cuando quiero especificar el tamaño de la matriz, el contador ect ...
fuente
size_tpuede ser un entero de 64 bits sin signo, mientras que en una máquina de 32 bits es solo un entero sin signo de 32 bits.