unsigned int 相减的妙处

本文通过实验验证了在Arduino中使用定时器时,即使定时器溢出清零,计算的时间间隔仍然准确。通过递增两个unsigned int变量并保持它们之间的固定差值,展示了即使在清零发生后,两者间的差值依然保持不变。

arduino 中定时器会清零,当我计算两个时间的间隔,是否会受到清0的影响,答案是不会的

在arduino中做了试验如下

unsigned int i, j=10000;


void loop() {
     i += 10000;
     j += 10000;
     Serial.print("i:");Serial.println(i);
     Serial.print("j:");Serial.println(j);
     Serial.println( j-i);
     delay(500);
}

让两数保持 10000 的间隔,而后递增10000

i:10000
j:20000
10000
i:20000
j:30000
10000
i:30000
j:40000
10000
i:40000
j:50000
10000
i:50000
j:60000
10000
i:60000
j:4464
10000
i:4464
j:14464
10000
i:14464
j:24464
10000
i:24464


可以看到 4465-60000 还是 10000

`unsigned int` 和 `unsigned int*` 是 C/C++ 中两种完全不同的类型,分别表示**无符号整数**和**指向无符号整数的指针**。以下是它们的详细区别和用途: --- ### **1. 类型定义与存储内容** | 类型 | 存储内容 | 示例 | |--------------------|---------------------------------|-----------------------------| | `unsigned int` | 一个无符号整数(通常是 4 字节) | `unsigned int x = 42;` | | `unsigned int*` | 一个内存地址,指向 `unsigned int` 类型 | `unsigned int* p = &x;` | - **`unsigned int`**: 直接存储整数值(如 `0`, `100`, `4294967295`),占用固定字节数(通常 4 字节)。 - **`unsigned int*`**: 存储一个内存地址(如 `0xFFFF0000`),指向某个 `unsigned int` 变量的存储位置。指针本身的大小取决于系统(32 位系统 4 字节,64 位系统 8 字节)。 --- ### **2. 用途对比** #### **(1) `unsigned int` 的用途** - **存储数值**: 用于表示非负整数(如计数器、位掩码、哈希值等)。 ```c unsigned int age = 25; // 存储年龄 unsigned int flags = 0b1010; // 存储二进制标志 ``` - **算术运算**: 支持加减乘除、位操作等。 ```c unsigned int a = 10, b = 20; unsigned int sum = a + b; // 结果为 30 ``` #### **(2) `unsigned int*` 的用途** - **间接访问内存**: 通过指针操作另一个 `unsigned int` 变量的值。 ```c unsigned int x = 100; unsigned int* p = &x; // p 指向 x 的地址 *p = 200; // 修改 x 的值为 200 ``` - **动态内存管理**: 与 `malloc`/`free` 配合使用,分配和释放堆内存。 ```c unsigned int* arr = (unsigned int*)malloc(10 * sizeof(unsigned int)); arr[0] = 42; // 通过指针访问数组元素 free(arr); // 释放内存 ``` - **函数参数传递**: 通过指针修改外部变量的值(避免值传递的开销)。 ```c void modify(unsigned int* ptr) { *ptr = 1000; } unsigned int y = 0; modify(&y); // y 被修改为 1000 ``` --- ### **3. 关键区别** | 特性 | `unsigned int` | `unsigned int*` | |---------------------|-------------------------|-------------------------------| | **存储内容** | 整数值 | 内存地址 | | **大小** | 固定(如 4 字节) | 依赖系统(32/64 位) | | **算术运算** | 直接支持(如 `x + 1`) | 指针算术(如 `p + 1` 移动 `sizeof(unsigned int)` 字节) | | **解引用** | 不适用 | 通过 `*p` 访问指向的值 | | **用途** | 存储数据 | 操作内存、传递引用、动态分配 | --- ### **4. 常见操作示例** #### **(1) `unsigned int` 操作** ```c unsigned int a = 10; unsigned int b = a << 1; // 左移一位,b = 20 unsigned int c = a & 0xF; // 按位与,c = 10 (0xA & 0xF = 0xA) ``` #### **(2) `unsigned int*` 操作** ```c unsigned int x = 42; unsigned int* p = &x; // 指针算术 unsigned int* q = p + 1; // q 指向 x 之后的下一个 unsigned int *q = 100; // 如果 x 是数组的一部分,这会修改下一个元素 // 动态内存 unsigned int* dynamic_arr = (unsigned int*)malloc(5 * sizeof(unsigned int)); dynamic_arr[0] = 1; // 通过指针访问数组 free(dynamic_arr); ``` --- ### **5. 注意事项** 1. **指针算术的步长**: `p + 1` 会移动 `sizeof(unsigned int)` 字节(通常是 4 字节),而非 1 字节。 ```c unsigned int* p = (unsigned int*)0x1000; unsigned int* q = p + 1; // q 的地址是 0x1004(假设 4 字节对齐) ``` 2. **野指针风险**: 未初始化的指针(如 `unsigned int* p;`)可能导致未定义行为。 ```c unsigned int* p; // 危险!未初始化 *p = 100; // 崩溃或数据损坏 ``` 3. **类型匹配**: 指针类型必须与指向的数据类型匹配,否则可能引发严格别名规则(Strict Aliasing)问题。 ```c float f = 3.14; unsigned int* p = (unsigned int*)&f; // 危险!违反类型规则 ``` --- ### **关键总结** 1. **`unsigned int`**:直接存储和操作无符号整数值。 2. **`unsigned int*`**:存储内存地址,用于间接访问或操作 `unsigned int` 类型的数据。 3. **核心区别**: - `unsigned int` 是数据,`unsigned int*` 是数据的地址。 - 指针支持算术运算(如 `+1` 移动整个类型大小),而整数直接参与数值运算。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值