在Scanf中使用&运算符

时间:2019-07-09 11:01:18

标签: c

当对数组使用scanf时,无论我是否使用'&'运算符,该函数都能正常工作。我想知道在字符数组

的情况下编译器如何看待'&'运算符

我已经知道scanf在使用单个字符时会传递指针。对于数组,变量本身将存储指向第一个元素的指针。 我的确切问题是,当我使用&ch(而ch是字符串)时,是否创建双指针?然后编译器如何运行

int main() 
{
    char ch,s[100],sen[100];
    scanf("%c",&ch);
    scanf("%s",s);
    scanf(" %[^\n]%*c",sen);

}

2 个答案:

答案 0 :(得分:0)

在这种情况下,关键字为array decay。编译器自动将数组转换为指向该数组第一个元素的指针。

在您的情况下,您必须传递一个指向scanf的指针。在第一行中,您通过ch运算符传递了&的地址。您还可以编写&Array[0]指向数组的第一个元素,或者编写Array,编译器会自动将其解析为&Array[0]

int main()
{
    char Array[1];

    scanf("%c", Array);

    printf("%p\n\r", &Array[0]);
    printf("%p\n\r", Array);

    return 0;
}

两个参数都是相同的地址。因此,在scanf的情况下,如果要从键盘获取单个整数或单个字符,请使用&运算符:

int value;
scanf("%d", &value);

如果您想接收一个char数组,则可以在不使用&运算符的情况下传递该数组,然后让编译器为您完成工作。

char Array[20];
scanf("%s", Array);

答案 1 :(得分:0)

  

在对数组使用scanf时,无论我是否使用'&'运算符,该函数都可以正常工作。

“似乎”是有效词。

除非它是// get stored value val myString = prefs.myString // store value prefs.myString = "My String Value" // get stored array val myStringArray = prefs.myStringArray // store array prefs.myStringArray = arrayOf("String 1","String 2","String 3") 或一元sizeof运算符的操作数,或者是用于在声明中初始化字符数组的字符串文字,否则 expression 为类型为&的N元素数组将被转换(“衰变”)为类型为“指向T的指针”的表达式,该表达式的值将为的第一个元素的地址数组。

如果您以以下方式致电T

scanf

表达式 scanf( "%s", s ); 从类型“ s的100个元素的数组(char)转换为“指向char [100]的指针” (char),其值是数组第一个元素(char *)的地址。

如果您以以下方式致电&s[0]

scanf

scanf( “%s”, &s ); 是一元s的操作数,因此不会发生转换,并且 expression &的类型为“指向100元素的指针” &s”(char)的数组。这是一个问题,因为char (*)[100]转换说明符期望使用%s类型的参数。传递任何其他类型的参数会导致未定义的行为-操作可能会按预期运行,或者可能完全崩溃,或者可能损坏数据,或者可能使程序处于不良状态,从而导致稍后崩溃,等等。

两个表达式char *s解析为相同的-数组的地址与它的第一个元素的地址相同-但它们的类型不同,并且在C中,不同的指针类型可能具有不同的表示形式(IOW,用于存储&s的地址值的方式可能不同于存储用于{{ 1}})。所以

char *

在某些平台上可能会失败。

  

我的确切问题是,当我使用&ch(而ch是字符串)时,我们是否会创建双指针?

不。如果将char (*)[100]声明为scanf( "%s", &s ); ,则ch的类型为char ch。如果将&ch声明为char *,则ch的类型为char ch[N]