- 运营商对char *做了什么?

时间:2012-03-12 00:51:55

标签: c string

我是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 个答案:

答案 0 :(得分:5)

由于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 - 1234,这是w"Hi, world"的索引。

ISO标准Additive operators)中的C99 6.5.6/9涵盖了这称为指针算法:

  

当减去两个指针时,两个指针都指向同一个数组对象的元素,或者指向数组对象的最后一个元素的元素;结果是两个数组元素的下标不同。

它提供了一种缩放方法,可以在同一个数组中计算差异,或者指向一个指向数组末尾的差异(其他所有内容都是未定义的)。

我的意思是用(例如)四字节整数进行指针运算,会在arr[7]arr[8]的地址之间给出 one 的区别,有些人可能认为不是四个。

buffer + i构造只是另一种说法&(buffer[i])的方式,即i数组buffer元素的地址。我实际上更喜欢后一种方法,因为它似乎在我试图表达的内容中更明确。

对于它的价值,这实际上并不是一个非常好的字符串替换代码。它有很多问题:

  • 如果没有进行替换,则会发生buffer的4K内存泄漏。
  • 在任何情况下,您都应该始终检查以确保malloc没有失败。
  • 你有可能像分配新字符串一样缓冲区溢出,你应该根据src searchreplace的长度进行分配。
  • 您可以使用单个sprintf ("%*.*s%s%s", i, i, src, replace, &(src[i + strlen (search)]));strcpy和两个strcat操作创建新字符串。混合两者似乎对我来说不协调。

答案 1 :(得分:1)

它是一个简单的指针算术。

buffer + ibuffer的子字符串,从i个字符开始[直到结尾]

p - src为您提供psrc之间的偏移。

答案 2 :(得分:1)

p只是一个指针 - 一个整数值。

+-运算符完全按照您的预期工作 - 它们递增或递减指针的值。

如果您认为字符串是一个连续的字符数组,那么您只是在谈论该字符串中的某个位置。

答案 3 :(得分:0)

阅读有关指针算术的更多信息。

+基本上char *

a=a+1  =>  a=(char *) ( (int)a + sizeof(char) )