这是一个查找特定字母出现的简单函数。
1: int count_x(char *p, char a)
2: {
3: int count = 0;
4: while(*p != '\0')
5: {
6: if (*p == a)
7: count++;
8: p++;
9: }
10: return count;
11: }
我们可以使用p[n]
访问特定元素,或者我们可以取消引用它*p
并获取该数组的第一个元素作为示例,以及我们通常所做的所有事情。
对我来说奇怪的是位于第8行。
当我们写p++
时,我们得到的数组从头开始传递-1符号。因此,如果它是hello, world
那么它将是ello, world
。
我们以某种方式通过索引进行迭代,但我并不真正理解如何。
我可以解释所有这些东西是如何工作的吗?
答案 0 :(得分:4)
循环条件*p != '\0'
表示:*迭代直到p
指向的值为'\0'
。循环体内的语句
p++;
将指针递增到传递的字符串的下一个字符。
第一次迭代
+--------+--------+--------+--------+--------+--------+--------+--- ----+--------+--------+--------+--------+
| | | | | | | | | | | | |
| 'h' | 'e' | 'l' | 'l' | 'o' | ',' | 'w' | 'o' | 'r' | 'l' | 'd' | '\0' |
| | | | | | | | | | | | |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
^
|
p
第二次迭代:
+--------+--------+--------+--------+--------+--------+--------+--- ----+--------+--------+--------+--------+
| | | | | | | | | | | | |
| 'h' | 'e' | 'l' | 'l' | 'o' | ',' | 'w' | 'o' | 'r' | 'l' | 'd' | '\0' |
| | | | | | | | | | | | |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
^
|
p
等等。当p
指向'\0'
时,条件*p != '\0'
变为false
并且循环终止。
在每次迭代时,指针p
都会改变它指向的位置。字符串保留在其初始存储位置。
答案 1 :(得分:1)
TL:DR - 使用指向数组的指针,我们遍历各个元素,就像我们使用数组索引一样。
将数组传递给函数时,它会衰减到指向第一个元素的指针。因此,char *p
指向数组中的第一个元素。
在这种情况下,函数需要一个以null结尾的char
数组(或指向以null结尾的char
数组的第一个元素的指针)作为第一个参数。
一旦增加p
,它就会指向下一个元素。这就是为什么,如果您尝试打印传入的字符串(实际上是"hello, world"
),它现在会打印"ello, world"
。
此外,通过选中*p != '\0'
,您确定不要越过数组(以空值终止)。
答案 2 :(得分:0)
表达式s[i]
(其中s是字符数组)按以下方式计算:s被转换为指向其第一个元素的指针,并应用所谓的指针算术。然后取消引用结果指针。
所以你可以用以下方式成像s[i]
char *p = s;
int i = 0;
p = p + i;
//...
if ( *p == a ) count++;
获取下一个你可写的角色
++i;
p = p + i;
//..
然而,这相当于
++p;
p = p + i;
其中i
具有以前的值。
所以你可以增加指针的索引。现在假设i
总是等于0。
然后你可以写
char *p = s;
int i = 0;
p = p + i;
//...
if ( *p == a ) count++;
++p;
p = p + 0;
if ( *p == a ) count++;
// and so on