C中scanf()的格式说明符?

时间:2013-12-05 15:45:58

标签: c

为什么我们将格式说明符传递给C中的scanf()作为参数?

我的意思是,我们不能只做

scanf( &var ); // Here, var is any pre-declared variable.

可以从其声明中获取var的类型。为什么不允许这样做?

我认为以下代码浪费了内存。

scanf( "%d" , &var );

5 个答案:

答案 0 :(得分:3)

该类型不能从其声明"中获取。 scanf()没有什么神奇的东西,它只是一个功能。 C中的函数无法访问有关变量的元信息。

这就是为什么一般来说,声明函数参数包括它们的类型。对于scanf()之类的变量参数函数,第一个参数不是可选的,它用于以函数本身选择的某种方式描述其他参数的数量和类型。

答案 1 :(得分:2)

您显然需要阅读一些关于C编程的书籍,以便更好地理解核心概念。与其他一些语言不同,C并没有将I / O机制融入语言。 scanf()只是一个库函数,因此,这个函数无法自动知道它应该填充的变量的类型。

答案 2 :(得分:2)

因为%d只会指定var的类型,所以没有内存浪费。 scanf(&var)不起作用,因为该函数不是设计为以这种方式接受参数。

答案 3 :(得分:2)

你知道C中的变量可以是不同的类型:

  • int:Integer
  • char:Character
  • float:浮点数。
  • ...

与其他语言不同,C语言编译时无法隐式推断变量类型。这就是为什么总是声明变量的类型(例如:int a或char c)。

因为scanf只是C中的一个函数,并且因为C中的函数应该采用特定类型的参数,所以编码C的人决定使用以下格式:

     scanf("%d", &var) ; // for integers
     scanf("%c", &var); //for chars
     scanf("%f", &var); //for double and floats.

使用%d或%c不会浪费内存或任何内容。您可以将其视为指定输入变量类型的标志。

C的开发人员可以在没有%d,%c等的情况下做到这一点吗?是的,他们可以,但是,他们必须处理发送错误类型可能引起的所有可能的异常。

假设C的开发人员使用以下格式

    scanf(&var);

这非常简洁,但是你必须使用相同的语法来发送chars / int / double ...等等,然后函数scanf必须找出一种方法来决定变量的类型那是发送的。还记得我之前告诉过你的吗?变量类型不能在编译时隐式推断,因此,这项任务几乎是不可能的。

然而,他们可以为每种类型使用不同的scanf函数。例如:

    scanfInt(&var);     //for integers.
    scanfFloat(&var);   //for floats.
    ...
    ...

这样可以完美地工作,但是复制相同的scanf代码并使用不同的函数没有意义,因为类型不同。

那么解决方案是什么? ==>使用相同的函数名称(scanf),然后添加一个参数(%d,%f,%c ..),该参数将在内部用作C的标志以了解参数类型。

我希望你现在对%d,%f ....

的使用有了更好的理解

答案 4 :(得分:2)

这里有两个主要观点。

首先,我们坐在键盘上的人会写出类似的东西:

char var = '0';

我们知道这个变量的“类型”是char,我们可能打算在那里存储一个字符。一旦编译器获得了这一点,就会删除这些“人”元素,剩下的就是在某个内存位置保留1个字节,对代码中我们编写“var”的地方的进一步引用将与此内存位置进行交互。这就是所有编译器都知道的,没有理解预期的变量“type”。

其次,格式指定者不仅仅指示一个简单的类型。查看解释scanf()的任何页面,您将看到一个长列表,特别注意扫描集,否定扫描集和预期输入长度等内容。

假设我希望用户只输入一个数字,0-9,我不必只是假设他们将按照我的要求进行操作,我可以帮助确保他们将通过使用scanf()中的格式说明符:

int var = 0;
print("enter 1 digit (0-9):\n");
scanf("%1d", &var);

现在,无论他们输入多少位数,我都只会存储第一个数字。

如果您想要从用户那里读取一个字符串,并且想要阅读所有内容,直到您点击一个新行字符(读取空格),该怎么办?我们有很多选择,但scanf也可以这样做。读取字符串的“标准”是:

scanf("%s",some_string);

但是这会停留在任何空白字符上,所以你不希望scanf()在这种情况下做出假设,你希望能够使用特定的否定扫描集:

scanf("%[^\n]",some_string);