感悟int 和unsigned int——大小端内存分配。

本文通过Intel笔试题实例,详细解析了位段结构在内存中的存储方式及其如何影响变量的值。介绍了小端模式下的数据存储顺序,并展示了如何通过位操作实现特定值的设置与读取。

在学习结构体成员位段的时候,遇到了这么一道题:

 

又如intel的笔试题:

#include      “stdafx.h”   

  #include   <iostream.h>   

  struct   bit  

  {   

int   a:3; 

    int   b:2; 

    int   c:3;

  };

  int   main(int   argc,   char*   argv[])    

  {     

bit   s;     

  char   *c   =   (char*)&s;     

  *c   =   0x99;     

  cout<<s.a<<endl<<s.b<<endl<<s.c<<endl;   

  return   0;     

  }

 Output:?  

 运行的结果是   1   -1   -4  

结构bit的成员在内存中由低地址到高地址顺序存放,执行 *c=0x99;后成员的内存分布情况为:

 

 

注意:我们通常用的pc都是intel的CPU。xp系统,都是小段模式:也就是。一个整数的高位存在高地址上。低位存在低地址上。还不通俗么?这么说吧。一个整数。千位存的地址位比百位的要大。百位存的地址比十位的要大。十位存的地址比个位要大。这么说可能更糊涂。如果计算机中用十进制存数据的话。那么就是这样的。只不多是在计算机中是以二进制存的。也就是。假设一个二进制为abcd。四位的二进制。a、b、c、d、四个字母可为0或1.那么这个二进制表达的十进制为:a*2^3+b*2^2+c*2^1+d。所以在小端模式下。a的地址比b高。b的地址比C高。c的地址比d高。存储的时候,地址由小到大里面存的应该是dcba。

我想我我说的更清楚了吧。

 

对比上图:a对应的地址存的二进制应该是int 类型 的二进制001。b对应的地址里面存的是二进制11(int)。c对应的地址里面存的应该是二进制100(int)。

知道我什么强调这些二进制是int类型的么?

因为这些二进制是以int类型存储在计算机里的。

 

读出的时候,我们会把他们按照%d的格式读出。

 

我说的是废话么?

 

这个时候,计算机知道你要将他们按照%d的格式读出,那么,计算机这道每个二进制的最左位为正负标志位。

 

那么int类型的二进制110。减1后为011.取反码为100.也就是其十进制为-4.

我们知道,int类型存储时,是按照补码的形式存储的。在32位的系统中,最左侧为正负标志位。右侧31位为数据位。标志的范围为-2^31至2^31-1。在本例中,已是如此的。只是该处的int类型是用3位来标识的。取值范围为-4到3.共8个数。3位的int型无法标识4。

 

`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` 移动整个类型大小),而整数直接参与数值运算。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值