nocturne25 发表于 2016-11-15 21:20:17

char定义字符串后再定义一个 unsigned char后前一个失效

在做《带你学C带你飞》S1E8课后题时,发现的。代码如下:
#include <stdio.h>

int main(){
        char name;
        unsigned char height;
        float mass;
       
        printf("请输入您的姓名:");
        scanf("%s", name);
       
        printf("请输入您的身高(cm)");
        scanf("%u",&height);
       
        printf("请输入您的体重(kg)");
        scanf("%f",&mass);
       
        printf("%s的身高为%.2f(in),体重为%.2f(lb)",name,height/30.48*12,mass*2.2046);
       
        return 0;
}

编译正常,但是运行结果中,name变量始终打印不正确,经各种测试,只要将变量height声明为float形式就可以解决问题,但是不明白为什么,求指点。

fc1735 发表于 2016-11-15 21:20:18

本帖最后由 fc1735 于 2016-11-15 23:28 编辑

我也觉得很奇怪,在内存中name在height的后面,如果是name在height的前面就不会影响

#include <stdio.h>

int main(){
      char name;
      unsigned char height; //用1个byte来存放数字(0~255)
      float mass;
      
      printf("请输入您的姓名:");
      scanf("%s", name);
      
      printf("请输入您的身高(cm)");
      scanf("%u",&height);//%u为4个字节,放到height的地址处,数值在256内时,第一个byte存放其数值,后面3个byte均存放0,但后面的地址是前面的name ,name,name的内容,故原本输入的名字被0即空字符覆盖掉了
      
      printf("请输入您的体重(kg)");
      scanf("%f",&mass);
      
      printf("%s的身高为%.2f(in),体重为%.2f(lb)",name,height/30.48*12,mass*2.2046); //name为空字符,即返回。
      
      return 0;
}


解决办法是先输入身高再输入姓名,就不会被覆盖,但前提是你知道内存中排列的顺序,所以这样写的话,虽然省了3个byte去存放数值,但在不知道存放顺序的情况下,要运行完或反编译之后再来修正原代码

另外正确的scanf 字符参数,要把输入的无符号数值以一个byte存放的话 是%hhu 这样就不会越界覆盖到name~name的位置

鱼币{:10_254:} {:10_254:}

人造人 发表于 2016-11-15 22:09:58

unsigned char height;
scanf("%u",&height);

#include <stdio.h>

int main(){
        char name;
        unsigned int height;
        float mass;

        printf("请输入您的姓名:");
        scanf("%s", name);

        printf("请输入您的身高(cm)");
        scanf("%d", &height);

        printf("请输入您的体重(kg)");
        scanf("%f", &mass);

        printf("%s的身高为%.2f(in),体重为%.2f(lb)", name, height / 30.48 * 12, mass*2.2046);

        return 0;
}

immortalfaith 发表于 2016-11-16 16:34:49

%u,是按4个字节为一个单位输出,而char只占一个字节,所以输出不正确

nocturne25 发表于 2016-11-17 17:20:09

人造人 发表于 2016-11-15 22:09
unsigned char height;
scanf("%u",&height);

朋友,多谢你点进来解答我的问题,不过不好意思啊,是我没说明白困惑的地方,按照我的理解,这里height声明成char形式,结果应该也是正确的,但是事实好像并不如我所想。不明白的是为何如此…

nocturne25 发表于 2016-11-17 17:53:30

fc1735 发表于 2016-11-15 21:20
我也觉得很奇怪,在内存中name在height的后面,如果是name在height的前面就不会影响




朋友,我想我大概明白了你的意思,而且,改变顺序以后确实也可以解决这个问题。
但是还是感觉很困惑,以hhu形式输入,只占了一个byte,那应该不会覆盖后面的name~name呀,但结果却还是不对,好奇怪。

fc1735 发表于 2016-11-17 18:43:32

nocturne25 发表于 2016-11-17 17:53
朋友,我想我大概明白了你的意思,而且,改变顺序以后确实也可以解决这个问题。
但是还是感觉很困惑,以 ...

真的吗?改成"%hhu"应该要正常了才对啊{:10_291:}

nocturne25 发表于 2016-11-17 22:01:13

fc1735 发表于 2016-11-17 18:43
真的吗?改成"%hhu"应该要正常了才对啊

#include <stdio.h>

int main(){
      char name;
      unsigned char height;
      float mass;
      
      printf("请输入您的姓名:");
      scanf("%s", name);
      
      printf("请输入您的身高(cm)");
      scanf("%hhu",&height);
      
      printf("请输入您的体重(kg)");
      scanf("%f",&mass);
      
      printf("%s的身高为%.2f(in),体重为%.2f(lb)",name,height/30.48*12,mass*2.2046);
      
      return 0;
}

在不改变顺序的情况下貌似还是不正常…{:10_250:}

fc1735 发表于 2016-11-17 22:25:51

本帖最后由 fc1735 于 2016-11-17 22:28 编辑

http://stackoverflow.com/questions/15825254/why-is-scanfhhu-char-overwriting-other-variables-when-they-are-local

也有人有同样的问题

nocturne25 发表于 2016-11-17 22:57:32

fc1735 发表于 2016-11-17 22:25
http://stackoverflow.com/questions/15825254/why-is-scanfhhu-char-overwriting-other-variables-when-th ...

啊哈,英文渣表示看起来略费劲,结论是说,因为我的编译器不支持hhu吗?我试着打印了hhu的长度,的确是1啊…hu应该是2吧..
看来这个问题还比较复杂,感觉,作为一个初学者再深究下去也不一定能很好掌握,我觉得这问题先这样吧,以后再来看这个问题好了。

朋友,多谢了。。
页: [1]
查看完整版本: char定义字符串后再定义一个 unsigned char后前一个失效