C语言-------数据类型中signed、unsigned他们在不同数据类型中存储的不同体现并且与printf关系的总结。

简介: C语言-------数据类型中signed、unsigned他们在不同数据类型中存储的不同体现并且与printf关系的总结。

数据类型中signed、unsigned他们在不同数据类型中存储的不同体现:

如:char a = -1;

在将-10放进内存中时,首先你需要知道内存中存的都是补码所以应该将-10换成补码即为:0x FF FF FF FF :11111111111111111111111111111111此时若要放进char中就要发生截断成8bit 即为 0x FF :11111111

unsigned char b = -1;

同理:最终放进内存中的值为:11111111

但是你需要知道此时的11111111中的第一位将不再看作符号位

signed char c = -1;

同理:11111111

第一位将看作符号位,当然光的char和此处也是一样的

因为unsigned存在时其符号位将不存在所以此时的unsigned char a = -1;存在内存中的数值已将变成一个正数也就是11111111(255) 所以unsigned char a = -1其实存的是char类型中最大的值(11111111),他不会再通过补变回原码

所以当我们在打印时会有:

int main()
{
  char a = -1;
  unsigned char b = -1;
  signed char c = -1;
  printf("%d %d %d", a, b, c);//-1 255 -1
  return 0;
}

那具体是如何实现打印的呢?

由前面我们可以知道,所有的数值都是以补码的形式存进内存中的。并且char 与 signed char 是相同的。所以,其实a、b、c存在内存中是一样的都是11111111,但是当我们在printf中进行使用时就会有不同(a、c一起看)

并且因为打印的是%d是有符号的整数所以在要打印的数据也应该为一个整形,所以如short、char这种小于int类型的就要进行整形提升(并且注意只要小于int类型的当遇到操作符时就会进行整形提升)

a:的补码11111111,

首先,需要进行整形提升(隐式提升,若忘了可以看->操作符的目录进行查看)补符号位:11111111111111111111111 111111111

其次,再转化成原码(因为是负数):10000000 00000000 00000000 00000001

最终:再进行打印(原码转化成10进制的值): -1


b的补码11111111

首先,需要进行整形提升补符号位,因为此处的b是一个无符号的字符类型所以其为一个正数,补符号位0:000000000000000000000000 111111111

其次再转化成原码,但此时符号位为0即为正的所以原反补相同就不需要再进行改变;

最终:再进行打印: 255


所以在通过上面的代码我们还可以发现一个知识点就是:

printf中的 %d 与  数值的类型 在整形提升前相互不会影响,即 b处他的类型是无符号的字符类型,而%d为有符号的整形,b在整形提升时仍然时一个无符号的字符类型。

而在整形提升后就会有一定的影响,即他认为内存中存的是一个有符号/无符号的整形(%d/%u)当需要打印的是有符号的整形此时就需要变成原码进行打印,而若为无符号的整形就不再需要转变成。

再如:

char a = 128

printf("%u",  a )

此时先将128的补码存进char中也就是

10000000 然后整形提升后:11111111111111111111111110000000

再打印就将会打印 11111111111111111111111110000000 二进制对应的十进制:4,294,967,168

附:通过上面的习题,我觉得有必要在补充一定关于 char类型在内存中的取值范围 (另一篇blog)的知识

练习:

一、

int main()
{
    int a = -20;
    unsignde int = 10;
    printf("%d",a + b);
    return 0;
}

该题分析:

a、b两个变量中都要存数据进到内存,并且都是以补码的形式存进内存中

即a中存的是:-20 的补码

而b中存的是:10 的补码

在printf中%d和a+b无直接联系:所以直接相加即可:那就得到了-10的补码(虽然a+b因为算术转换变成了一个无符号的整形但是这和%d无关,当用%d打印时其仍然将你看成一个有符号的整形来进行打印)

最后通过,%d打印即可得到-10(原码)

二、

 #define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
  char arr[1000] = { 0 };
  int i = 0;
  for (i = 0; i < 1000; i++)
  {
    arr[i] =  - 1 - i;
  }
  printf("%d", strlen(arr));
  return 0;
}

分析:

因为char类型的范围是从-128~127

所以arr的取值就也可以是从:-128~127

第一次:arr[0] = -1  第二次:...   =  -2   arr[127]  =-128   ...  arr[254]   = 1

