作业帮 > 综合 > 作业

#include#include#includeint main(){long int x1=123456789;lon

来源:学生作业帮 编辑:搜狗做题网作业帮 分类:综合作业 时间:2024/06/03 16:23:50
#include
#include
#include
int main(){
long int x1=123456789;
long int x2=12345;
int x3=123;
double y1=123.6;
int z=(int)y1;
printf(
"%ld,%d>\n"
"%ld,%d>\n"
"%d,%lf>\n"
"%lf,%d>\n"
"< z-->%d,%lf>\n",
x1,x1,
x2,x2,
x3,x3,
y1,y1,
z,z);
system("pause");
return 0;
}
关键问题在于:为什么错误的输出方式会影响到正确的输出方式
#include#include#includeint main(){long int x1=123456789;lon
为什么错误的输出方式会影响到正确的输出方式是因为:
一般机器上,
int 2 字节
long 4 字节
float 4 字节
double 8 字节
char 1字节
在 "%d,%lf>\n" 这行,后一个X3在作为不定参数压入值时,自动转成double (类型提升)
机器读取了2 + 8 = 10个字节,而实际上两个X3加起来只有四个字节,
所以造成了错误,因为机器认为每个二进制位 都是 有意义的.
并且 整型 和 实数型 在底层 二进制位上的 排列标准,也是不一样的.
所以在输出时要注意控制变量的格式
只要把输出变量强制转换就可以了,代码如下,修改地方已表明
#include
#include
#include
int main(){
long int x1=123456789;
long int x2=12345;
int x3=123;
double y1=123.6;
int z=(int)y1;
printf(
"%ld,%d>\n"
"%ld,%d>\n"
"%d,%lf>\n"
"%lf,%d>\n"
"< z-->%d,%lf>\n",
x1,x1,
x2,x2,
x3,double(x3),//强制转换成double型
y1,int(y1),//强制转换成int型
z,double(z)); //强制转换成double型
system("pause");
return 0;
}
再问: 关键是,你看看y1的输出吧,y1是double型,但是,在输出%lf情况也出错,为什么
再答: 前面的两个X3不是字节数不够么,那么后面的y1就自动补足,后x3和前y1的前部分字节在 "%d,%lf>\n" 里的%lf中输出了错误的值,y1的后面部分字节又与后一个y1的前部分字节在"%lf,%d>\n"中的%lf中输出了错误的值。以此类推,字节数会自动补足,所以在最后一行 "< z-->%d,%lf>\n"的最后%lf中输出这样1.#QNAN0的字符,因为总的输出字节数大于了你所赋过值的字节数,那么就会造成最后有一部分字节是错误的,并没有事先赋过值。
再问: 那岂不是,都按照补足的说法,那取y1值的时候,地址,变了?我试着在x3之前和之后分别用%p输出y1的地址,好像还真是。。。你试试
再答: 确实,由于补位的原因,导致地址也是截取的是补位剩下的字节的地址。你把两个y1的地址都输出,"%p,%p>\n" ,就会发现后面的y1地址又正常了,因为输出地址的时候没有部位现象,截取的地址就是完整的。
再问: 这么邪门,我一直以为,一旦指定了变量,只要是输出位置就是不会变化的,这些变量应该是存储在堆栈中的吧,那么,他们送到寄存器中,可以这么理解么:送了一趟字节流过去,他们是连续的?然后才会导致补足?怎么送给寄存器的啊?怎么感觉再错也不会输出一百多个零吧??想找相关的资料也没找到
再答: 额,这样说吧,这些数据是一串数据流,整体读取出来放入寄存器,是连续的,在printf时要先制位再输出,制位时按照要制位的字节数对寄存器中的相应字节数的数据进行制位。 你前面看到的地址不同只是因为输出的地址是其中一部分字节的首地址,而实际这些数据的地址并没有发生变化。
再问: 行,我自己再去找找资料,谢谢,绝对的最佳答案