第 6 章 数据类型
6.5 获取数据存储大小
sizeof 运算符,可以计算出指定数据的【字节大小】
结果是 size_t 类型的数据(无符号整数值),对应的格式占位符是 %zu
( size_t
的大小取决于操作系统架构,在32位系统中,size_t
被定义为unsigned int
,占用4个字节的内存空间;而在64位系统中,size_t
被定义为unsigned long
,占用8个字节的内存空间。)
使用说明:
计算指定数据的字节大小
1、sizeof 和 数据类型名称 一起使用 eg:
printf("char:%zu \n",sizeof(char));
2、sizeof 和 变量 可以一起使用 eg:
printf("num占用的存储长度: %zu \n", sizeof num );
//变量(常量同理)可以省略小括号,数据类型不可以省略(因为是特殊字符)
3、sizeof 和 常量 可以一起使用 eg:
printf("%zu \n", sizeof 8.8L);
使用变量将 sizeof 的计算结果存下来
size_t a = sizeof 3.4; printf("%zu \n", a);
6.6 数据类型转换
① 自动类型转换
1. 运算过程中的自动类型转换 (窄类型->宽类型)
① 不同类型的整数之间: ① 窄类型->宽类型 ② 有符号 -> 无符号 ③ char 和 short 都会转为 int 再运算
② 不同类型的浮点之间: 精度小->精度大
③ 整数和浮点之间:整数 -> 浮点
2. 赋值过程中的自动类型转换
给变量赋值的时候,值会 自动转为变量的类型;
可能会发送宽类型转窄类型,造成精度损失
eg:/ 3000 补码:00000000000000000000101110111000
// 将 3000 存到 8bit 中,存后8位 1011 1000
——> 反码:1011 0111——> 源码:1100 1000
注:计算机上存储的是 补码,计算之后还是补码,读取显示时:需要把补码转化位原码
eg:赋值转换
1、char类型:
char c = 200;
printf("c=%d \n", c); // -56,由于200超过c的数字表示范围,把200表示为int类型,取后八位:
// 补码:1100 1000
// 原码:1011 1000 —— -56
printf("c=%u \n", c); // %u是int类型的格式占位符,会把-56表示为int类型的无符号整数
// -56 int类型:
// 原码:10000000000000000000000000111000
// 补码:11111111111111111111111111001000 ——补码按无符号表示:4,294,967,240
return 0;
2、int -> char类型
// 3000 补码:00000000000000000000101110111000
// 将 3000 存到 8bit 中,存后8位 1011 1000 ——> 反码:1011 0111——> 源码:1100 1000
int n4 = 3000;
char n5 = n4;
printf("n5=%d \n", n5); // 有符号整型 -72
② 强制类型转换
(数据类型) 数据
注:当 数据 为一个表达式时,应改变表达式中其中一个 元素 的数据类型
第 7 章 运算符
运算符: 运算符是一种特殊的符号,用于数据的运算、赋值和比较等。
操作数: 运算符运算的数据。
表达式: 表达式指的是一组操作数、运算符的组合,表达式一定具有值 ,一个变量一个常量也是表达式。
运算符4要素: 含义和功能、操作数个数、所组成表达式的值、该运算符有无副作用
运算符分类(按操作数个数): 一元运算符、二元运算符、三元运算符
运算符分类(按功能): 算术运算符、关系(比较)运算符、逻辑运算符、位运算符、赋值运算符、其他运算符
7.1 算术运算符
1. 正号、负号(+ , -) ——无副作用
正号: 一元运算符; 所组成表达式的值:操作数作为表达式的值; 无副作用
负号: 一元运算符: 所组成表达式的值:操作数取反作为表达式的值;无副作用
2. 加、减、乘、除(+,-,*,/) ——无副作用
二元运算符、无副作用
3. 取余(取模)(%)
① 表达式的值的符号(正负)与第一个操作数一致
② 取余运算符的操作数必须都是 整数
-
递增、递减(++,--) ——有副作用
① 递增、递减运算符可以在操作数前面,也可以在后面
② 运算符在前在后对【操作数的副作用是 相同的】
③ 【表达式的值】:
如果运算符在后(n++),取操作数自增或自减之 前 的值作为表达式的值如果运算符在前(++n),组操作数自增或自减之 后 的值作为表达式的值
特殊使用说明:
复杂表达式中的两个子表达式都带有副作用,且副作用针对同一个变量:
C标准未作出规定,未规定计算顺序,由编译器自行决定
//强烈不建议写该形式
eg: s = (++ n) + (++ n);
printf("s=%d", s); //无法确定输出的值
注意:带有副作用的运算符要求 操作数 必须是 变量的形式!
7.2 关系(比较)运算符
1. 包括: >、 >=、 <、 <=、 ==、 !=
2. 都是 2 个操作数
3. 表达式的值是 0 或者 1,是 int 类型
比较的时候,有符号转无符号之后再进行比较
7.3 逻辑运算符
真表示的是 非零;假表示的是 0
1. 逻辑与 && // 可以称为and、并且
表达式的值: 两个操作数都为真(非0),表达式的值才是1,否则是0。
逻辑与短路: 如果第一个操作数为假,第二个操作数直接不会执行
2. 逻辑或 ||
表达式值: 两个操作只要一个为真,表达式值就是1,只要两个操作数都为假,表达式的值才是0
逻辑或短路:如果第一个操作数为真,第二个操作就不会执行
3. 逻辑非 !
一元运算符
表达式的值:操作数为真,表达式的值是0,操作数为假,表达式的值是1
7.4 位运算符
计算机上存的是补码,用补码计算后需转换为原码
1. 按位与:&; 按位或:|; 按位异或:^ ——需要有两个操作数
2. 按位取反: ~ ——(只有一个操作数)
3. 按位左移: <<; 按位右移: >>
【左移 值变大,(*2的移动位数的次方);右移 值变小,(/2的移动位数的次方)】
/**
* 98 向左移动2位 9800 向左移动8位 98*10^8
* 192 向右移动1位 19.2
*/
/**
十进制数:
** 98 向左移动2位 9800 向左移动8位 98*10^8*
** 192 向右移动1位 19.2*
得出二进制数:
** 向左移动2位:原数 * 2^2*
** 向右移动3位:原数 / 2^3* ——如得到小数,遵循越舍越小的原则(右移数字变小)
** **/
总结
数据类型转换
1. 自动类型转换(隐式转换)
1.1 运算过程中
① 整数之间:窄类型->宽类型;有符号->无符号; char和short运算中转为int
② 浮点之间:精度小—>精度大
③ 整数和浮点数: 整数->浮点
1.2 赋值过程中
2. 强制类型转换(显示转换)
(类型名)数据
运算符
1. 运算符4要素
功能、操作数个数、所组成的表达式的值、有无副作用
2. 算术运算符
+ - * /
%
+ -
++ --
3. 关系(比较)运算符
> >= < <=
== !=
4. 逻辑运算符
&&
||
!
5. 位运算符
& | ^
~ ——按位取反
<< >>
附录
再 tasks.json 中添加,提高警告等级:
"-Wconversion",
"-Wextra",
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)