简体   繁体   English

当c是char时使用scanf(“%d”,&c)会发生什么?

[英]What happens when using scanf(“%d”, &c) while c is a char?

the code is like this: 代码是这样的:

char c;  
scanf("%d", &c);  

inputting 3... 输入3 ...

My guess is that when 3 is inputted, it is as type int ; 我的猜测是,当输入3时,它的类型为int
and then type-demoted to char and assigned to c ; 然后将其降级为char并分配给c

I print the value of c in specifier %d yielding 3, seems to be as expected; 我在说明符%d打印c的值,结果为3,似乎与预期的一样;
but printing the value of c with specifier %c yields --a blank-- on the terminal;this is one question...(1); 但是用指定符%c打印c的值会在终端上显示-空白-这是一个问题...(1);
to test more I furthermore declare a variable ch with type char and initialized it like this: 为了测试更多,我还声明了一个类型为char的变量ch ,并像这样初始化它:

char ch = 1;  

and the test is like this: 测试是这样的:

(i&j)? printf("yes") : printf("no");  

and the result is "no" 结果为“否”
I print out the value of i&j , and it is 0 我打印出i&j的值,它是0
but 1&3 should be 1 ? 但是1&3应该是1 this is another question....(2); 这是另一个问题。...(2);
my question is (1) and (2) 我的问题是(1)和(2)

You're actually invoking undefined behavior doing that. 您实际上是在执行未定义的行为。

By using the format string %d , you're telling scanf to expect an int* as a parameter and you're passing it a pointer to a single character. 通过使用格式字符串%d ,您告诉scanf期望一个int*作为参数,并向其传递一个指向单个字符的指针。 Remember that scanf has no further type information on what you're passing it than what you're putting in the format string. 请记住,与传递格式字符串中的内容相比, scanf没有进一步的类型信息。

This will result in scanf attempting to write an int sized value to memory at an address that points to a char sized reservation, potentially (and for most architectures) writing out of bounds. 这将导致scanf尝试将一个int大小的值写入一个指向char大小的保留的地址的内存,这可能(对于大多数体系结构)超出范围。

After invoking UB, all bets are off on your further calculations. 调用UB后,您所有的计算都将关闭。

Suppose that scanf() were not a varargs-function, but a plain ordinary function taking a pointer-to-int as the 2nd argument: 假设scanf()不是varargs函数,而是一个以int指针作为第二个参数的普通普通函数:

int noscanf(char *format, int *ptr)
{
  *ptr = 42;
  return 1;
}

int main(void)
{
  char ch;
  int rc;

      // This should *at least* give a warning ...
  rc = noscanf("Haha!" , &ch); 

  return 0;
}

Now, scanf() is a varargs function. 现在,scanf() 一个varargs函数。 The only way for scanf() to determine the type of the (pointer) arguments is by inspecting the format string. scanf()确定(指针)参数类型的唯一方法是检查格式字符串。 And a %d means : the next argument is supposed to be a pointer to int. 一个%d表示:下一个参数应该是一个指向int的指针。 So scanf can happily write sizeof(int) bytes to *ptr. 因此scanf可以愉快地将sizeof(int)个字节写入* ptr。

I can't see a variable j there. 我在那里看不到变量j So i&j will be 0. And yes, if i == 1 and j == 3 then i & j == 1 . 因此, i&j将为0。是的,如果i == 1j == 3i & j == 1

(i&j)? (i&j)? printf("yes") : printf("no"); printf(“ yes”):printf(“ no”);
statement gives the output yes,for i=1 and j=3. 对于i = 1和j = 3,语句给出的输出为yes。

And for (1) question ASCII 3 is for STX char which is not printable. 对于(1)问题,ASCII 3表示不可打印的STX char。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM