C语言中signed和unsigned的存储方式、混合运算问题

  在C语言中,signed要求最高位是符号位,以下表示数据大小,而unsigned则全部位都表示大小。如果用8位二进制表示的话,signed范围就是-128到127,unsigned就是

0到255,C语言中专门用两个关键字来描述两种表示方法,于是,就产生了一些不可思议的问题。

1、溢出

  在有符号运算中可能会产生溢出问题,归纳起来就是:两个整数相加可能会溢出,两个负数相加也可能会溢出,一正一负相加肯定不会溢出。在《C深度剖析》中看到一个有趣的问题。

#include <stdio.h>

#include <string.h>

int main(void)

{

  char a[1000];

  int k = 0;

  for (; k < 1000; k++) {

    a[i] = -1-i;  

  }

  printf(“%d\n”, strlen(a));

  return 0;

}

  最终的结果是255。因为数组a[1000]是char类型的,在C语言中明确规定char类型占一个字节内存空间,且在x86的gcc平台上char默认是signed,一开始,k=0,a[0]=-1,随着k不断增大,当k=127,香港服务器租用,则a[127]=-128,对应的二进制是10000000,我们知道-128是编译器能表示的最小值,当k=128,a[128]当然不可能存储-129这个值了,因为最高位发生了溢出,所以在计算机中储存的补码值是01111111,。随着k继续增大,当k=254时,a[254]在计算机中存放的补码是00000001,而k=255,a[255]对应的存储值是00000000,即0,strlen函数遇到第一个0就停止,所有最后的结果是k从0到254,总共长度是255。

2、signed和unsigned混合运算

  C语言中除了char类型,编译器默认其他整型都是signed,在x86的gcc平台上包括char在内所有整型都是signed。

#include <stdio.h>

int main(void){unsigned a = 10;unsigned b = -10;if (a) printf(“yes\n”); else printf(“no\n”);if (b) printf(“yes\n”); else printf(“no\n”);

int c = b;printf(“%d\n”, c);if (c) printf(“yes\n”); else printf(“no\n”);

int d = -20;int e = a + d;printf(“%d\n”, e);if (e) printf(“yes\n”); else printf(“no\n”);

return 0;}

最后结果是

yesyes-10yes-10yes

  从上面例子可以看出,在C语言中,有符号数可以赋值给无符号数,网站空间,结果是一个无符号数,香港空间,而无符号数也可以赋值给有符号数,结果还是一个无符号数;在混合运算中,只要有一个无符号数,都会将有符号数转化成无符号数参加运算,结果也以无符号保存。

我想,这就是旅行的真义吧。

C语言中signed和unsigned的存储方式、混合运算问题

相关文章:

你感兴趣的文章:

标签云: