что оператор - делает с char *? - PullRequest
0 голосов
/ 12 марта 2012

Я новичок в C. Я читаю алгоритм поиска-замены для C, и я немного запутался, что операторы - & + делают в этом коде:

char *replace(char * src, const char * search, const char * replace) {
   char * buffer = malloc(4096);  //allocate 4096 bytes in memory to new string
   char * p; //substring of my search in the src string
   int i;

   p = strstr(src, search);
   if ( NULL == p ) return src; if // 'search' not found on 'src' return src
      i =  p - src; //index of my substring

   strncpy(buffer, src, i); //copy the substring value to buffer
   sprintf(buffer + i, "%s%s", replace, 
   p + strlen(search)); // ???

   return buffer;
}

Ответы [ 4 ]

5 голосов
/ 12 марта 2012

Поскольку p - это местоположение в вашем массиве символов (строка), а src - его начало,

i = p - src;

установит i на индекс, по которому p указывает.

Например, рассмотрим следующую схему памяти:

 [0] [1] [2] [3] [4] [5] [6] [7] [8]  [9]  <-- Indexes
 123 124 125 126 127 128 129 130 131  132  <-- Addresses
+---+---+---+---+---+---+---+---+---+----+
| H | i | , |   | w | o | r | l | d | \0 |
+---+---+---+---+---+---+---+---+---+----+
  ^               ^
  |               |
 src              p

В этом случае p - src даст вам 127 - 123 или 4, что является индексом w в пределах "Hi, world".

Эта так называемая арифметика указателей описана в Additive operators в стандарте ISO (C99 6.5.6/9):

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

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

Под этим подразумевается, что выполнение арифметики с указателями (например) с четырехбайтовыми целыми числами даст вам разницу один между адресами arr[7] и arr[8], а не четырьмя, как некоторые могут думаю.

Конструкция buffer + i - это просто другой способ сказать &(buffer[i]), адрес i-го элемента массива buffer. Я на самом деле предпочитаю последний метод, поскольку он кажется более явным в том, что я пытаюсь представить.

На самом деле это не очень хороший код для замены строк. У него множество проблем:

  • если замены не сделаны, у вас утечка памяти 4K с buffer.
  • в любом случае вы должны всегда проверить, чтобы убедиться, что malloc не потерпел неудачу.
  • у вас есть возможность переполнения буфера при размещении новой строки, вы должны действительно распределить, основываясь на длинах src search и replace.
  • Вы можете создать новую строку с одной sprintf ("%*.*s%s%s", i, i, src, replace, &(src[i + strlen (search)])); или strcpy и двумя strcat операциями. Смешивание этих двух кажется мне неуместным.
1 голос
/ 12 марта 2012

p это просто указатель - целочисленное значение.

Операторы + и - работают точно так, как вы ожидаете - они увеличивают или уменьшают значение указателя.

Если вы думаете о строках как о непрерывном массиве символов, вы просто говорите о местоположении в этой строке.

1 голос
/ 12 марта 2012

это простая арифметика указателей.

buffer + i - это подстрока buffer, которая начинается с i-го символа [до конца]

p - srcдает вам смещение от p до src.

0 голосов
/ 12 марта 2012

Подробнее об арифметике указателей.

В основном + для char *:

a=a+1  =>  a=(char *) ( (int)a + sizeof(char) )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...