想象一下,你在 C 中有一个初始化指针的函数:
void initialize(Pointer * p);
我会说参数 p 是一个 [out] 参数。
然后我们有一个函数可以获取 p 并对其进行操作。
void manipulate(Pointer * p)
现在我怀疑 p 是 [out] 还是 [in/out]。
我会说 [out] 因为我们只是在操纵它。我会说 [in/out] 因为进来的东西已经被初始化了。
我想知道哪一个是真的?
想象一下,你在 C 中有一个初始化指针的函数:
void initialize(Pointer * p);
我会说参数 p 是一个 [out] 参数。
然后我们有一个函数可以获取 p 并对其进行操作。
void manipulate(Pointer * p)
现在我怀疑 p 是 [out] 还是 [in/out]。
我会说 [out] 因为我们只是在操纵它。我会说 [in/out] 因为进来的东西已经被初始化了。
我想知道哪一个是真的?
声明中没有任何内容表明这一点。唯一真正的决定是函数中的代码做了什么。
在更现代的实现中,const
关键字可用于指示只读参数:
void manipulate(const Pointer * p)
这表示*p
不能在函数内赋值,所以它是只读(或in
)类型。但是,如果const
缺少,它仍然可以是只读的。
两者都不完全正确。
您正在传递一个指向函数的指针。所以它可以被认为是因为你传递了指针的value。此外,它可以被认为是out,因为您可能正在更改它的指针。
所以我不会相信这个理论。我会把它作为一个指针:)
标准 C 中没有直接输入/输出的概念。但是您可以通过定义自己的宏来实现。
实际上,所有参数传递仅通过 2 种方法完成。
1. pass by value
2. pass by address
这取决于你如何操作。如果您不想修改传入参数,请使用const
.
如果Pointer
类型本身不是一个实际的指针,比如typedef int *Pointer
,那么initialize
函数不能为参数分配内存。
在这种情况下,您必须将指针作为引用传递,即您必须传递指针的地址,这意味着函数应该将指向指针的指针作为参数:
void initialize(Pointer **p)
{
*p = malloc(sizeof(Pointer));
...
}
调用为
Pointer *p;
initialize(&p);
示例 1
char buf[256];
void manipulate(char * p)
{
strcpy(p,"Just test string");
}
int main()
{
manipulate(buf);
printf("%s\n",buf);
}
在上面的示例中,buf 字符串被初始化为静态缓冲存储器。这里的 manipulate
函数会将消息复制到缓冲存储器。
示例 2
char *buf;
void initialize(char **p)
{
*p = malloc(256*sizeof(char));
}
void manipulate(char * p)
{
strcpy(p,"Just test string");
}
int main()
{
initialize(&buf)
manipulate(buf);
printf("%s\n",buf);
}
在第二个示例中,buf 是指向未在定义中初始化的字符串的指针。这里的初始化函数initialize
将使用缓冲区,这就是我们使用它的原因,char **p
这意味着该函数将初始化指针的地址。如果我们*p
像在函数中那样传递变量,manipulate()
这意味着我们只能更改指针p
指向的内存的内容。