Чем указатель char отличается от указателя int в приведенном ниже коде?

#c #pointers

#c #указатели

Вопрос:

 1)
  int main()
  {
   int *j,i=0;
   int A[5]={0,1,2,3,4};
   int B[3]={6,7,8};
   int *s1=A,*s2=B;
   while(*s1   = *s2  )
   {
       for(i=0; i<5; i  )
          printf("%d ", A[i]);
   }
 }


2)
  int main()
  {
     char str1[] = "India";
     char str2[] = "BIX";
     char *s1 = str1, *s2=str2;
     while(*s1   = *s2  )
        printf("%s ", str1);
   }
  

Второй код работает нормально, тогда как первый код приводит к некоторой ошибке (возможно, ошибка сегментации). Но как переменная указателя s2 в программе 2 работает нормально (т.е. до конца строки), но не в программе 1, где она выполняется бесконечно….
Кроме того, во второй программе переменная s2 не будет увеличиваться сверх длины массива?

Ответ №1:

Особенность строк в C заключается в том, что у них есть специальный символ, который отмечает конец строки. Это '' символ. Этот специальный символ имеет нулевое значение.

Во второй программе имеющиеся у вас массивы включают символ-терминатор, и поскольку он равен нулю, он обрабатывается как «false» при использовании в логическом выражении (например, условие в вашем while цикле). Это означает, что ваш цикл во второй программе будет копировать символы вплоть до символа-терминатора включительно, но поскольку это «false», цикл завершится.

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

Таким образом, разница заключается не в том, как обрабатываются указатели, а в данных. Если вы добавите ноль в конец исходного массива в первой program ( B ), то он также будет работать хорошо.

Ответ №2:

В str2 вы назначили строку. Это означает, что будет конец строки (» или NULL), из-за чего, когда вы увеличите Str2 и он достигнет конца строки, он вернет null и, следовательно, ваш цикл прервется.

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

Ответ №3:

Иоахим дал хорошее объяснение терминального символа строки на языке C.

Еще одна вещь, о которой следует помнить при работе с указателем, — это арифметика указателей.

Арифметическая единица для указателя — это размер указываемого объекта.

С char * указателем с именем charPtr в системе, где char хранятся в 1 байте, выполнение charPtr увеличит значение в charPtr на * 1 (1 байт), чтобы он мог указывать на следующий символ в памяти.

С int * указателем с именем intPtr в системе, где int хранятся в 4 байтах, выполнение intPtr увеличит значение в IntPtr на 4 (4 байта), чтобы оно было готово указывать на следующий int в памяти.