何时将值隐式转换为指针?

时间:2013-01-30 17:34:13

标签: c arguments c99 argument-passing

我有很多功能,如:

void write(char* param, int len)
{
    //
}

我注意到我几乎从不使用&运算符作为参数。当我传递数组时:

char in[20];
write(in, 20);

我不需要它,但是当我传递一个值时:

write(5, 1);

我似乎不需要它,当我传递指针时:

char* in = malloc(20);
write(in, 20);

我也不需要它。那么在什么情况下我真的需要打电话:

write(&in, 1);

因为我很困惑:D

5 个答案:

答案 0 :(得分:4)

您确定第二种情况吗?它不能为我编译,应该是

char in = 5;
write(&in, 1);

答案 1 :(得分:2)

  

何时将值隐式转换为指针?

实际上,编译器可以隐式地将整数类型转换为指针。从理论上讲,这是非法的,接受它的编译器通常会发出警告:

example.c:2:6: warning: incompatible integer to pointer conversion initializing
               'void *' with an expression of type 'int'

在上面的示例中:

char in = 5;
write(in, 20);

char是一个整数类型,所以如果您的编译器允许它,可能被隐式转换为指针类型,尽管它不是C标准的一部分并且完全是编译器特异性。

请注意,标准允许使用强制转换将整数类型转换为指针类型,尽管结果是实现定义的:

char in = 5;
write((char *)in, 20);

唯一允许的隐式转换情况是整数常量0,表示空指针:

write(0, 20);    // allowed

请注意,整数常量本身是允许的,但值为0的整数类型的变量不是:

char in = 0;
write(in, 20);   // not allowed

至于其他人,当你传递一个指针时,你显然不需要&,因为它已经是一个指针。 When you pass an array, it decays to a pointer所以你也不需要&。在这两种情况下,使用它实际上都是非法的,因为上面的函数需要char *并分别使用char **char (*)[20]

答案 2 :(得分:1)

如果以某种方式将函数'write'的原型复制到调用此函数的文件中,如下所示。

void write(char *in, int len);

void foo(int bar){
   char in=5;
   write(in, 1);
}

您可能会收到警告。因为in不是指针,尽管5可以是地址。 我想如果您的程序已成功编译和链接,它将在运行时崩溃。

答案 3 :(得分:1)

使用; return_type function_name(prim_data_type* param...) param是一个指向内存中地址的指针,*param是该地址中的值。 答案是关于你想对这个param做什么。

char in[20];

说“ in ”是第一个元素的地址。所以在函数调用:

write(in, 20);

您要发送第一个元素的地址,因此在函数实现中,您可以通过*param访问第一个元素,使用*(param+1)param[1]访问第二个元素等。 你感到困惑的地方是:

char in = 5;
write(in, 1);

因为中是地址5(00000005),所以在执行该功能时,您将访问该位置,无论哪个值。你必须小心这样使用。

在malloc操作中:

char* in = malloc(20);
write(in, 20);

in 是一个指向地址的指针(第一个元素的地址),占用20个char元素可以占用空间。在函数中,您可以使用param指针访问所有元素(*param是第一个元素,*(param+7)param[7]是8.元素)

在结论中,当你想在另一个函数中使用主数据类型变量(int,float,char ..)时,你必须使用;

write(&in);

通过这样做,在函数的实现中,您可以访问该变量,将值更改为*param而不会产生混淆。

注意:为了更好地理解,这里简化了一些解释。这里将欢迎额外的警告。

答案 4 :(得分:0)

函数和数组在某些上下文中会衰减为指针。函数可以衰减为指向函数的指针,数组可以衰减成指向数组第一个元素的指针。没有其他类型的行为。

这个例子:

char in = 5; 
write(in, 1);

虽然错了。在这种情况下,你肯定需要&。你确定它的效果如此吗?