学益得线上课堂
从基础学习嵌入式
玩转智能硬件、斩获高薪offer
学习嵌入式的第一步必须要搞懂C语言,不管后面是从事硬件开发、还是底层开发、还是应用开发,都离不开C语言。C语言效率高是一个根本原因,毫不夸张的说,没有C语言,就没有计算机,没有现在我们能看到的一切智能电子设备。
前面专门有文章讲解了C语言在工作中的实际应用,大家可以阅读下。
详细盘点C语言在工作中的实际应用
C语言的学习需要从基本的数据类型学起,类容很多,包括运算符、表达式、数组、指针、函数、内存管理等等,在这里也给大家详细总结了一下。
学益得智能硬件-C语言学习路线
C语言在运行的过程中需要保存数据,保存数据就需要内存,需要多大的内存呢?于是C语言就造出了数据类型的概念,不同的数据类型占用不同大小的内存空间,比如你想保存一个整数,编译器就给你分配4个字节,你想保存一个字符,编译器就给你分配1个字节。
数据类型分类
数据类型的分类没有固定的标准,我这里暂且把他们分为两类,基本数据类型和复合数据类型。
字符型数据和数值型数据都有符号之分,分为有符号和无符号。所谓有符号,就是既能表示整数也能表示负数。所谓无符号数,只能表示正数。
int a; //等价于 signed int a; 定义一个有符号的整数
unsigned int b; //定义无符号整数b,b只能用于保存正数
char c; //等价于 signed char c; 定义有符号字符
unsigned char d; //定义无符号字符
字符为什么还有符号一说?难道还有‘-a‘这个东西吗?
这得从字符在内存中的表示说起。计算机只能识别二进制,就是高低电平(要么有电、要么没电)。所以内存里面保存的数据要么是1,要么是0。但是这样的话字符’a‘就没法表示了,他跟数字没有关系,不能转换成二进制。于是就想了一个方法,把’a‘转换成数字,就是所谓的ASC码。可以理解成,每个字符都对应一个数字,比如’a‘对应的是97,所以’a‘在内存里面的存储就是数字97,只不过’a‘是用一个字节来表示97,整数97是用四个字节表示。
ASCII码表
复合数据类在这不做过多解释,后面都会作为一个专题来讲。
数据类型长度
每个数据类型长度必须搞清楚,笔试的重点内容,虽然不会直接问你char占几个字节,但是会放在结构体里面考查。涉及到两个知识点:
数据类型长度在不同的操作系统上略微有不同,大部分情况下都是按照32位操作系统计算。如何判断数据类型长度?sizeof可以解决。
#include
int main()
{
printf("%ld\n", sizeof(char)); //sizeof是关键字,不是函数,用于求数据类型的长度
printf("%ld\n", sizeof(int));
printf("%ld\n", sizeof(short));
printf("%ld\n", sizeof(long));
printf("%ld\n", sizeof(float));
printf("%ld\n", sizeof(double));
return 0;
}
在32位操作系统里面,结果是char 1字节,short 2字节,int 4字节,long 4字节,float 4字节,double 8字节,64位操作系统略有不同,比如long 8字节。
字节是什么?内存是以字节为单位,就像教学楼一样,以教室为单位,每个教室都有一个门牌号。内存也是,每个字节都有一个地址,一个整数会占用4个地址。每个字节由8位二进制数组成,就像每间教室有8个作为一样,每个座位有两种状态,要么有人,要么没人。
下面尝试着计算类型【char】能表示的范围。
char在内存中占1个字节,每个字节由8位二进制数组成。
先来研究无符号char,无符号char的8位全部用来表示数值,于是得到最大值:
对这个数值加1,得到100000000,即2^8,256,减一,得到255。无符号char能表示的最大数就是255。
最小数:
无符号char能表示的最小数0。
再考虑有符号的情况。有符号数,最高位用来表示符号位, 0表示正数,1表示负数。 于是得到最大数:
这个数字是 128 - 1 = 127,有符号字符能表示的最大数是127。
最小数肯定是负数,所以第一位应该是1。于是很多同学误以为,最小数:
这个数字是-127。所以有符号char能表示的范围是-127到127?显示不是,0到255可以表示256个整数,-127到+127能表示255个整数,明显少了一个,原因在于:
这两个数字重复了,一个是-0,一个是+0。所以在计算机中,0的表示应该是:
如果写成这样:
表示最小数-128。所以有符号char能表示的范围 -128 到 127。
关于数据类型,最重要的还是要搞清楚数据在内存里面是怎么存放的,比如负数在内存中以补码形式存储。下面计算一下在 char 类型中,为什么 -128 - 1 = 127 ?
-128的二进制 10000000,先计算反码, 11111111,再计算补码(反码加1) 10000000,符号位保持不变,其实相当于是越界了,超过了8位,所以最高位1去掉。同理可得 -1 的补码。
最终的结果是 101111111,因为char只有1个字节,只有8位,所以最高位去掉,结果是 01111111,即127。
最后给大家留一个微软经典的笔试题:
unsigned int a = 3;
a * -1 = ? //不仅涉及到负数在内存的存储,还涉及到混合运算
更多文章、视频、嵌入式学习资源,微信关注 【学益得智能硬件】。