signed ,unsigned 关键字

本文详细解释了整型数据在内存中的存放形式,包括有符号和无符号整型的表示范围,以及如何使用补码进行加减运算。同时,通过实例分析了char型数据在负数表示上的特点,以及溢出现象的产生和解决方法。

整型数据在内存中的存放形式

数据在内存中是以二进制形式存放的

而signed int 表示有符号基本整型

unsigned int 表示无符号基本整型

数值都是以补码形式表示的,一个正数的补码就是其本身,一个负数的补码就是对这个数按位取反然后加1

 

unsigned int 类型整数其值表示法
范围为::0~ 2^32 -1

unsigned char类型整数其值表示法
范围为::0~ 2^8-1

这两个好理解 int型的是32位从0开始所以是0~ 2^32 -1 char型的是8为即是0~255

signed int 类型整数其值表示法
范围为::-2^31 ~ 2^31 -1

signed char类型整数其值表示法
范围为::-2^7~ 2^7-1

 这是一种补码规则

就char型的来说

正数部分 数值    在内存中的表现形式

                   0         00000000

                   1         00000001

                   2         00000010

                  ...

                  127     011111111

再加个1 就成为了负数的--128                       

                  -128    10000000

                  -127    10000001

                  -126    10000010

                  ...

                   -1        11111111

-1~-128 正好128个数 0~127也正好为128个数 加起来是256个数

有了补码就可以实现正常的相加减  如 1+(-128) = -127  用补码相加 00000001+10000000=10000001 而10000001就是-127 正好符合。

-0和+0的区别

零在计算机里就是0,不存在正负一说。

0和正数的补码都等于原码,也就是平时说的2进制数。

负数的补码是符号位置一的情况下,对原码求反,再加一得到的。

-0 就是对1 0000  0000 取反加1 得到结果还是00000000 即为+0;

举两例子下面是摘抄下来的

int main()
{
     char a[1000];
     int i;
     for(i=0; i<1000; i++)
     {
             a[i] = -1-i;
     }
     printf("%d",strlen(a));
     return 0;
}

打印的结果是255

按照负数补码的规则,可以知道-1 的补码为0xff,-2 的补码为11111110……当i 的值为127
时,a[127]的值为-128,而-128 是char 类型数据能表示的最小的负数。当i 继续增加,a[128]
的值肯定不能是-129(1 0111 1111)。因为这时候发生了溢出,-129(1 0111 1111)需要9 位才能存储下来,而char 类型数据只有8 位,所以最高位被丢弃。剩下的8 位是原来9 位补码的低8 位的值,即0x7f。
当i 继续增加到255 的时候,-256 的补码的低8 位为0。然后当i 增加到256 时,-257 的补
码的低8 位全为1,即低八位的补码为0xff,如此又开始一轮新的循环……
按照上面的分析,a[0]到a[254]里面的值都不为0,而a[255]的值为0。strlen 函数是计
算字符串长度的,并不包含字符串最后的‘\0’。而判断一个字符串是否结束的标志就是看
是否遇到‘\0’。如果遇到‘\0’,则认为本字符串结束。
分析到这里,strlen(a)的值为255 应该完全能理解了。这个问题的关键就是要明白char
类型默认情况下是有符号的,其表示的值的范围为[-128,127],超出这个范围的值会产生溢
出。另外还要清楚的就是负数的补码怎么表示。弄明白了这两点,这个问题其实就很简单了。

在看一个

#include <stdio.h>
void foo(void)
{
       unsigned int a = 6;
       int b = -20;
       (a+b>6)? puts(">6"):puts("<=6");
}

 int main()
{
       foo();
       return 0;
}

问输出什么?

打印出>6

问题很好解决b=-20 先要求它的的补码然后进行相加。

### C++ 中 unsigned 关键字的含义和用法 #### 1. 定义与基本特性 在 C++ 中,`unsigned` 是一个关键字,用于声明无符号类变量。无符号类意味着该变量只能存储非负整数值(即零或正数)。通过使用 `unsigned`,可以扩展变量的正数范围,因为其所有位都用于表示正值[^1]。 例如,一个标准的 `int` 类通常占用 4 字节(32 位),其取值范围为 -2,147,483,648 到 2,147,483,647。而 `unsigned int` 的取值范围则为 0 到 4,294,967,295。这种扩展使得 `unsigned` 类非常适合需要处理大数值但不需要负数的场景。 ```cpp unsigned int max_value = 4294967295; // 最大值示例 ``` #### 2. 数据类结合 `unsigned` 可以与多种整数类结合使用,包括但不限于: - `unsigned char` - `unsigned short` - `unsigned int` - `unsigned long` - `unsigned long long` 每种类的大小和范围取决于目标平台的编译器实现。例如,在大多数现代系统中: - `unsigned short` 的范围是 0 到 65,535。 - `unsigned long long` 的范围是 0 到 18,446,744,073,709,551,615。 #### 3. 使用场景 以下是 `unsigned` 的典使用场景: - **数组索引**:由于数组索引始终是非负数,因此 `unsigned` 是一种自然选择。 ```cpp unsigned int index = 10; std::cout << "Element at index: " << array[index] << std::endl; ``` - **计数器**:当循环计数器仅需非负值时,`unsigned` 提供了更大的上限。 ```cpp for (unsigned int i = 0; i < large_number; ++i) { // 循环体 } ``` - **位操作**:在涉及位掩码或位字段的操作中,`unsigned` 类能够避免意外的符号扩展问题。 ```cpp unsigned int flags = 0x0F; if (flags & 0x01) { std::cout << "Flag 0 is set." << std::endl; } ``` #### 4. 注意事项 尽管 `unsigned` 提供了更大的正数范围,但在实际编程中需要注意以下几点: - **溢出行为**:`unsigned` 类在发生溢出时会进行模运算,这可能导致意外结果。例如,`unsigned int x = -1;` 实际上会将 `x` 设置为其最大值[^1]。 ```cpp unsigned int x = -1; // 等价于 x = 4294967295 std::cout << "x: " << x << std::endl; ``` - **混合类运算**:当 `unsigned` 和 `signed` 类混合运算时,可能会导致隐式类转换,从而引发错误或不符合预期的结果[^1]。 ```cpp int a = -1; unsigned int b = 1; if (a < b) { // 此条件可能不按预期工作 std::cout << "a is less than b" << std::endl; } ``` #### 5. 示例代码 以下是一个综合示例,展示 `unsigned` 的使用及其注意事项: ```cpp #include <iostream> int main() { unsigned int count = 0; while (count < 5) { std::cout << "Count: " << count << std::endl; ++count; } // 溢出示例 unsigned int overflow = 0; --overflow; // 溢出,结果为最大值 std::cout << "After decrement: " << overflow << std::endl; return 0; } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值