С++ uint, беззнаковое целое, целое

Привет, у меня есть программа, которая много работает с векторами и индексами элементов этих векторов, и мне было интересно:

  1. есть ли разница между uint и unsigned int
  2. что лучше использовать один из вышеперечисленных типов или просто использовать int, поскольку я читал, что некоторые люди говорят, что компилятор более эффективно обрабатывает значения int, но если бы я использовал int, мне пришлось бы всегда проверять отрицательные idxs, что является болью.
  3. как вы думаете, итераторы лучше? это более эффективно, чем обычное индексирование vectorx[idx]?

p.s. Программное обеспечение будет обрабатывать большие объемы данных, а хорошая производительность является обязательным требованием.


person Ismail Marmoush    schedule 23.08.2010    source источник


Ответы (4)


  1. C++ не определяет такого типа, как uint. Это должен быть «ваш» тип, то есть тип, определенный в вашем коде или какой-либо сторонней библиотеке. Можно догадаться, что это то же самое, что и unsigned int. Хотя может быть unsigned long int или что-то еще. В любом случае, вы должны проверить это сами.

  2. Это вопрос личного стиля. Я, например, считаю, что нужно использовать беззнаковые типы для представления естественно неотрицательных значений, таких как размеры или количества. Нет никакой разницы в производительности между подписанными и неподписанными типами, за исключением некоторых конкретных контекстов. Я бы сказал, что в большинстве случаев это беззнаковые типы, которые будут обрабатываться более эффективно.

  3. Итераторы делают реализации более общими, т. е. вы можете использовать итератор последовательного доступа и, таким образом, сделать вашу реализацию применимой к любой последовательной структуре данных. Используя индекс, вы предъявляете требование произвольного доступа к структуре данных, что является строгим требованием. Не рекомендуется предъявлять строгие требования, когда в них нет реальной необходимости.

person AnT    schedule 23.08.2010
comment
@AndreyT: Я не знаю, но я использую netbeans, компилятор GCC, и я уже написал код с uint, и он работает без каких-либо библиотек. Пункты 2 и 3 очень информативны, большое спасибо :) - person Ismail Marmoush; 24.08.2010
comment
uint определяется как сокращение для unsigned int большинством компиляторов. - person You; 24.08.2010
comment
В любом случае, это не меняет того факта, что такого типа, как uint, нет ни в C, ни в C++, поэтому, если не рассматривать конкретный компилятор, вопрос о uint не имеет осмысленного ответа. - person AnT; 24.08.2010
comment
@AndreyT, я бы также добавил, что вы не должны использовать ни unsigned int, ни unsigned long при работе с размерами контейнеров. По крайней мере, в С++, поскольку вопрос помечен, вы должны использовать size_t. - person Nathan Ernst; 24.08.2010
comment
@ Натан Эрнст: Неправда. Вы говорите о контейнерах в целом, верно? Вы не должны никогда использовать size_t с контейнерами вообще. Нет гарантии, что диапазон size_t достаточен для любого контейнера. size_t достаточно только для контейнеров на основе массива, но с учетом прочего. Кроме того, при работе со стандартными контейнерами следует использовать container_type::size_type, а не size_t. - person AnT; 24.08.2010
comment
Наконец, соответствующий тип для каждого данного конкретного контекста определяется этим конкретным контекстом, то есть вашим конкретным приложением. Легко может быть unsigned int или unsigned long. size_t подходит только в общих контекстах на основе массивов. - person AnT; 24.08.2010
comment
Производительность на самом деле должна быть точно такой же, благодаря тому, что они являются дополнением 2. - person RecursiveExceptionException; 04.03.2017
comment
@itzJanuary: Во-первых, беззнаковые типы не могут быть дополнением до 2. Дополнение 2 является знаковым представлением. Типы без знака используют чисто двоичную запись. Во-вторых, производительность меняется, когда вы выходите за рамки простого сложения и вычитания. Целочисленное деление является одним из очевидных примеров, когда производительность знаковых типов хуже, чем производительность беззнаковых (конечно, если аппаратная платформа не обеспечивает прямую поддержку ЦП для знакового деления в стиле C). - person AnT; 04.03.2017
comment
«Я бы сказал, что в большинстве случаев именно беззнаковые типы будут обрабатываться более эффективно». это не правильно. Перенос в C++ определен для беззнаковых, но не для целочисленных типов со знаком. Это означает, что компилятору иногда приходится вставлять дополнительные инструкции, чтобы добиться определенного поведения: -o?t=2361 - person Michael; 09.07.2017
comment
@Michael: Возможно, но в то же время C и C ++ требуют знакового деления в стиле Fortran, в то время как эффективные реализации на машинном уровне выполняют евклидово деление. Отсюда необходимость в дополнительных инструкциях для каждого подписанного деления. Я бы сказал, что это оказывает более негативное влияние. Кстати, когда именно компилятору придется вставлять дополнительные инструкции для беззнакового переноса? Можете ли вы описать это вместо предоставления ссылки на часовое видео? - person AnT; 09.07.2017
comment
@Ant: я не понимаю сборку x86, но, по-видимому, он увеличивает индекс массива uint32_t на 64-битной машине, и из-за поведения переполнения беззнаковых типов компилятору приходится каждый раз вставлять дополнительные инструкции для усечения до 32 бит. Извините за видео, я тоже ненавижу ссылки на видео, но, по крайней мере, они указывают правильное время. Что касается деления: есть ли разница между беззнаковым и подписанным? Насколько я понимаю, в любом случае это в основном определяется реализацией. - person Michael; 09.07.2017

Если вы перебираете вектор последовательно, во что бы то ни стало, используйте итератор. Существуют накладные расходы, связанные с индексированием, независимо от типа индекса, которых можно избежать путем итерации.

person TreDubZedd    schedule 23.08.2010

1) uint = unsigned int, на самом деле uint — это просто typedef для unsigned int (будет заменен на unsigned int во время компиляции).

2) Если вы хотите добавить в свой код некоторую «безопасность», используйте uint, вы точно избежите отрицательных значений.

3) Если вы прогоняете вектор последовательно, идите с итераторами, они оптимизированы для последовательного зацикливания (они какие-то указатели).

person Arslan    schedule 23.08.2010
comment
Недостаточно плохо для отрицательного голоса, но uint обычно будет typedef, а не макросом, и подписанное или неподписанное имеет мало общего с безопасностью (во всяком случае, это может вызвать ошибки безопасности, поскольку арифметика без знака работает не так, как ожидают многие программисты!) - person Tyler McHenry; 24.08.2010
comment
Вы правы для typedef (я изменю его). Под безопасностью я подразумеваю чувство безопасности для программиста, ничего не связанного с компилятором, поэтому я поставил - person Arslan; 24.08.2010

Как отметил другой автор, uint, вероятно, является typedef для unsigned int. Если вы используете Visual Studio, вы можете очень быстро проверить этот факт, нажав F12, когда текстовый курсор находится в uint, чтобы увидеть его определение. .

person HelloDog    schedule 06.10.2016