#include "stdio.h"
int main(){
char c1,c2;
scanf("%d %d",&c1,&c2);
printf("%d %d %p %p\n",c1,c2,&c1,&c2);
printf("%u %u %u %u\n",c1,c2,&c1,&c2);
return 0;
}
dev-c++
vs2010
解释一下操作流程,为什么打印这个值,现在有点懵。
比如先压栈c2,其次c1,scanf操作流程和printf过程,
根据楼下回复。推理如下
对于这个问题,你首先需要弄清楚的有几个知识点:
一是各个数据的数据长度,char 占用 1个字节,而你scanf输入的是一个整数,占用4个字节。
二是windows内存对齐机制。
三是内存的大端模式和小端模式。
参考网址:https://blog.csdn.net/yangcs2009/article/details/39698997
就拿你输入的159594为例,scanf会从char字符的地址开始写入四个字节的数据,四个字节的二进制表示100110111101101010,而printf读取char字符的地址开始的一个字节数据106,二进制为1101010,正好与输入的数字的最后几个二进制相同。
跟定义类似有关系把,你把CHAR c1 改成 int 试试看
1.对于printf()来说,编程时应想方设法编写好它的格式控制串,以便使输出数据看起来整齐;而对于scanf() 来说,格式控制串越简洁越好。编写的格式控制串越复杂,用户(在运行此程序并进行)输入时要敲击的键 就越多,除了给用户增添麻烦外,对用户的输入工作毫无帮助。可以对输入数据的操作起说明作用的是,在 scanf()调用前,添加一条printf()调用语句。 例如,如果写了: scanf("请输入你的年龄%d",&year); 这样的语句,用户就必须在程序运行时,面对漆黑的显示器屏幕,从键盘输入: 请输入你的年龄 这几个汉字,然后再输入数值19并按回车键,告诉程序你自己是19岁。在“请输入你的年龄”这几个汉字 与输入19这个数值之间,还不能敲击空格键或Tab键。 这个问题比较好的解决方案如下: printf("请输入你的年龄/n"); scanf("%d",&year); 在程序运行时,程序先在屏幕上显示“请输入你的年龄”这样的提示,然后换行,程序暂停于此,等待用户 输入年龄。在输入19并按回车键后,程序才会继续运行。 2.printf()的输出项既可以使变量,也可以是常量和表达式;而对于scanf()中的输入项来说,不可以是数值常量,也不可以是表达式,还不可以是普通的变量。其输入项只能是某个变量的首地址(通过对这个变量用取地址运算符,比如&a)或者指针变量(以及数组名)。
跟定义类似有关系把,你把CHAR c1 改成 int 试试看
把CHAR c1 改成 int型,再试试看呢
char c1,c2; 注释:申明C1 和C2 是字符类型(char)的变量
scanf("%d %d",&c1,&c2); 注释:从键盘以整数格式(%d) 读入变量C1和C2
printf("%d %d %p %p\n",c1,c2,&c1,&c2); 注释:以整数格式(%d)输出 C1和C2,以及C1和C2的指针变量的值(%p 即,存储的地址),\n 是换行
printf("%u %u %u %u\n",c1,c2,&c1,&c2); 注释:以十进制无符号数格式(%u)输出 C1和C2,以及取C1和C2的地址符(&)输出
return 0;
因为c1 c2都是char类型,而char其实就是1字节的无符号整型,编译器在给变量分配内存空间的时候通常都是连续分配空间,
所以如果c1内存地址是0x00,那么c2的内存地址就是0x08。当给c1和c2分别赋值的时候,首先给c1赋值为:
130545(1 1111 1101 1111 0001),其中低8位的1111 0001为c1的值,高位的全部溢出,此时如果只有一个c1而没有c2,那么读到的数据就是-15,如果有c2就另当别论了。
下面看c2,给c2赋值14521(0011 1000 1011 1001),此时低8位的1011 1001位c2的值,高8位溢出,溢出的部分正好覆盖了c1所在的内存地址,所以c1的值就变成了0011 1000,也就是56。
由于c2的值是1011 1001,这个单字节的有符号整数的最高位为符号位,符号位是1说明这是一个负数,而计算机中的数字都是以补码的形式表示的,正数的补码和原码相同,负数的补码比较麻烦,
1100 0110转换以后就是1100 0111,去掉最高位的符号位1以后就是00 0111,也就是71,所以最后的结果就是56和-71。
无符号整型的问题也可以按这个方式说明。