为什么不在第二个参数上进行类型检查而只在第一个参数上进行?

时间:2014-05-07 14:53:46

标签: c typechecking

在下面的代码中输入' a'价值为3.4(即浮动)它给我回答垃圾价值,甚至不允许我进入' b'价值,当我给出' a'价值为3和' b'价值为2.3(即浮动)它被接受并给我答案5而不是垃圾。

我的问题是为什么第二个参数没有进行类型检查;为什么只有第一个参数?

如果我给3,3.5代码工作更清楚但是为什么我不能输入3.5,3?

int sum(int k,int l)
{
  int s= k+l;
  return s;
}

void main()
{
  int a,b,k;
  printf("enter the numbers");
  scanf("%d",&a);
  scanf("%d",&b);
  k= sum(a,b);
  printf("the value of sum is %d", k);
}
PS:我在quora上看到了这个问题。我对那里提供的答案不满意。我认为这是提出这个问题的最好地方。

3 个答案:

答案 0 :(得分:2)

类型检查不是程序中的问题。类型检查在编译时发生;您看到的行为发生在运行时。 printfscanf和类似函数的编译时类型检查存在问题,我将在下面讨论,但这不适用于您的程序,它会传递正确类型的参数同时scanfprintf。不过,我将在下面讨论这个问题(因为我在仔细阅读你的问题之前写过这个问题)。

您拨打scanf两次以(尝试)读取两个int值。输入为3.4,这是floatdouble的有效输入。那么scanf对此做了什么?

带有scanf格式的

"%d"读取的输入格式类似于可选的有符号整数文字,当它看到任何与该格式不匹配的内容时停止。因此,第一个scanf只读取3并停在.。它不认为.可能是小数点,因为您没有要求它读取浮点值。 .不是错误,只是scanf("%d", ...)正在寻找的输入的结尾。

第二个scanf尝试读取另一个int值,但现在输入流中的第一个字符是.,它不能是有效整数字的一部分,所以它失败。 (检查scanf的返回值会告诉您;它会返回成功扫描的项目数。)

你应该总是检查输入函数返回的结果并编写代码来处理失败(即使只是通过用错误消息中止程序来处理它)。

更安全的读取数字输入的方法是使用fgets()一次读取整行,然后使用sscanf解析内存中的行。这也可能有问题,但它不会让以后的调用等待读取无效的输入字符(除非你有一个很长的输入行)。阅读fgetssscanf的文档以获取更多信息 - 再次,请务必检查它们返回的结果,以便检测输入错误。


printfscanf都是可变参数函数,这意味着它们可以接受可变数量和类型的参数。

例如,printf的声明是:

int printf(const char *format, ...);

这意味着对printf的调用中的第一个参数将根据参数类型进行检查,但在编译时不会检查零个或多个后续参数。这为您提供了极大的灵活性,但代价是编译=时间检查。几乎完全取决于您确保所有以下参数都是格式字符串指定的类型。如果传递错误类型的参数(例如printf("%d\n", 1.5)),则不一定会收到错误消息;相反,行为是未定义的。

scanf类似,但格式字符串的语义不同(大多数参数是指针而不是要打印的值)。

如果格式字符串是字符串文字,某些编译器(特别是gcc)将为您做额外的检查,但这不是必需的,其他编译器可能不会这样做。


顺便提一下,您发布的代码缺少必需的

#include <stdio.h>

void main()应为int main(void)。如果您正在使用建议使用void main()的书籍或教程,则可能是由不熟悉C语言的人编写的。找一个更好的。

答案 1 :(得分:1)

当scanf遇到变量&#39; a&#39;正如你所说的3.4。它以整数形式读取3并以小数形式停止。然后,.4将在下一次调用时读作双精度数。它在第二个输入是浮点数时有效,因为它会丢弃小数并且不会再次调用,因此会忽略其余的小数。 如评论中所述,请阅读有关scanf的内容并对代码进行一些更改。

答案 2 :(得分:-2)

我认为你应该添加&#34; getchar()&#34;在scanf方法之后,按Enter键时,&#39; / n&#39;会给 下一个参数。 这只是我的观点。

void main()
{
  int a,b,k;
  printf("enter the numbers");
  scanf("%d",&a);

  getchar();/* the /n is last in stdin*/

  scanf("%d",&b);
  k= sum(a,b);
  printf("the value of sum is %d", k);
}