我是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;
}
答案 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 - 123
或4
,这是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
search
和replace
的长度进行分配。sprintf ("%*.*s%s%s", i, i, src, replace, &(src[i + strlen (search)]));
或strcpy
和两个strcat
操作创建新字符串。混合两者似乎对我来说不协调。答案 1 :(得分:1)
它是一个简单的指针算术。
buffer + i
是buffer
的子字符串,从i
个字符开始[直到结尾]
p - src
为您提供p
到src
之间的偏移。
答案 2 :(得分:1)
p
只是一个指针 - 一个整数值。
+
和-
运算符完全按照您的预期工作 - 它们递增或递减指针的值。
如果您认为字符串是一个连续的字符数组,那么您只是在谈论该字符串中的某个位置。
答案 3 :(得分:0)
阅读有关指针算术的更多信息。
+
基本上char *
:
a=a+1 => a=(char *) ( (int)a + sizeof(char) )