**
2026十月C语言学习记录1
- 6.2.1数据类型和sizeof的用法 ,6.2.2除int之外的其他类型
先补充一些前提知识(同时也是“6.2.3 整数在计算机是如何表达”的内容)
6.2.1 数据类型与 sizeof 6.2.2除int外的其他数据类型
1. C语言有哪些基础数据类型?
C语言是强类型语言,变量必须先声明类型。我们写段代码,用sizeof看看它们各自占多大内存。
#include<stdio.h>intmain(){// 用 sizeof 查基础类型的大小printf("=== 1. 基础类型大小 ===\n");printf("char: %d 字节\n",sizeof(char));printf("short: %d 字节\n",sizeof(short));printf("int: %d 字节\n",sizeof(int));printf("long: %d 字节\n",sizeof(long));printf("float: %d 字节\n",sizeof(float));printf("double: %d 字节\n",sizeof(double));return0;}代码解释:
- 整型家族主要分
char(1字节)、short(2字节)、int(4字节)、long(在32位系统是4字节,64位系统是8字节)。 - 浮点数家族有
float(4字节,单精度)和double(8字节,双精度)。 - 你运行后会发现,在 DevC++(32位/64位 PC)下和在 STM32(32位单片机)下,
int和float都是 4 字节,这是最常见的数据宽度。
2. sizeof 不仅可以量类型,还可以量变量
inta=10;doubleb=3.14;printf("\n=== 2. 变量的大小 ===\n");printf("变量 a 的大小: %d 字节\n",sizeof(a));// 相当于 sizeof(int)printf("变量 b 的大小: %d 字节\n",sizeof(b));// 相当于 sizeof(double)代码解释:
sizeof是C语言里的一个单目运算符,不是函数。- 用法很灵活:既可以写
sizeof(int),也可以写sizeof(变量名),算出来的结果是一回事。 - 它的计算单位是字节。
3. 【超级易错点】sizeof 在编译时求值,不执行里面的表达式
这是考试和面试最爱考的一个坑,看代码:
inti=10;intsize=sizeof(i++);printf("\n=== 3. 易错点测试 ===\n");printf("sizeof(i++) 结果: %d\n",size);printf("执行完这行后,i 的值: %d\n",i);代码解释:
- 运行结果:
size的值是4,而i的值依然是 10,不是 11! - 为什么?因为
sizeof在程序编译阶段就已经算出了i占 4 个字节,i++这个表达式根本不会在程序运行时执行。 - 这是初学者极易踩的坑,记住:sizeof 的括号里,只求类型,不搞计算。
4. 小结(翁恺原话精髓)
- 不同数据类型占用内存不同,有符号(
signed)和无符号(unsigned)的取值范围也不同。 - 写代码时,要养成用
sizeof看类型大小的习惯,知道你的变量到底占了多少字节,这对后续理解内存和指针至关重要。 - (STM32关联:以后写STM32,直接敲
uint8_t、uint32_t,占几个字节不用猜,代码移植也不会出错。)
这一节的核心就一句话:计算机用有限的二进制位存数字,最高位决定正负,由此推算出最大最小值。
6.2.4 整数的范围:如何推算整数类型的所能表达的数的范围,溢出了怎么办
这一节的核心就一句话:计算机用有限的二进制位存数字,最高位决定正负,由此推算出最大最小值。
1. 先看代码,感受“溢出”是什么
#include<stdio.h>intmain(){charc=127;// char 能存的最大正数c=c+1;// 加1,超出范围printf("char 127 + 1 = %d\n",c);unsignedcharuc=255;// 无符号 char 的最大值uc=uc+1;printf("unsigned char 255 + 1 = %d\n",uc);return0;}代码解释:
- 运行结果:
char 127 + 1 = -128,unsigned char 255 + 1 = 0。 - 这就是“溢出”。127 的二进制是
01111111,加1变成10000000。最高位变成1了,被计算机当成负数(补码),也就是 -128。 - 无符号的 255 是
11111111,加1直接变成100000000,超出的1被丢掉,剩下00000000,结果是 0。
2. 如何推算范围(公式推导)
一个类型占n个字节,就是8n个二进制位(bit)。
- 无符号(unsigned):没有符号位,所有位都用来存数值。
- 最小值:全0,即0。
- 最大值:全1,即
2^(8n) - 1。 - 例如
unsigned char(1字节):范围0 ~ 2^8-1 = 0 ~ 255。
- 有符号(signed):最高位被拿去做符号位(0正1负),剩下
8n-1位存数值。- 最大值:最高位0,后面全1,即
2^(8n-1) - 1。 - 最小值:最高位1,后面全0。因为计算机用补码,所以对应的是
-2^(8n-1)。 - 例如
char(1字节):范围-2^7 ~ 2^7-1 = -128 ~ 127。
- 最大值:最高位0,后面全1,即
3. 用代码验证类型的极限值
C语言在<limits.h>头文件中定义了各种类型的极值宏。
#include<stdio.h>#include<limits.h>intmain(){printf("=== 有符号 char ===\n");printf("最小值: %d\n",CHAR_MIN);printf("最大值: %d\n",CHAR_MAX);printf("\n=== 无符号 char ===\n");printf("最小值: %d\n",0);printf("最大值: %d\n",UCHAR_MAX);printf("\n=== int 类型 ===\n");printf("最小值: %d\n",INT_MIN);printf("最大值: %d\n",INT_MAX);return0;}代码解释:
- 输出结果会显示:
CHAR_MIN是 -128,CHAR_MAX是 127,UCHAR_MAX是 255。 INT_MIN是 -2147483648,INT_MAX是 2147483647。- 你可以把
CHAR替换成SHRT(short)、INT、LONG(long)来查其他类型。
4. 【易错点】printf 用%d打印无符号数会出问题
unsignedintu=4294967295;// 无符号 int 的最大值printf("用 %%d 打印: %d\n",u);// 结果是 -1printf("用 %%u 打印: %u\n",u);// 结果是 4294967295代码解释:
- 同样是 4 个字节的
11111111 11111111 11111111 11111111:- 用
%d(有符号)打印,最高位是1,计算机认为这是补码,算出是 -1。 - 用
%u(无符号)打印,最高位也当数值,算出是 4294967295。
- 用
- 这也是为什么你在开发时,如果看到一个大正数打印出来是负数,肯定就是数据类型的符号搞错了。
小结(推算口诀):
- n 个字节 = 8n 个二进制位。
- 无符号:
0到2^(8n) - 1。 - 有符号:
-2^(8n-1)到2^(8n-1) - 1。 - 最高位是符号位,存负数用补码。
- (STM32关联:ADC采集电压值用
uint16_t刚刚好,因为单片机ADC是12位的,最大也就4095,用无符号类型刚好合适,用有符号反而给自己找麻烦。)