24_grade_C/笔记/第三课.md
2025-03-07 12:21:06 +08:00

291 lines
7.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 知识点
#### **1. 变量类型及其占用空间**
在C语言中变量类型决定了变量可以存储的数据范围以及占用的内存空间大小。以下是四种常见变量类型的详细信息
| 变量类型 | 占用空间 | 数据表示范围 | 说明 |
| :------- | :------- | :-------------------------------- | :----------------------------------------------------------- |
| `int` | 4字节 | -2,147,483,648 到 2,147,483,647 | 用于存储整数,范围约为 -21亿 到 +21亿。 |
| `float` | 4字节 | 约 ±3.4e-38 到 ±3.4e+38 | 单精度浮点数可存储小数但精度有限约6-7位有效数字。 |
| `double` | 8字节 | 约 ±1.7e-308 到 ±1.7e+308 | 双精度浮点数可存储更大范围和更高精度的小数约15位有效数字。 |
| `char` | 1字节 | -128 到 127 或 0 到 255无符号 | 用于存储单个字符通常表示ASCII码0-127。 |
#### **2.数据表示范围的限制**
- **`int` 类型**
- 范围有限,超出范围会导致溢出。例如:
```c
int a = 2147483647; // int 的最大值
a = a + 1; // 溢出,结果未定义
```
- 解决方法:使用更大范围的类型(如 `long long`)。
- **`char` 类型**
- 只能表示有限数量的字符ASCII码为0-127
- 如果需要表示更多字符如中文可以使用多字节编码如UTF-8
- **浮点数类型**
- `float` 和 `double` 虽然可以表示小数,但精度有限。
- 例如:
```c
float f = 0.1f;
printf("%.20f\n", f); // 输出 0.10000000149011611938(精度损失)
```
#### **3. 类型转换**
在C语言中类型转换分为两种**隐式类型转换** 和 **强制类型转换**。
##### **1隐式类型转换**
- 编译器自动进行的类型转换,通常发生在不同类型的数据进行运算时。
- 规则:将低精度类型转换为高精度类型(如 `int` → `double`)。
- 示例:
```c
int i1 = 5, i2 = 2;
double d = 1.0 * i1 / i2; // 隐式将 i1 和 i2 转换为 double 类型
printf("隐式类型转换后的值为: %lf\n", d); // 输出 2.500000
```
##### **2强制类型转换**
- 程序员手动指定类型转换,使用 `(目标类型)` 语法。
- 示例:
```
int i1 = 5, i2 = 2;
double d = (double)i1 / i2; // 强制将 i1 转换为 double 类型
printf("强制类型转换后的值为: %lf\n", d); // 输出 2.500000
```
------
#### **4. 示例代码**
以下代码演示了类型转换的使用场景:
```c
#include <stdio.h>
int main() {
int i1 = 5, i2 = 2;
double d;
// 未进行类型转换
d = i1 / i2; // 结果为 2.000000(小数部分被丢弃)
printf("未进行类型转换的值为: %lf\n", d);
// 强制类型转换
d = (double)i1 / i2; // 将 i1 转换为 double 类型
printf("强制类型转换后的值为: %lf\n", d);
// 隐式类型转换
d = 1.0 * i1 / i2; // 通过 1.0 触发隐式转换
printf("隐式类型转换后的值为: %lf\n", d);
return 0;
}
```
**输出结果**
```
未进行类型转换的值为: 2.000000
强制类型转换后的值为: 2.500000
隐式类型转换后的值为: 2.500000
```
变量类型占用的空间有限那么使用时数据的表示范围也就有限例如int类型数据表示范围是**-21亿到+21亿**而char字符只占一个字节理论上能表示256种数据足够表示ASCII码的128个字符。
之前我们在做运算时,会发现两个整数相除,小数位会被自动丢弃掉,那如果我们不想丢弃小数,就只能使用类型转换了,将整数类型给他转换为小数类型。
类型转换分为强制类型转换和隐式类型转换,下面用代码方式演示
```c
#include <stdio.h>
int main() {
int i1 = 5, i2 = 2;
double d;
d = i1 / i2;
printf("没有进行类型转换的值为:%lf\n", d);
d = (double)i1 / i2; // 在变量名前写上想要转换的类型,即可转换为该类型
printf("强制类型转换后的值为:%lf\n", d);
d = 1.0 * i1 / i2;
printf("隐式类型转换后的值为:%lf\n", d);
return 0;
}
```
#### **5. 注意事项**
1. **精度损失**
- 强制类型转换可能导致精度损失,尤其是从高精度类型转换为低精度类型时。
- 例如:
```c
double d = 3.14;
int i = (int)d; // i 的值为 3小数部分丢失
```
2. **溢出问题**
- 当数据超出目标类型的表示范围时,会导致溢出。
- 例如:
```c
int i = 2147483647; // int 的最大值
i = i + 1; // 溢出,结果未定义
```
3. **隐式转换的陷阱**
- 隐式转换可能导致意外的结果,尤其是在混合类型运算时。
- 例如:
```c
int i = 5;
float f = i / 2; // f 的值为 2.000000(未触发隐式转换)
```
------
#### **6. 总结**
- **变量类型**决定了数据的表示范围和占用空间。
- **类型转换**分为隐式转换和强制转换,用于在不同类型之间进行数据转换。
- 使用类型转换时,需注意精度损失和溢出问题。
# 练习
```
1.
输入如下格式数据
(404) 817-6900
转换成如下格式输出
404.817.6900
```
```c
#include <stdio.h>
int main() {
int a, b, c;
scanf("(%d) %d-%d", &a, &b, &c);
printf("%d.%d.%d", a, b, c);
return 0;
}
```
```
2.
计算两个分数相加的结果,结果无需约分
输入
5/6+3/4
输出
38/24
```
```c
#include <stdio.h>
int main() {
int a, b, c, d;
int fenzi, fenmu;
scanf("%d/%d+%d/%d", &a, &b, &c, &d);
fenzi = a * d + b * c;
fenmu = b * d;
printf("%d/%d", fenzi, fenmu);
return 0;
}
```
```
3.
输入一个数字x代表需要支付的钱数现有100元20元5元1元纸币若干张想要使用最少的纸币去结清账款请你计算怎么付可以让付出去的纸币数量最少
输入
256
输出
付了2张100元还需要支付56元
付了2张20元还需要支付16元
付了3张5元还需要支付1元
付了1张1元支付完成
```
```c
#include <stdio.h>
int main() {
int x; // 需要支付的钱款数额
int a100, a20, a5, a1; // a100代表100元纸币需要多少张依次类推
printf("请输入:");
scanf("%d", &x);
a100 = x / 100; // 通过除以100来计算需要付多少100张的纸币并且C语言中整数相除可以自动舍弃小数
x = x % 100; // 计算余数看付完100元的纸币后接下来还需要付多少钱
printf("付了%d张100元还需要支付%d元\n", a100, x);
a20 = x / 20;
x %= 20; // 简写方式,等同于 x = x % 20;
printf("付了%d张20元还需要支付%d元\n", a20, x);
a5 = x / 5;
x %= 5;
printf("付了%d张5元还需要支付%d元\n", a5, x);
printf("付了%d张1元支付完成\n", x);
return 0;
}
```
```
4.
编写一个程序,输入一个四位数,分别取出他的个十百千位上的数字
输入
1234
输出
```
```c
#include <stdio.h>
int main() {
int x;
int ge, shi, bai, qian;
printf("请输入:");
scanf("%d", &x);
// 直接除10取得的余数就是个位的
ge = x % 10;
// 除以10将十位上的数移动到个位上然后取余10就可以拿到十位上的数
shi = x / 10 % 10;
// 先取余1000可以理解为干掉千位以上的数留下的三位数在除100干掉后面两位数
bai = x % 1000 / 100;
// 除1000直接干掉个十百位数剩下的就是千位了
qian = x / 1000;
printf("个位上的数为:%d\n", ge);
printf("十位上的数为:%d\n", shi);
printf("白位上的数为:%d\n", bai);
printf("千位上的数为:%d\n", qian);
return 0;
}
```