数组形参的表达方式
设计一个有数组作为参数的函数,代表数组的形参有两种表达方式:指针 vs 数组名。从作用上来讲,两者完全相同,可以互换。但它们背后所隐含的区别更值得了解。
接下来,我们要自己设计并实现一个strlen()函数
,作用同标准库中的同名函数一样,即返回一个字符串的长度。
指针作为形参
size_t mystrlen(char *s)
{
int count = 0;
while (*(s++) != '\0') {
count++;
}
return count;
}
客户端程序如下:
size_t mystrlen(char *s);
int main(int argc, const char * argv[]) {
char x[] = "12345";
printf("%zd\n", mystrlen(x));
return 0;
}
- 首先,我们知道数组名虽然是
指向数组第一个元素的指针
,但这个指针永远不能被改变
,即不能指向其他对象(可以说是一个指针常量
)。而指针变量
则不同,它可以指向任意对应类型的对象。 - 其次,我们还知道在函数调用的过程中,
实参的值会被赋给形参
,被调用函数内部可以通过操作形参来操作实参的值。
由此可以得出,char x[]实际上是被赋给了char *s,即s = x;这样,函数内部就可以对s进行指针运算,让它指向不同的对象,就好像上面的代码s++
所做的一样,而x++
就不行。
所以,以下用法都是正确的:
mystrlen("Hello World!");
mystrlen(array);
mystrlen(ptr);
数组名作为形参
所有代码同上面一样,只是将形参char *s
改为char s[]
。两者完全通用,效果一致。但是前面不是说过作为指针的数组名不能改变吗?为什么在s是数组名的情况下,s++
依然正确呢?
- 首先,我们知道在声明数组的时候,必须明示数组的长度。例如
char x[100]
或char x[] = "abc"
。 - 其次,思考一下为什么作为形参时,可以写成
char x[]
呢?这是因为你不能将数组传给函数,只能传递指针。char x[]
作为形参的意义是:一个指向char型数组元素的指针。所以,即使将形参写作char x[100]
,也不代表形参是一个长度为100的数组。事实上,100会被忽略,x还是会被当作一个指针使用。