C, указатель, строка

#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, компилятор поймает ошибки такого рода для него.