数组作为scanf函数参数。地址运营商

时间:2015-03-03 12:52:25

标签: c arrays pointers scanf variadic-functions

#include <stdio.h>

int main(void)
{
  char s[32];

example_1:
  scanf("%s", s);
  printf("%s\n", s);

example_2:
  scanf("%s", &s[0]);
  printf("%s\n", s);

example_3:
  scanf("%s", &s);
  printf("%s\n", s);
}
  1. 为什么#3与其他2的工作方式相同?

  2. #3有效吗?为什么呢?

2 个答案:

答案 0 :(得分:9)

  1. 变体一取决于array decay,因此有效。

    (在大多数情况下,数组衰减到指向其第一个元素的指针,例外是:地址 - (&s),sizeof s_Alignas(s)_Alignof(s)。)< / p>

  2. 变体2可以手动执行数组衰减并且更加冗长,因此更糟糕。

  3. 变体三严格Undefined Behavior,但它恰好适用于大多数实现 关键是&s在默认促销后不属于char*类型,但它指向正确的地址。

  4. 似乎工作是UB最危险的子集。

答案 1 :(得分:2)

虽然三者的类型不同:

  • schar[32](32个char s的数组),在需要的地方透明地衰减到char*
  • &s[0]char*(指向char
  • 的指针
  • &schar(*)[32](指向32 char s的数组的指针)

它们都解析为相同的值(字符数组的起始地址)。因此,当将其传递给期望printf的{​​{1}}时,所有3的结果都是相同的(假设char*的对象表示与char(*)[32]的对象表示相同{1}},这是依赖于实现的,但通常是这种情况。)

只有前两个有效 - 第三个只是偶然起作用。