这个是程序的链接,主要是main函数部分
https://share.weiyun.com/Mb7asiXd
代码错误主要有3个,一个是
if (a = 0) ,判断要用 == 而不是 =
你全部写错了,都要改
另一个是
char * name;
这里name并没有分配地址
下面你就 scanf("%s", name); 了,这必然崩溃
你得 char name[100];
还有一个是switch的问题,每一个 case 结束都要加上 break;
不知道你这个问题是否已经解决, 如果还没有解决的话:其实,我们在一开始设sh为128是有风险的,因为有符号类型的char的表示范围是-128~127
为什么会这样?
表示有符号数的时候,我们会有一个符号位,这个位是二进制数的最高位,用0来表示正数,用1来表示负数。剩下的位,如果本身是正数,则不变;如果是负数,则将它的绝对值的表示转换为二进制补码(实质上,一般无需首先确定符号位,因为负数的第一位一般来说补码都是1)(具体详见佛罗赞的《计算机科学导论》)
C语言中,有符号数与无符号数主要是由于是高位是否代表符号(正、负数)来决定的。有符号数是最高位(二进制位)代表符号,1代表是负数,0代表是正数,不管是正数还是负数都是以补码的形式存储与使用的。
也就是说,我们让sh = 128,最终导致它发生溢出!
就像一个环一样,从127在踏出一步,就到了-128(因为计算机会将溢出的位数直接舍弃,保留剩下的位数,具体详见佛罗赞的《计算机科学导论》)
而这时,sh的绝对值的二进制表示应当是1000 0000(即0111 1111 + 1),其中第一位表示大小的同时表示符号为负,因此同时应该将其转换为补码(补码不代表它的数值大小)
如果此时向左移位,如果它不能自动转换为int类型,那么应该显示为0;如果可以,应当显示为-256,即0001 0000 0000
为进一步证实这一点,我们将左移后结果强制转换为char
结果如我们所料,是0
那么,我们回到第一个问题,如何证明是自动转换为了int而不是其他类型?
其实方法很简单,那就是利用int类型和其他类型能保存的位数的不同。
如上所言,此时-256是以补码形式表示的,如果此时将它强制转换为无符号数,它应当是一个很大很大的数,那么我们就可以根据结果的大小来判断是否为int型
我们期望的值是1111 1111 1111 1111 1111 1111 0000 0000
而实验所得值是:
结果如我们所愿。
并且将转换说明换成%lu也没有影响:
如果sh一开始的值稍小一点,为127的话,结果就会天差地别:
这是因为正数和负数在补码(two's complement)中的表示天差地别。
这就证明了它会自动转换为int类型(当然,我不知道不同编译器会不会对这种自动转换有影响,但至少在VS 2019中是这样的)