整数类型
cahr:1字节(8比特)
short:2字节
int:取决于编译器(CPU)通常是“1个字”在32位计算机和64位计算机表达是不一样的可能是 4 可能是 8
long:取决于编译器(CPU)通常是“1个字”在32位计算机和64位计算机表达是不一样的可能是 4 可能是 8
long long:8字节
1. 整数的内部表达
计算机内部一切都是二进制的
18 -> 00010010
0 -> 00000000
-18 -> ?
2.二进制负数
1个字节可以表达的数:
00000000 - 11111111(0-255)
三种方案:
仿照十进制,有一个特殊的标志表示负数
取中间的数为0,如10000000表示0,比他小的是负数,比他大的是正数
补码
3.补码
-1,希望 -1+1 = 0
0 在8进制中是 00000000
1 在8进制中是 00000001
11111111 + 00000001 = 10000000 ; 但是在8进制中超出8位会被丢掉1位所以这个数就是 (1)00000000,只是因为1被丢掉了
因为 0 - 1 = -1,所以 -1= (1)00000000 - 00000001 = 11111111
11111111被当做纯二进制看时是 255 被当做补码看就是 -1
对于 -a 补码就是 0-a,实际是2n - a
补码的意义就是拿补码和原码可以加出一个溢出的 “0”
4.数的范围
对于一个字节(8位)可以表达的是:
00000000 - 11111111
00000000 是 0
从高位看 11111111 ~ 10000000 -> -1 ~ -128 这个是按照补码看
从低位看 00000001 ~ 01111111 -> 1 ~127
5. unsigned
如果一个字面量常数想要表达自己是 unsigned 可以在后面加 u 或 U
255U 、unsigned char c = 255;
用 l 或 L 表示 long(long)
*unsigned的初衷是为了做纯二进制运算,而不是为了扩展数能表达的范围,主要是为了移位
char c = 255;
printf("c=%d",c); 输出 -1
unsigned char c = 255;
printf("c=%d",c); 输出 255
// 00000000-11111111 0-255 使用 unsigned 表达正数的时候会被扩大一倍
原本 char 只能表达 -128~127 但是使用 unsigned 可以表达 0255
char c = 127;
c = c+1;
printf("c=%d",c); 输出 -128
char c = -128;
c = c-1;
printf("c=%d",c); 输出 127使用unsigned
#include <stdio.h>
int main()
{
char c = 127;
c = c + 1 ;
printf("c = %d\n",c); //-128
char i = -128;
i = i - 1 ;
printf("i = %d\n",i); //127
unsigned char a = 255 ;
a = a + 1;
printf("a = %d\n",a); //0
unsigned char b = 255 ;
b = b + 1;
printf("b = %d\n",b); //0
unsigned char d = 0 ;
d = d - 1;
printf("d = %d\n",d); //255
}整数的输入和输出
只有两中形式:int 或者 long long
%d : int
%u : unsigned
%ld : long long
%lu : unsigned long long
8进制和16进制
一个以0开始的数字字面量是8进制
一个以0x开始的数字字面量是16进制
%o用于8进制,%x用于16进制
8进制和16进制只是如何把数字表达为字符串与内部如何表达数字无关
16进制很适合表达二进制数据,因为4位二进制是一个16进制位,因为二进制四次方是十六
选择整数类型
为什么整数要有那么多种?
为了准确表达内存,做底层程序的需要
没有特殊需要,就选择int
现在的CPU的字长普遍是32位或64位,一次内存读写就是一个int,一次计算也是一个int,选择更短的类型不会更快,甚至可能更慢,现代的编译器一般会设计内存对齐,所以更短的类型实际在内存中有可能也占据一个int的大小(虽然sizeof告诉你更小)
unsigned与否只是输出的不同,内部计算是一样的