后arr[255] = 0(此时因为strlen是遇到'\0'就会停止)

所以最终strlen最终有 0 ~ 254 (-1 到 -128 再从127 到 1  : 128 + 127)个元素 共并打印255个

相关文章
|
3月前
|
存储 编译器 C语言
C语言存储类详解
在 C 语言中,存储类定义了变量的生命周期、作用域和可见性。主要包括:`auto`(默认存储类,块级作用域),`register`(建议存储在寄存器中,作用域同 `auto`,不可取地址),`static`(生命周期贯穿整个程序,局部静态变量在函数间保持值,全局静态变量限于本文件),`extern`(声明变量在其他文件中定义,允许跨文件访问)。此外,`typedef` 用于定义新数据类型名称,提升代码可读性。 示例代码展示了不同存储类变量的使用方式,通过两次调用 `function()` 函数,观察静态变量 `b` 的变化。合理选择存储类可以优化程序性能和内存使用。
161 82
|
2月前
|
存储 C语言
【c语言】数据类型和变量
本文介绍了C语言中的数据类型和变量。数据类型分为内置类型和自定义类型,内置类型包括字符型、整型、浮点型等,每种类型有不同的内存大小和取值范围。变量分为全局变量和局部变量,它们在内存中的存储位置也有所不同,分别位于静态区和栈区。通过示例代码和图解,详细阐述了这些概念及其应用。
44 1
|
2月前
|
C语言
3.4 C语言基本数据类型2
在C语言中,声明一个整型(int)变量时,需先写入&#39;int&#39;关键字,后跟变量名并以分号结尾。若同时声明多个变量,可在&#39;int&#39;后用逗号分隔列出所有变量名。例如,`int erns;` 或 `int hogs, cows, goats;` 都是合法声明。变量声明后需通过赋值语句如 `cows = 112;` 或使用函数如 `scanf()` 来初始化其值。
46 10
|
2月前
|
存储 程序员 C语言
3.1 C语言基本数据类型
在C语言中,整数类型如`int`类型是很有用的,它属于有符号整型,意味着该类型的值必须是整数,并且可以是正整数、负整数或者零。`int`类型的数值范围依据计算机系统有所不同,通常取决于系统的位宽。例如,在早期16位的IBM PC兼容机上,`int`类型使用16位存储,取值范围为-32768至32767;而在当前32位系统中,使用32位存储,拥有更宽泛的取值范围。随着64位处理器的普及,`int`类型能够存储的整数范围将进一步扩大。根据ISO C标准,`int`类型的最小取值范围被规定为-32768到32767。系统通常会利用一个特殊的位来表示整数的正负。
35 10
|
2月前
|
C语言
3.1C语言基本数据类型
在C语言中,初始化变量是指为变量设定初始值,通常在声明时直接完成,例如 `int cows=32;`。应注意避免在同一语句中混合初始化与未初始化的变量,如 `int dogs, cats=94;` 这样的写法容易引起误解。此外,整型常量如21、32等在C语言中被视为int类型,但非常大的整数则不然,且带有小数点或指数的数值不属于整型常量。
28 9
|
2月前
|
存储 C语言
C语言中的浮点数存储:深入探讨
C语言中的浮点数存储:深入探讨
|
2月前
|
存储 C语言
深入C语言内存:数据在内存中的存储
深入C语言内存:数据在内存中的存储
|
2月前
|
C语言
初识C语言:与计算机的交流之输入与输出(scanf和printf)
初识C语言:与计算机的交流之输入与输出(scanf和printf)
182 0
|
2月前
|
存储 C语言
初识C语言:常量与变量中寻找数据类型
初识C语言:常量与变量中寻找数据类型
|
3月前
|
存储 C语言 数据格式
【C语言基础考研向】03混合运算和printf讲解
本文分为两部分。第一部分介绍了C语言中的混合运算与类型强制转换的重要性,通过实例展示了当整型数进行除法运算且结果为小数时,必须使用类型转换才能正确存储浮点数结果。第二部分详细讲解了`printf`函数的功能与使用方法,包括格式化输出不同类型数据的基本语法,并通过具体示例演示了如何利用字段宽度和对齐方式来控制输出格式,帮助读者更好地理解和掌握输出格式的控制技巧。
49 10