计组实验——short与int的类型转换
要求:利用C语言函数,实现功能(不能利用强制转换)
short—>int
首先我们知道,short型在计算机中存储时占用了16个bit,int型占用了32个bit,题目要求的都是有符号数
因此 short:0–14位是数值位,15位是符号位;int:0–30位是数值位,31位是符号位
从short到int,我们需要将short中的0-14位存入int型的0–14位,同时将符号位传到对应位置。
int short2int(short a){
short x=a,*px;
int y=0,*py;
py=&y;
px=(short*)py;
*px=x;
if(x&0x8000)
y|=0xffff0000;
return y;
}
我们思考用指针来完成这个操作,首先在函数体内定义一个同样的short型整数x和short型指针px;
同时定义好接收的int型变量y和指针py,py指向变量y
指针类型和指针类型转换
接下来我们写到的
px=(short*)py;
这一步是对指针的类型转换,我们知道指针的本质是存储地址,所以不同类型的指针都是在存储地址,区别就是
指针在内存中每次移动的字节数,例如int类型占4个字节,指针就从首地址开始移动,读取4个字节,short类型占2字节,指针就移动2字节。通过声明指针类型,告诉指针每次移动多少字节,来获取变量的值。
因此指针类型就限制了指针读取字节的步长,我们在这里将py转换为int型变量,这样的话,(py+1)对应的操作就是向后移四个字节读取而不再是两个字节。
经过这步操作之后,px和py一样是short型指针,同样指向变量y,再通过解引用操作,将x的值赋给指针所存地址所存内容。
接下来我们要将符号位进行传递,通过位运算,如果short的符号位是1,那么y保持低十六位不变,高十六位或1,同步符号位,完成操作。
int --> short
大端模式(Big-endian):
所谓的大端模式,是指数据的高字节,保存在内存的低地址中,而数据的低字节,保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;
例子:
0000430: e684 6c4e 0100 1800 53ef 0100 0100 0000
0000440: b484 6c4e 004e ed00 0000 0000 0100 0000
在大端模式下,前32位应该这样读: e6 84 6c 4e ( 假设int占4个字节)
记忆方法: 地址的增长顺序与值的增长顺序相反
小端模式(Little-endian):
所谓的小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致
例子:
0000430: e684 6c4e 0100 1800 53ef 0100 0100 0000
0000440: b484 6c4e 004e ed00 0000 0000 0100 0000
在小端模式下,前32位应该这样读: 4e 6c 84 e6( 假设int占4个字节)
记忆方法: 地址的增长顺序与值的增长顺序相同
我的计算机是小端模式
首先给出代码
int int_short(const int x,short* py) //int->short
{
short* px=(short*)&x;
short y=*px; //y取int低位
int x0=x;
if(x&0x80000000) //转原码
x0=(~x)+0x00000001;
x0=(x0>>15)&0x0000ffff; //取15-30位
if(x0!=0) //非0,不可转short
return -1;
if((x&0x80000000)==0) //正数,改符号为0
y&=0x7fff;
else y|=0x8000; //负数,改符号为1
*py=y;
return 0;
}
定义short型指针px,指向了int型数据,由于它是short型,步长为int的一半,因此px指针指向的数据就是x的低16位。
在这里我们要判断能否转换,因此我们要看int型数据的15-30位是否有数据,一旦存在就超出了short的存储范围,将无法转换。
我们在这里用x0得到高15-30位,再与0进行比较,最后再对符号做调整,利用指针的解引用,给short型指针赋值。