c语言的类型
整数:char、short、int、long、long long
浮点数:float、double、long double
逻辑:bool
指针
自定义类型
所表达的数的范围:
char < short < int < float < double
不同类型的变量在内存中的表现形式不同:
整形的变量是二进制数或者二进制的补码;浮点数(float、long、double)是编码形式
整数类型
char:1字节(8比特即8位二进制数)
short:2字节
int:取决于编译器(cpu)(int可以表达一个寄存器的大小)
long:取决于编译器(cpu)
long long:8字节
二进制负数如何表示
1.仿照十进制数用标志表示(复杂不推荐)
2.取中间数记为0比他小的是负数,比他大的是正数(麻烦不推荐)
3.补码(常用)
补码
用补码表示负数
例如想要表示 -1 可以理解为 -1+1=0
1111 1111+0000 0001=1 0000 0000 在8位的二进制数中如果有溢出,即9位数会将最高位舍弃
1111 1111+0000 0001=0000 0000
(0-1=-1)
(1)0000 0000-0000 0001=1111 1111
1111 1111被当作纯二进制时值为255,被当作补码时是-1
所以:对于 -a ,其补码就是0-a,实际是(2的n次方-a)n是这种类型的二进制位数
因此:补码的意义就是拿补码和原码可以加出一个溢出一位的数然后将最高位舍去得到0值
数的范围
对于一个字节(8位二进制数)(一定是8位二进制数的情况下)
当作纯二进制数看待表达的范围是0-255
0000 0000 -- 1111 1111
当作补码看待表达的范围是 -128 ~ 127(即 - 2的n-1次方到2的n-1次方再-1;注:n是二进制位数)
0000 0000-->0
1111 1111 ~ 1000 0000 --> -1 ~ -128
0000 0001 ~ 0111 1111 --> 1 ~ 127.
#include <stdio.h>
int main()
{
char c=255;
//c=1111 1111=-1
int i=255;
//i=0000 0000 0000 0000 0000 0000 1111 1111=255
printf("c=%d\n",c);
printf("i=%d\n",i);
return 0;
图示理解
不管是原码还是补码,运算的时候都是用单纯数值进行二进制运算的
1111 1111 +1-->1 0000 0000 -->0(最前面一位溢出舍弃得0)
0111 1111 +1-->1000 0000 --> -128
1000 0000 -1-->0111 1111 -->127
#include <stdio.h>
int main()
{
char c=127;
int i=255;
c=c+1;
printf("c=%d,i=%d\n",c,i);
return 0;
}
#include <stdio.h>
int main()
{
char c=-128;
int i=255;
c=c-1;
printf("c=%d,i=%d\n",c,i);
return 0;
}
图示
#include <stdio.h>
int main()
{
unsigned char c=127;
int i=255;
c=c+1;
printf("c=%d,i=%d\n",c,i);
return 0;
}
#include <stdio.h>
int main()
{
unsigned char c=255;
//255是8位二进制数的最大值超出会发生溢出,进而舍弃溢出位得到0
int i=255;
c=c+1;
printf("c=%d,i=%d\n",c,i);
return 0;
}
#include <stdio.h>
int main()
{
unsigned char c=0;
int i=255;
c=c-1;
printf("c=%d,i=%d\n",c,i);
return 0;
}
unsigned
unsigned 可以使输出不带负数的纯二进制数值,设立初衷是为了做纯二进制运算。
如果一个常量想表达自己是unsigned可以在后面加u或U,例如:255U
#include <stdio.h>
int main()
{
unsigned char c=255;
int i=255;
printf("c=%d\n",c);
printf("i=%d\n",i);
return 0;
}
整数的输入输出
所有小于int的整数输入输出都用%d
所有大于int的整数输入输出都用%ld
unsigned输入输出用%u
unsigned long long用%lu
#include <stdio.h>
int main(){
char c=-1;
//-1表示二进制位数范围内最大的数
//例如char是8位二进制1111 1111当作补码看是-1
int i=-1;
//int 一般看作32位二进制 -1表示11111111 11111111 11111111 11111111
printf("c=%u,i=%u\n",c,i);
/*当于int位数的其他类型输出时
会自动转化为int类型和int的位数
上面char的最大值应为8位二进制255
但是会转化为 32位二进制最大数4294967295 */
return 0;
sizeof()
sizeof是一个运算符,给出某个类型或是变量内存中所占据的字节数
sizeof是静态运算符,他的结果在编译时已经确定
不能在sizeof的括号里面做运算,这些运算是不会做的
#include <stdio.h>
int main()
{
int a;
a=6;
printf("sizeof(a=)%ld\n",sizeof(a));
printf("sizeof(a++=)%ld\n",sizeof(a++));
//在sizeof中a++的值还是等于a
//因为sizeof中无法做运算只会根据数据类型int输出数值
printf("sizeof(double)%ld\n",sizeof(double));
printf("sizeof(a+1.0)=%ld\n",sizeof(a+1.0));
//a+1.0的值输出为8
//原因是1.0是浮点数,浮点数与整数一起参与计算会将整数化为浮点数
//所以此时a+1.0的输出值为浮点数double类型
printf("a=%d\n",a);
return 0;
}
十进制八进制十六进制输入输出
输出十进制用%d
输出八进制用%o
十六进制输出用%x
十六进制带字母用%x输出小写字母用%X输出大写字母
无论是八进制还是十六进制输出的内容都不带前缀,想要前缀就自己在c=oX%X输入
以上在读入scanf()同样适用,意思为读到的数字是()进制
#include <stdio.h>
int main()
{
char c=012; //八进制0做前缀
int i=0x12; //十六进制0x做前缀
//输出十进制用%d
printf("c=%d,i=%d\n",c,i);
//输出八进制用%o
printf("c=%o,i=%o\n",c,i);
//十六进制输出用%x,
//十六进制带字母用%x输出小写字母用%X输出大写字母
printf("c=%x,i=%x\n",c,i);
printf("c=%X,i=%X\n",c,i);
//无论是八进制还是十六进制输出的内容都不带前缀,
//想要前缀就自己在c=oX%X输入
return 0;
}
任何形式的输出都是人把他当作什么看,例如unsigned,或是十六进制、八进制等输出只是输出形式不同,与计算机内部实际数值无关。