#c #pointers
#c #указатели
Вопрос:
main()
{
char *x="girl";
int n,i;
n=strlen(x);
*x=x[n];
for(i=0;i<n;i )
{
printf("%s n",x);
x ;
}
}
Каков результат?
Пожалуйста, объясните результат…………………..
o / p — это :
irl
rl
l
Комментарии:
1. Результат = UB = Неопределенное поведение (u)r
2. Измените
char*x
наchar x[]
, чтобы избежать неопределенного поведения.3. @missingno: с кодом связано больше проблем UB; изменение строкового литерала связано не только
Ответ №1:
Результатом является неопределенное поведение. Вы изменили строковый литерал.
Комментарии:
1. … и вызвал переменную функцию без прототипа в области видимости; и не вернул значение из
main
(код не C99 (который принимал бы main без возврата), потому что C99 запрещает неявныйint
).2. @Adi: Вы только изменили слово в строке. Это не меняет UB.
Ответ №2:
Как указывали другие, написанная программа имеет неопределенное поведение.
Если вы внесете небольшое изменение:
char x[] = "girl";
тогда я считаю, что это законно и возможно объяснить. (РЕДАКТИРОВАТЬ: на самом деле с этим все еще есть проблемы. Это int main()
, и вы должны return 0;
закончить. Вам также необходимо, #include <string.h>
потому что вы используете strlen
, и #include <stdio.h>
потому что вы используете printf
.)
Строка
*x = x[n];
устанавливает x[0]
(т.Е. *x
) в x[4]
(которое, оказывается, является ограничителем строки ''
). Таким образом, первая строка, которая будет напечатана, — это пустая строка, потому что самый первый символ является завершителем строки.
Затем мы перебираем строку по одному символу за раз, печатая подстроки:
irl
rl
l
Ответ №3:
Хотя результатом является неопределенное поведение, как сказал DeadMG, давайте предположим, что вы объявили x как char x[] = "girl"
.
Вы присваиваете 4 значению n
(поскольку длина слова «девушка» равна 4), и вы присваиваете значение в x[4]
*x
(которое является x[0]
), но это значение равно » (нулевой ограничитель)
Теперь вы выполняете цикл и печатаете слово от x до следующего нулевого ограничителя, но в первый раз первый символ является нулевым ограничителем, поэтому вы ничего не получаете. после этого вы печатаете слово из увеличивающегося индекса.
g i r l 0
*x = x[4]:
0 i r l 0
^ ^ ^ ^
it1 it2 it3 it4 // << Where does x points to in each iteration of the for loop
Ответ №4:
Код вызывает определенные подозрения. *x=x[n]
пытается перезаписать литерал «girl», и эффект будет отличаться в зависимости от платформы и компилятора. Более корректно это должно быть объявлено как:
const char *x = "girl";
и тогда он не будет (не должен) компилироваться.
Комментарии:
1. Более правильно, он должен обеспечивать безопасность изменения строки, а не заставлять всю свою программу прерываться, проверяя компилятором исходную неизменяемость строки.
2. Да? Как правильнее написать код, который не будет компилироваться?
3. @Simon: это «более правильно» в том смысле, что это не позволит ему изменять строковый литерал; IOW, компилятор поймает ошибки такого рода для него.