知识梳理第一期
本人仅分享个人学习C语言过程中遇到的重难点问题以及踩坑,仅供参考。
本人使用的编程软件为VS 2026
1 . ASCII码值
ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是计算机中最基础的字符编码标准。它用 7 位二进制数(0~127)来表示 128 个字符,包括英文字母、数字、标点符号以及一些控制字符。理解 ASCII 码是理解 C 语言中字符与整数关系的第一步。
几组常用数据:
字符A~Z :65 ~ 90
字符a~ z: 97 ~ 122
实际上你只需要记住一共有26个字母,A对应65,且a与A的ASCII码值差值为32,即可轻松记住所有字母的ASCII码值。
数字字符0~9的ASCII码值从48 ~ 57
附表:ASCII码表
2 . 常用转义字符
\n换行符 将光标移动到下一行的开头
\0空字符 字符串的结束标志,ASCII 值为 0。
\反斜杠 表示它们“字面”的含义
"双引号 表示它们“字面”的含义
’单引号 表示它们“字面”的含义
?问号 在书写连续多个问号时使用,用于防止多个问号被编译器误认为是三字母词。
插播一下:三字母词(trigraph)是C语言的一种早期特性,用三个字符的序列(以 ?? 开头)来表示单个字符,例如 ??= 会被替换为 #、??/ 被替换为 \。虽然现代编译器默认已不推荐使用了,但标准仍保留了这一特性。? 的作用就是防止 ??? 被误解析为三字母词的开头。
八进制: \ddd(1~3 位八进制数字,例如 \101 代表 ‘A’,因为 A 的 ASCII 是 65,八进制为 101)
十六进制: \xdd(1~2 位十六进制数字,例如 \x41 代表 ‘A’,因为 A 的 ASCII 是 65,十六进制为 41)
3 . 数据类型
3.1 字符型
在C语言中用char表示字符类型
3.2 整型
在C语言中用int表示整型类型
3.3 浮点型
float:单精度浮点数,通常占 4 字节。
double:双精度浮点数,通常占 8 字节(精度更高,最常用)
long double:扩展精度浮点数,通常占 8、12 或 16 字节
3.4 布尔类型
_Bool: 用于表示真假
3.5 各种数据类型的长度
接下来内容我觉得对新手很不友好,先介绍一个关键字:
sizeof
装逼一点说sizeof是一个一元运算符,用于以字节为单位返回操作数类型或表达式的存储大小,结果类型为 size_t。
讲人话sizeof就是用来量数据在电脑里占了几个格子。
注意事项
sizeof 后面主要跟以下四类数据
1.1数据类型名称(必须加括号)
sizeof (int);// 测量基本类型
sizeof (double);// 测量浮点类型
sizeof (struct Node);// 测量自定义的结构体类型
sizeof ( int * );// 测量指针类型
1.2变量名(括号可省)
int a = 10;
sizeof a ;// 测量变量 a 的大小
1.3各种表达式(括号通常建议保留)
sizeof(10 + 3.14);// 结果是 8,因为 int + double 结果是 double 类型
sizeof(i++);// 结果是 4,且 i 的值不会增加
sizeof( func( ) );// 结果取决于 func() 的返回值类型(若返回 int 则为4),且 func() 不会被调用
注意:不能是函数本身:sizeof(func) 是非法的,因为函数名不能直接代表一个数据对象(但 sizeof(func()) 是合法的,因为它测量的是函数返回值的类型)。
1.4数组名(特殊)
在 C 语言中,数组名通常会自动退化为指针,但在 sizeof 后面是唯一的例外。当数组名作为 sizeof 的操作数时,它代表的是整个数组。
int arr[10];
sizeof(arr);// 结果是 40 (10个元素 × 4字节),而不是指针的大小(8)sizeof 的计算结果是size_t类型的。
size_t类型在 printf 中使用的专属占位符是%zu。.优先级陷阱(极易出错)
sizeof 作为一个一元运算符,它的优先级非常高(仅次于括号、后缀自增/自减等)。
现象:当它与其他运算符混合使用时,如果不加括号,很容易产生意想不到的结果。
示例:
int a = 10;
printf(“%zu\n”, sizeof a + 10);
// 错误直觉:先算 a+10,再求大小
// 实际执行:sizeof(a) + 10 -> 结果是 4 + 10 = 14
// 正确做法:如果真想算表达式的大小,必须加括号
printf(“%zu\n”, sizeof(a + 10));// 结果是 4
3.6 数据类型长度
3.6.1
char (1 字节)
bool(1 字节)
short (2 字节)
int (4 字节)
float (4 字节)
long (在 32位系统(或 Windows 下的 VS2026)中占4 字节,在 64位 Linux 系统中占 8 个字节)
long long (8 字节)
double (8 字节)
指针类型 (void *) (8 字节)
long double (在vs2026中占8 字节,在gcc环境中占16字节)
注意!!!:
如果是编程新手的小伙伴们,可能会被这些名词弄得晕头转向,所以我在下面列举一些我学习中遇到的困惑,希望能够帮助到大家。
Q :字节是什么鬼?
A :“字节”(英文叫 Byte,通常简写为 B)是计算机中用来表示存储空间大小的最基本计量单位,规定 8 个位(bit) = 1 个字节(Byte)。
那么bit又是什么呢?位(bit):是计算机最小的数据单位,只能存 1 个 0 或 1。
更具体点说,1 个字节由8 个 0 或 1组成(比如 01000001)。这 8 个 0 和 1 的组合,刚好可以表示 256 种不同的状态(0~255),足够用来表示英文字母、数字和标点符号了。
Q :double和float在使用中的区别是什么?
A :1.C 语言中,所有的小数常量(如 3.14)默认都是double 类型。
如果你写 float f = 3.14;,编译器会报警告(因为把高精度赋给低精度会丢失数据),必须写成float f = 3.14f;才行。
如果你直接用 double f = 3.14;,则完全合法且不会有任何警告。
2.float输入必须用%f。
double输入必须用%lf(如果用 %f 读入 double 会导致数据错误,因为%f只分配了4 字节的空间,而 double 需要8 字节。)。
输出时,float 用%f,double 用%f或%lf都可以。
3.注意**“精度丢失”**问题
float的极限:只有6~7 位有效数字。如果你写 float a = 123456.789f;,打印出来可能是 123456.789062,后面的数字已经错乱了。
double的表现:有15~16 位有效数字,能精确表示更多位数。
大数加小数的 “吞没 ” 效应:当 float 的数值非常大时(例如 16777216.0f),当你加10000,结果会正常变成 16787216.0f,但是如果给它加 1,结果依然是 16777216.0f。因为它的精度不够,根本表示不出这个 +1 的变化。
4.绝对不要直接用 “==” 比较浮点数
由于上述的精度丢失问题,浮点数的计算结果往往带有微小的误差。
错误示范:if (0.1 + 0.2 == 0.3)。这个判断在 C 语言中是假(False)的。
正确做法:通过判断两个数的差值是否小于一个极小值(误差容限)来比较。例如:
#include <math.h>
#define EPS 1e-6
if (fabs(a - b) < EPS) { … }
如果你有兴趣了解上面这段代码,可以自行去问下AI,在这里我不过多赘述。
5.在实际开发中,绝大多数情况下默认推荐使用double。
在现代计算机的 CPU 架构下,处理 double 和 float 的速度差距已经非常小了,日常应用几乎感觉不到性能损耗。
Q :short,long,long long是什么意思?
**A :**在 C 语言中,short、long和long long都是整型(Integer)的修饰词。
使用建议:
默认用 int:95% 以上的情况,普通的 int 就完全够用了。
需要大数用 long long:如果你在做算法题,发现普通的 int 算出来结果不对(溢出了),直接无脑换成 long long。
尽量别用 long:因为 long 在不同系统下大小不一样(Windows 下是 4 字节,Linux 下是 8 字节),跨平台移植时容易出 Bug。
3.7 signed和unsigned
C 语言使用 signed 和 unsigned 关键字修饰字符型和整型类型。
signed关键字,表示一个类型带有正负号,包含负值;unsigned关键字,表示该类型不带有正负号,只能表示零和正整数。
对于int类型,默认是带有正负号的,也就是说int等同于signed int。
由于这是默认情况,关键字signed一般都省略不写,但是写了也不算错。
Q :使用unsigned的好处是什么?
A :同样长度的内存能够表示的最大整数值,增大了一倍。
比如,16位的signed short int的取值范围是: -32768~32767,最大是32767;而
unsigned short int的取值范围是: 0~65535,最大值增大到了65535。
unsigned int里面的int可以省略,所以以下两行代码效果相同。
1unsigned int a;
2unsigned a;
字符类型char也可以设置signed和unsigned。
1signed char c;// 范围为 -128 到 127
2unsigned char c;// 范围为 0 到 255
注意,C语言规定char类型默认是否带有正负号,由当前系统决定。
这就是说,char不等同于signed char,它有可能是signed char,也有可能是unsigned char。
日常使用时:
如果你只是把 char 当作纯粹的字符来使用(比如存英文字母、标点符号,或者处理普通的文本字符串),直接写 char 即可。
当你把 char 当作极小的整数来参与数学计算、或者处理底层数据时,必须明确加上修饰词。
这一点与int不同,int就是等同于signed int。
- 接下来我们要学习一个比较深入的概念。
在 C 语言中,字符(char)本质上就是整数(数字)
之前我已经粗略介绍过ASCII 码表, 计算机不知道什么是字母 ‘A’,什么是汉字,它只认识数字(0 和 1 的组合)。
在 C 语言中,char(character)虽然名字叫“字符”,但它在内存中实际上就是一个占 1 个字节的小整数。当你写char c = ‘A’;时,计算机在内存里实际存下的数字是 65(因为 ASCII 表规定 A 对应 65)。
当你写char c = ‘a’;时,计算机存下的数字是 97。
当你写char c = ‘0’;时,注意,这不是数字 0,而是字符 0,它在内存里存下的数字是 48。
Q :既然 char 本质上就是数字,那我直接用 int 不就行了?为什么还要搞个 char?
A :因为int 通常占 4 个字节,而 char 只占 1 个字节。如果你只是存一个字母,用 int 会浪费 75% 的空间。并且分不同情境是使用 int 和 char,可以使语义更清晰。
例:当你写下 char c = ‘A’; 时,任何看到这段代码的程序员都会立刻明白:“哦,这里存的是一个字符”。
如果你写 int c = 65;,别人看代码时会疑惑:“这是一个计数器?还是数组下标?还是某个状态码?” 你必须额外写注释去解释它其实是个字符,增加了沟通成本。
同时,我必须要解释另一个重要的问题:
在 C 语言中,变量最终被打印成什么样子,完全取决于你使用的 % 占位符(格式说明符),而不是变量本身的类型。
例:
1.char c = ‘A’;
底层真相:内存里存的是数字 65。
输出%c:printf(“%c”, c); 👉 告诉编译器:“把它当字符看”,输出 A。
输出%d:printf(“%d”, c); 👉 告诉编译器:“把它当整数看”,输出 65。
2.int c = 65;
底层真相:内存里存的也是数字 65。
输出%d:printf(“%d”, c); 👉 告诉编译器:“把它当整数看”,输出 65。
输出%c:printf(“%c”, c); 👉 告诉编译器:“把它当字符看”,输出 A。
以上是我个人学习中遇到的难点问题,希望能够对你有帮助!
虚心接受一切批评与指正,欢迎讨论!