c-这个函数在不使用任何指针的情况下是如何工作的



我正在尝试学习C,并通过K&R书。在线的许多示例似乎都使用指针来返回函数中的值。我会认为,同样的会被用于这个K&R功能:

/*
Reverse a string in place
*/
void reverse(char s[])
{
int c, i, j;
for (i = 0, j = strlen(s) - 1; i < j; i++, j--)
{
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
int main()
{
char s[] = "HELLO";
reverse(s);
printf("%s", s);
return (0);
}

我认为在这种情况下,字符串不会反转。然而,它按照作者最初的意图向后打印char数组。

它是怎么做到的?我还不完全理解指针,但我想它会像reverse(&s),然后是void reverse(char *s[]) {...}

数组作为参数传递给函数时,会衰减为指向其第一个元素的指针。因此,当您将任何类型的数组(包括字符串)传递到函数中时,实际上是通过引用传递它,并且在函数调用之后,对函数中的数组所做的任何修改都将反映在调用代码中。

检查此代码的输出以丰富您对指针和数组的理解:

#include <stdio.h>
#include <stdlib.h>
void foo(int *arg, size_t len)
{
size_t i;
printf("sizeof arg is %zun", sizeof arg);
for(i = 0; i < len; i++)
{
printf("arg[%zu] = %dn", i, arg[i]);
}
printf("arg's address is %pn", (void *) arg);
}
int main()
{
int array[10] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
printf("sizeof array is %zun", sizeof array);
printf("array begins at %p in memoryn", (void *) array);
foo(array, 10);
return 0;
}

由于在任何位置都不会复制字符串,因此必须通过reverse中的数组赋值来修改原始字符串。将void reverse(char s[])更改为void reverse(char *s)不会有任何改变。未知大小的数组的行为就像指向数组第一个元素的指针一样。

我还从K&R、 这是最好的书之一,尽管读过之后,会得到一本涵盖C99和C11的书。

如果你看看一书中的5.3节

5.3指针和阵列

他们写道:

当数组名称传递给函数时,传递的是初始元素的位置。在被调用的函数中自变量是局部变量,因此数组名称参数是指针,即包含地址的变量。

因此,尽管数组和指针不同,但当您将数组传递给函数时,它不会传递数组,而是传递指向第一个元素的指针。

一些区别:

数组名称和必须记住。指针是一个变量,所以pa=A和pa++是合法的。但是数组名称不是一个变量;类似a=pa和a的构造++是非法的。

关于K&R书。他们曾经提到过某件事,50页后他们就用了,除非你记得,否则它看起来就像是凭空而来的。他们在书中很少重复自己的话。

当作为参数传递给函数时,数组将隐式转换为指向数组第一个元素的指针。

这就是为什么原始数组的元素被修改而不是它的副本,因为没有制作数组的副本;只有第一个元素的地址。

最新更新