2016-09-02 1 views
0

Я написал очень простой код c командой atoi и выполнил его., который может объяснить мне, почему эта команда atoi работает и как

void 
main 
(void) 
{ 
    int length; 

    length = atoi("Content: 111"); 
    printf("atoi(\"Content: 111\") = %d\n",length); 

    length = atoi("Content: 111" + 10); 
    printf("atoi(\"Content: 111\" + 10) = %d\n",length); 

    length = atoi("Content: 1" + 6); 
    printf("atoi(\"Content: 1\" + 6) = %d\n",length); 

    length = atoi("Content: 111" + 12); 
    printf("atoi(\"Content: 111\" + 12) = %d\n",length); 

    length = atoi("Content-aaaaaa:   111" + 20); 
    printf("atoi(\"Content-aaaaaa:   111\" + 20) = %d\n",length); 

    printf("\"aaa\"+7 = %s","aaa"+7); 
} 

Выход будет следующим:

atoi("Content: 111") = 0 
atoi("Content: 111" + 10) = 111 
atoi("Content: 1" + 6) = 0 
atoi("Content: 111" + 12) = 0 
atoi("Content-aaaaaa:   111" + 20) = 111 
"aaa"+7 = ; 

, как это возможно? почему atoi пропускает количество символов, которые я написал с помощью + int? Должна быть ошибка, нет? и почему последний printf также работал?

Я прочитал документацию и нет ничего об этом поведении:

INT atoi (Const символ * ул); Преобразование строки в целое число Разбор строки C, интерпретирующей ее содержимое как целое число, которое возвращается как значение типа int.

Функция сначала отбрасывает столько пробельных символов (как в isspace) по мере необходимости, пока не будет найден первый символ без пробелов. Затем, начиная с этого символа, берет необязательный начальный знак плюс или минус, за которым следует максимально возможное количество базовых 10 цифр, и интерпретирует их как числовое значение.

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

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

+3

это не имеет ничего общего с 'atoi', а скорее с указателем арифметики –

ответ

1

Рассмотрим, например, заявление

length = atoi("Content: 111" + 10); 

Это выражение

"Content: 111" + 10 

используется в качестве аргумента в вызове функции содержит так называемую арифметику указателей.

Строковый литерал "Content: 111", который имеет тип char[16], неявно преобразован в указатель на его первый символ, который получает тип char *. Затем к указателю добавляется целочисленное значение 10, которое дает смещение от начала строкового литерала.

Таким образом, выражение

"Content: 111" + 10 
     ^

указывает на отмеченной позиции в строке буквального.

Вы можете визуализации вызов функции следующим образом

char *tmp = "Content: 111"; 
tmp = tmp + 10; 
puts(tmp); // just for testing 
length = atoi(tmp); 

Функция пропускает ведущие пробельные символы, пока цифра или знак не будет встречаться и извлекает номер 111. Вот и все. :)

+0

Спасибо! большое объяснение! –

+0

@NinjaYo. Нет. Добро пожаловать.:) –

5

atoi обрабатывает целые числа, но также принимает символы ведущего пробела.

Остальное - простая арифметика указателей.

  • Когда вы "Content: 111" + 10 вы проходящее " 111" к atoi и она работает.
  • Когда вы "Content: 1" + 6 вы проходящее "t: 1 к atoi и возвращает 0.
  • "aaa"+7: не делайте этого: неопределенное поведение.
Смежные вопросы