计算机的工作原理
CPU 找数据 数据通过地址信息来标记
高级语言:在内存中"分配"空间用变量来标识
所以变量一定是存在地址的
例如:
int a=10;
//a就是变量名用来对地址进行标识 0x100对这个地址标识
必备常识:8bit=1byte
常见的数据类型:
char short int long
//如果问这些数据多大
//并没有一定是多大多大
//我们只是规定了 char最小 为一个字节
规定 short<=int<=long
规定 long>=4B
必备常识:2B 最大是65535 整型常量
注意:
1.小数都是默认为double类型的
2.float 类型变量在定义的时候,需要在字面值后加 F / f,建议F
//比如 3.14多大?
float a=3.14;//这个写法是错误的
//float 是4B 3.14 是8B
//数据表示错误
double a=3.14;
float b=3.14f;
//这两种写法才是对的,请注意这些在以前的学习中所忽略的
//小数不加 f 一定是double类型 大小为8B
必备知识:如何通过补码就知道原数据是多少?
最高位是符号位 通过8421 就可以算出原数据 无需一步一步的倒回原码
%x //输出16进制
%d 有符号的十进制数
%u 无符号的十进制数
C语言是如何表示,操作,找到数据的?
数字:都与符号有一一对应的映射关系 比如"1" 映射0x31
0x31经过编译后在屏幕上显示 数字1
如何在内存中保存? 容量的关注点
1.大小=>容量=>数据类型
高级语言就是为人们提供了一个容量的映射关系
硬件 0 1 两种状态
软件 8bit=1byte 表示一个字节的行为
在不同的设备上容量有所差异
long :Windows 4B
Linux 8B
但规定long long 类型一定是8B
解释一句简单的代码
int a1;
//申请了4B的内存 并用a1来标识
2.容器
定义了一堆标点符号与计算机的内部执行动作做了映射关系
什么是符号,什么是赋值
unsigned int a1=-100;
//无符号数据类型 后面却是一个负数
//编译过程是不会报错的 但这却是很明显的错误
所以赋值只是将内存空间逐位拷贝,只关注容量大小 ,不会考虑数学逻辑,他们大小都是4B,是不会报错的
明显看出即使存在数学逻辑的错误,并未显示编译错误
并且同样的内存值,由于解码方式不同,打印出结果也不同
解码方式:
%d //补码编码进行解析
%u //正数权值进行组合 8421 所以打印出来必定是一个整数
//若用%u来打印负数,只会得到一个极大的正数
必备常识:0xff就是1111 1111
unsigned char a=0xff;
为什么会有这样的结果?
首先我们要知道**%d, %u都会自动取4字节的二进制内容进行解析转换为整形数据**
所以都是32位运算
0000 0000 1111 1111
必备常识:一个8个数字,因为一个数字占4位
所以根据正数权值和原码补码运算,%d %u所打印出255
不要被printf所欺骗,多用%x来查看地址
必备常识:乘以2=>左移一位 除以2=>右移一位
关于右移:右移完无符号数肯定右侧补0
很好理解,我们看段代码
#include <stdio.h>int main()
{unsigned int a=-10; unsigned int b1=a*2;unsigned int b2=a/2;//涉及到除法 右移,a是无符号数 要补0 必定为正数printf("%d %u %x\n",b1,b1,b1); printf("%d %u %x\n",b2,b2,b2); return 0;
}
为什么没有输出-5,却输出了一个很大的正数
就是因为a是无符号数 最高位右移补0 变成正数了
这样就输出-5了,因为有符号数不再补0,并未改变正负
a有符号,必然进行有符号运算
逻辑判断
#include <stdio.h>int main()
{int c1=-10;unsigned int c2=10;if(c1<c2)printf("correct c1<c2");elseprintf("error c1>c2");
}
这段代码会是什么结果?
为什么和我们的逻辑不一样?
注意:当数据类型不一样,会把int 强转为 unsigned int来比较
c1//补码前面很多1111
c2//补码很多0000
当他俩都是无符号数最高位还是符号位吗?
不是了,0肯定小于1
所以这里就是正数比负数小了
符号:
= //容量相同就OK
< >//进行数据类型强转后比较补码大小
取反
#include <stdio.h>int main()
{int c1=-10;int d1=~c1;printf("%d %u %x",d1,d1,d1);
}
必备常识:取反=>原数+取反数=-1 这样能够快速得到取反数为多少
数据类型的容量
#include <stdio.h>int main()
{unsigned char a=250;printf("%d\n",a+6);a=a+6;printf("%d\n",a);
}
解析:其中250为整型大小为4B a为字符型 大小为1B
大容量->小容量拷贝 必然是装不下的
装不下怎么办—>截断:从低到高,依次拷贝,直到容量不够
第一个打印:是一个表达式常量为4B,所以打印出大小为4B的256
常量大小:4B
第二个打印:是字符型a 大小只有1B
1B的范围是0~255
256刚好超出 所以就补0了,打印出0
依然是大->小拷贝
int main()
{char a2=0x12345678;printf("%d %u %x",a2,a2,a2);
}
a2大小为1B 0x12345678 一共8位数字 ,一个数字占4位 一共32位=4B
一个字节只能打印出2个数字,所以只打印出了78
再来看看小容量->大容量赋值
int main()
{int c1=0x80000000;unsigned long long a3=c1;printf("%lld %llu %llx",a3,a3,a3);
}
long long 有64位 c1只有32位 c1=1000 0000 0000
那前面还有32位补什么呢?
补的是符号位
无符号补0,有符号补的是1
所以%x打印出了fffffff
必备常识:size_t 相当于 unsigned long/ unsigned int