Ваша функция имеет бесконечный цикл: так как i
без знака, i >= 0
всегда верно.
Это может быть улучшено различными способами:
Вы должны вычислить длину str
только один раз. strlen()
недешево, он должен сканировать строку, пока не найдет нулевой терминатор. Компилятор не всегда способен оптимизировать избыточные вызовы для одного и того же аргумента.
power
можно вычислять постепенно, избегая необходимости во вложенном цикле.
вам не следует использовать имя atoi
, так как это стандартная функция в библиотеке C. Если вы не реализуете его спецификацию точно и правильно, вы должны использовать другое имя.
Вот исправленная и улучшенная версия:
unsigned long long int atoi_power(const char str[]) {
size_t i, len = strlen(str);
unsigned long long int power = 1, num = 0;
for (i = len; i-- > 0; ) {
num += (str[i] - '0') * power;
power *= 10;
}
return num;
}
Измененная таким образом, функция должна иметь производительность, аналогичную версии atoi_imp
. Обратите внимание, что они не реализуют одну и ту же семантику. atoi_pow
должна быть задана строка цифр, тогда как atoi_imp
может содержать завершающие символы.
На самом деле ни atoi_imp
, ни atoi_pow
не реализуют спецификацию atoi
, расширенную для обработки больших целых чисел без знака:
atoi
игнорирует любые начальные пробельные символы,
atoi
принимает необязательный знак, либо '+'
, либо '-'
.
atoi
использует все последующие десятичные цифры, поведение при переполнении не определено.
atoi
игнорирует и завершает символы, которые не являются десятичными цифрами.
Учитывая эту семантику, естественная реализация или atoi
- это реализация atoi_imp
с дополнительными тестами. Обратите внимание, что даже strtoull()
, который вы можете использовать для реализации своей функции, обрабатывает пробелы и необязательный знак, хотя преобразование отрицательных значений может дать удивительные результаты.