для цикла, дающего неожиданный результат в C - PullRequest
1 голос
/ 04 июля 2019

Я не могу понять следующее для цикла. Пожалуйста, помогите мне. Спасибо за ваше время. Я не могу понять, как цикл for становится истинным в первой итерации. если s [0] = "d", то как "d" будет трактоваться как "true".

#include <stdio.h>

int main()
{
    char s[] = "d";
    int i;
    for(i = 0; s[i]; i++)
        printf("%c %c %c %c",s[ i ], *(s+i), *(i+s), i[s]);
    return 0;
}
output : dddd

Ответы [ 3 ]

1 голос
/ 04 июля 2019

char s[] = "d"; объявляет строковый литерал, заканчивающийся нулем. В вашем цикле for условие прерывания равно s[i], что означает, что оно будет работать до тех пор, пока не достигнет символа NULL (который будет вторым символом).

1 голос
/ 04 июля 2019

char s[] = "d" инициализирует s массивом, содержащим символ 'd', за которым следует нулевой терминатор ('\0').

В начальной итерации цикла for мы проверяем s[0]чтобы определить, следует ли запустить цикл.Это проверяет первый символ s, который является 'd'.В C любой символ, кроме '\0', считается истинным, а '\0' считается ложным.(Это потому, что C обрабатывает символы, аналогичные целым числам, где 0 равно false, а любое другое int равно true.)

Таким образом, цикл for первоначально проверяет 'd', который является истинным значением, и запускает цикл.

На второй итерации он смотрит на s[1], то есть '\0'.Это ложное значение, поэтому цикл не запускается второй раз.

1 голос
/ 04 июля 2019

Согласно стандарту C (6.5.2.1 Массив подписки)

2 Постфиксное выражение, за которым следует выражение в квадратных скобках [] является подписанным обозначением элемента объекта массива. Определение индекса оператора [] заключается в том, что E1 [E2] идентичен к (* ((E1) + (E2))). Из-за правил преобразования, которые применяются к бинарный оператор +, если E1 является объектом массива (эквивалентно, указатель на начальный элемент объекта массива) и E2 является целым числом, E1 [E2] обозначает E2-й элемент E1 (считая с нуля).

Таким образом, s[i] эквивалентно *( s + i ), что с математической точки зрения эквивалентно *( i + s ) и в C может быть переписано как i[s], потому что в любом случае выражение считается как *( i + s ).

Таким образом, все эти конструкции

s[ i ] 
*(s+i) 
*(i+s) 
i[s]

эквивалентны в C и обозначают i-th элемент массива s.

Что касается вашего комментария к моему ответу

Не могли бы вы объяснить, как цикл for становится истинным во время начальная итерация?

затем массив s инициализируется строковым литералом "d".

char s[ ] = "d";

Строковый литерал включает в себя завершающий нулевой символ '\0'. Таким образом, приведенная выше декларация может быть эквивалентно переписана следующим образом:

char s[ ] = { 'd', '\0' };

Поскольку первый элемент массива не равен нулю (он равен символу 'd'), то условие s[i], эквивалентное условию s[i] != 0, истинно, когда i равно 0.

И цитата относительно оператора for (6.8.5 Итерационные операторы)

4 Итерационный оператор вызывает оператор, называемый телом цикла, повторяться до тех пор, пока управляющее выражение не сравнится до 0 . Повторение происходит независимо от того, является ли тело цикла вводится из оператора итерации или с помощью прыжка.1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...