谦卑请教 C语言 int i=1;i<<31为什么结过时0x8000,0000 有符号整型的第一位不是符号位吗? 求原因

作者&投稿:越费 (若有异议请与网页底部的电邮联系)
C语言的一个问题~

你的机子是几位的?

unsigned b; -- unsigned int b; ?
int a; -- TC 表示 short int.

有符号数,最高位是符号位,数值要少掉一位。数值超过存放长度时,例如17位数放在16位里,最高位会丢失。16位数无符号数放到16位有符号数存放单元,最高位变负号。

a=xx67x; 输出不会变 xx76x

32768 是 0x8000 -> 1000 0000 0000 0000
32767 是 0x7fff -> 0111 1111 1111 1111

0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,
0x40
};

static unsigned char auchCRCHi[]=
{
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40
};


bool CRCDecToHex(unsigned char Destination[],unsigned char Source,const int DesLen,int &HexBit);
void UCToASCII(unsigned char Lo16[],int len);
unsigned short CRC16(unsigned char puchmsg[],unsigned short usdatalen);


int main()
{
//unsigned char buf[]={0x01,0xA8,0x98,0x42,0x65,0x74,0x74,0x65,0x72,0x17};

//unsigned char buf[]={0x07,0x11,0x41,0x00,0x53,0xB9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03};
unsigned char buf[]={0x00,0x00,0x01,0x00,0x00,0x00,0x1A,0x00,0x1C,0x03};
//unsigned short Len=10;
//unsigned short Len=19;
unsigned short Len=10;
unsigned char Lo=CRC16(buf,Len)%256;
unsigned char Hi=CRC16(buf,Len)/256;

unsigned char Lo16[4]={0};
unsigned char Hi16[4]={0};
printf(" 十进制:低字节Lo=%d
十进制:高字节Hi=%d
",Lo,Hi);
unsigned char temp=Lo;
int ASCIILoLen=0;
CRCDecToHex(Lo16,temp,4,ASCIILoLen);
UCToASCII(Lo16,ASCIILoLen);

printf(" 低字节:Lo16=");
for (int i=0;i<ASCIILoLen;i++)
printf("%c",Lo16[i]);
printf("H
");


temp=Hi;
int ASCIIHiLen=0;
CRCDecToHex(Hi16,temp,4,ASCIIHiLen);
UCToASCII(Hi16,ASCIIHiLen);

printf(" 高字节:Hi16=");
for (int I=0;I<ASCIIHiLen;I++)
printf("%c",Hi16[I]);
printf("H
");

return 1;
}

//十进制转十六进制
bool CRCDecToHex(unsigned char Destination[],unsigned char Source,const int DesLen,int &HexBit)
{
unsigned char temp=Source;
int i=DesLen-1;

while(temp>=16)
{
Destination[i]=temp%16;
printf("Lo[%d]=%d
",i,Destination[i]);
temp=temp/16;
i--;
}
Destination[i]=temp;
printf("Lo[%d]=%d
",i,Destination[i]);

HexBit=DesLen-1-i+1;
for(int a=i;(a-i)<(DesLen-1-i+1);a++)
{
Destination[a-i]=Destination[a];
printf("移位后:Lo16[%d]=%d
",a-i,Destination[a-i]);
}

return true;
}

//无符号字符型转ASCII码

void UCToASCII(unsigned char Lo16[],int len)
{
for(int i=0;i<len;i++)
{
if (Lo16[i]>=10)
{
switch (Lo16[i])
{
case 10:
Lo16[i]='A';break;
case 11:
Lo16[i]='B';break;
case 12:
Lo16[i]='C';break;
case 13:
Lo16[i]='D';break;
case 14:
Lo16[i]='E';break;
case 15:
Lo16[i]='F';break;
default: break;
}

}
else
{
Lo16[i]+=48;
}
}
}

unsigned short CRC16(unsigned char puchmsg[],unsigned short usdatalen)
{
unsigned char uchCRCHi=0xFF;
unsigned char uchCRCLo=0xFF;
unsigned short uIndex;
unsigned short y=0;
while(usdatalen--)
{
uIndex=uchCRCHi=(unsigned char)(uchCRCHi ^ puchmsg[y++]);
uchCRCHi=(unsigned char)(uchCRCLo ^ auchCRCHi[uIndex]);
uchCRCLo=auchCRCLo[uIndex];
}
return(unsigned short)(uchCRCLo+uchCRCHi*256);

C语言的<< 移位运算是包括符号位的,1从第0位左移31位,当然到了第31位上,因此,得到你上面的数0x8000......,这个数当然是负数了。

你用的是16进制。不管有符号,没符号。用16进制都这样表示啊。

c语言对溢出的控制很宽松,其实上述情况属于溢出的一种。原来是一个正数,有限次的乘以2,结果可能是一个负数,此为乘法溢出;原来是一个正数,再加一个正数,结果可能是负数,此为加法溢出。溢出的原因和补码的表示方法有关,如同一个时钟,以12点钟为0,顺时为加正数,逆时为加负数。6点钟是最小负数-2^(n-1),5点钟是最大正数2^(n-1)-1,最大正数顺时针转一格,变成了最小负数。学习c语言要自己留心有没有发生溢出,然也

printf("%d",i); //"%d" 固定以整数形式输出 可能输出负号

printf("%u",i); //"%u" 固定以无符号整数形式输出 没有负号

printf("%x",i); //"%x" 固定以十六进制数形式输出 没有负号

无论你定义i是什么类型

3楼说得对


新河县18243482099: c语言中static int i=1什么意思 -
赞疤附子: 定义静态变量,并把1赋值给i static 声明的变量在C语言中有两方面的特征: 1)、变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值.这一点是它与堆栈变量和堆变量的区别. 2)、变量用static告知编译器,自己仅仅在变量的作用范围内可见.这一点是它与全局变量的区别.

新河县18243482099: 谦卑请教 C语言 int i=1;i<<31为什么结过时0x8000,0000 有符号整型的第一位不是符号位吗? 求原因 -
赞疤附子: C语言的

新河县18243482099: c语言中,int i=1; x=i++ - 1与x=i空格+空格+ - 1的区别 -
赞疤附子: int i=1; x=i++-1; 等于 int i=1; x=i-1; i++; int i=1; x=i + +-1;是一个语法警告!+-1被解释为正负1,实际上就是负1,x最后应该等于零 最好不要这样写代码

新河县18243482099: 在C语言中定义int i=1;执行语句while(i++<5)后i的值为6,为什么? -
赞疤附子: while(i++++在后,先取i的值和5比较,然后i自动加1 当i=4时,执行4++执行5++so,i的值最终为6

新河县18243482099: c语言中int i=1,j,=1,;i+=j+=2这个怎么算?希望有过程,谢谢! -
赞疤附子: 赋值语句从右往左,i+=j+=2;相当于如下过程:j = j+2; i = i+j;所以j=3,i=4.

新河县18243482099: 在c语言已知 int i=1执行语句while(i++<4 )后 i的值 -
赞疤附子: i的值为5

新河县18243482099: C语言问题请教啊;int i=1;int y=i+++i++; 为什么y=2呢?不应该是3吗? -
赞疤附子: int y=i+++i++;中,++ 出现在i的后面,应该先算加法,再自加.因此这句话可以拆为以下三句话int y=i+i;i++;i++;很明显y为2.

新河县18243482099: java里int i=1; i++ ; I++;输出I时多少,C语言中是多少?这是为什么,求解析???? -
赞疤附子: int i=1; i++; System.out.println(i); 这里的输出是 2 所以楼主提出来的输出i是2

新河县18243482099: C语言问题 int i=1; j=(i++,i+3),怎么输出的是j=5 我怎么觉得是i先用1,然 -
赞疤附子: 你可以这样想 j =i++的话, j = 1,但是 i = 2; 所以(i++, i+3),i 的值是先算 i++,i变成2,再计算 i+3,最后的结果赋给 j ,就成了5

新河县18243482099: c语言问题 全局变量声明auto int i=1为什么是错误的 -
赞疤附子: auto这个关键字用于声明变量的生存期为自动.这个关键字意味着,当前变量的作用域为当前函数或代码段的局部变量,意味着当前变量会在内存栈上进行分配. 全局变量不能为auto,因为这两者在内存分配上是不同的两种模式. 但要注意的是,全局变量不能等价于静态变量(static),在内存分配原则上,全局变量等价于extern,它们的生存周期都是进程级.

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网