C语言之(有关%d和%u的有关内容,输出方法)(有符号和无符号在内存中的存储情况)(整形无符号数和有符号数是如何进行计算的,整形无符号数和有符号数在循环中的应用举例)

简介: C语言之(有关%d和%u的有关内容,输出方法)(有符号和无符号在内存中的存储情况)(整形无符号数和有符号数是如何进行计算的,整形无符号数和有符号数在循环中的应用举例)

在C语言的课本中,我们常见的是%u,但我们平时在写代码常用的确是%d,它们二者之间有什么区别呢?

表示形式上

%u表示输入输出格式说明符,是按照unsigned int(无符号十进制数据)格式输入或输出数据。%d则表示signed

int(有符号十进制数据)格式输入或输出数据。


举例:

#include<stdio.h>
int main()
{
  char a = -28;
  printf("%d\n", a);
  printf("%u\n", a);
  return 0;
}


上篇我们讲述了char类型的数据用%d的形式是如何输出的,不懂的小伙伴可以去看上篇文章,这里我们主要讲述

以%u的形式如何输出:

首先我们先写出变量a的二进制形式:

//原码:10000000000000000000000010000000

//反码:1111111111111111111111111111011111111

//补码:111111111111111111111111111110000000

进行截断:10000000

进行整型提升:111111111111111111111110000000-----该数的补码

由于该数要以%u,无符号的形式进行打印,所以原码,补码,反码相同。即打印结果:4292967168

下面我们通过一张图来了解有符号和无符号在内存中的存储情况。


通过上面这张图,我们了解到有符号字符存储的范围是127---- -128,那么如果想表示大于127的正数呢?它是一个对称的原则,大于127的整数直接进行跳转到左半边圆表示的范围。

如下所示代码会输出什么样的结果?

#include<stdio.h>
int main()
{
  char a = -128;
  char b = 128;
  printf("%u\n", a);
  printf("%u\n", b);
  return 0;
}


128和-128的输出结果一样,由于有符号整数的范围已经被限制,直接代数加一定是不可取的,不过通过上面这张图我们可以得出当为有符号整数128,就相当于127加1,也就是-128。

之前我们学过了字符型的unsigned char/signed char是如何进行相加减运算的,这篇我们就来讲讲

整形的unsigned int/signed int是如何进行运算的:

举例:

#include<stdio.h>
int main()
{
  int i = -20;
  unsigned int j = 10;
  printf("%d\n", i + j);
  return 0;
}

我们让代码跑起来看看运行结果:

-10

那么它的计算过程是什么样的呢?

分析过程如下:

和之前char类型相似,首先写出两个变量的补码:

int i = -80;
  //原码:10000000000000000000000000010100
  //反码:11111111111111111111111111101011
  //补码:1111111111111111111111110111101100
unsigned int j = -10;(由于是无符号整形,原码,反码,补码均相同)
  //原码/反码/补码:00000000000000000000000000001010
i + j:
  //补码:     11111111111111111111111111101100
  //原码/反码/补码:00000000000000000000000000001010
  //i+j:补码      11111111111111111111111111110110
  //i+j:反码      11111111111111111111111111110101
  //i+j:原码      10000000000000000000000000001010

unsigned int和signed int类型的运算和char类型不同的地方在于,它不需要整形提升这一过程。

学习了unsigned int的定义和运算方法之后,下面我们来学习

它在循环中的应用:

首先我们先来看一串代码:

#include<stdio.h>
#include<windows.h>
int main()
{
  unsigned int i;
  for (i = 9; i >= 0; i--)
  {
    printf("%u\n", i);
    Sleep(100);
  }
  return 0;
}

请问它的输出结果是多少呢?如果你认为是9,8,7,6,5,4,3,2,1,0那你就大错特错了。

正确的输出结果应该是无限循环,那么有的人会问为什么是无限循环呢?

下面我们对这串代码进行分析,首先变量i被定义的类型是unsigned int而不是int,这就决定了它是不可能取到负数的,因此i>=0永远满足条件,程序会进行无限循环。


下面我们再来看一个关于char类型的应用实例:
#include<stdio.h>
#include<string.h>
int main()
{
  char a[1000];
  int i;
  for (i = 0; i < 1000; i++)
  {
    a[i] = -1 - i;
  }
  printf("%d", strlen(a));
  return 0;
}

这串代码的输出结果又会是什么呢?

我们先对代码进行分析,首先定义字符型数组a,再使用变量i访问数组元素,当i=0,a[i]=-1,当i=1,a[i]=-2,当i=2,a[i]=-3以此类推,那么有的同学会因此得出strlen(a)的长度不就是1000吗?如果你也是这么想的,恭喜你又错了,你又忽略了一个很简单但很重要的知识点,char类型的范围是-128-----127.



这张图还有印象吗?

signed char类型的数据存储到编译器中,无论多大的数字,编译器都会将该数字转为-128-------127之间的一个数,并不会超出这个范围。因此strlen(a)的值为255.

看到这里你是不是觉得自己这次一定学会啦?

那我再检测一下你是不是真的学会了!!!

#include<stdio.h>
int main()
{
  unsigned char i = 0;
  for (i = 0; i <= 255; i++)
  {
    printf("hello world!");
  }
  printf("%d\n", count);
  return 0;
}

如果你认为输出结果是无限循环,那就证明你大概是学会了,为什么是无限循环呢?还是要用到我们之前学过的无符号和有符号的范围,这里的变量i被定义的是unsigned char,无符号的范围是0-255,而循环的条件即为i<=255,和上文提到的例子相同,unsigned char类型的数据存储到编译器中,无论多大的数字编译器都会将该数字转为0-255之间的一个数,并不会超出这个范围。因此循环的条件永远成立。

注:无符号数经常会导致程序进入死循环,因此在以后编写程序的过程中,无符号数字我们要谨慎使用,以免发生程序死循环现象。

相关文章
|
9月前
|
安全 C语言 C++
比较C++的内存分配与管理方式new/delete与C语言中的malloc/realloc/calloc/free。
在实用性方面,C++的内存管理方式提供了面向对象的特性,它是处理构造和析构、需要类型安全和异常处理的首选方案。而C语言的内存管理函数适用于简单的内存分配,例如分配原始内存块或复杂性较低的数据结构,没有构造和析构的要求。当从C迁移到C++,或在C++中使用C代码时,了解两种内存管理方式的差异非常重要。
335 26
|
C语言
C语言中条件操作符的应用
最后,条件操作符是个超级英雄,但不是每个代码问题都需要一个超级英雄来解决。一定要在适当的时候适度的使用它,那么它将成为你的编程工具箱中的一件强力工具。
497 75
|
9月前
|
安全 C语言
C语言中的字符、字符串及内存操作函数详细讲解
通过这些函数的正确使用,可以有效管理字符串和内存操作,它们是C语言编程中不可或缺的工具。
434 15
|
9月前
|
SQL 缓存 安全
深度理解 Java 内存模型:从并发基石到实践应用
本文深入解析 Java 内存模型(JMM),涵盖其在并发编程中的核心作用与实践应用。内容包括 JMM 解决的可见性、原子性和有序性问题,线程与内存的交互机制,volatile、synchronized 和 happens-before 等关键机制的使用,以及在单例模式、线程通信等场景中的实战案例。同时,还介绍了常见并发 Bug 的排查与解决方案,帮助开发者写出高效、线程安全的 Java 程序。
509 0
|
存储 编译器 程序员
【C语言】内存布局大揭秘 ! -《堆、栈和你从未听说过的内存角落》
在C语言中,内存布局是程序运行时非常重要的概念。内存布局直接影响程序的性能、稳定性和安全性。理解C程序的内存布局,有助于编写更高效和可靠的代码。本文将详细介绍C程序的内存布局,包括代码段、数据段、堆、栈等部分,并提供相关的示例和应用。
736 5
【C语言】内存布局大揭秘 ! -《堆、栈和你从未听说过的内存角落》
|
C语言
【C语言】符号优先级详解 -《谁与争锋 ! 》
理解C语言中的运算符优先级和结合性是编写正确代码的关键。本文详细介绍了C语言中的各种运算符、它们的优先级和结合性,并通过示例展示了如何正确使用这些运算符。掌握这些知识,将有助于编写出逻辑严谨、结构清晰的C语言程序。
818 8
|
开发框架 .NET PHP
网站应用项目如何选择阿里云服务器实例规格+内存+CPU+带宽+操作系统等配置
对于使用阿里云服务器的搭建网站的用户来说,面对众多可选的实例规格和配置选项,我们应该如何做出最佳选择,以最大化业务效益并控制成本,成为大家比较关注的问题,如果实例、内存、CPU、带宽等配置选择不合适,可能会影响到自己业务在云服务器上的计算性能及后期运营状况,本文将详细解析企业在搭建网站应用项目时选购阿里云服务器应考虑的一些因素,以供参考。
|
机器学习/深度学习 算法 数据挖掘
C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出
本文探讨了C语言在机器学习中的应用及其重要性。C语言以其高效性、灵活性和可移植性,适合开发高性能的机器学习算法,尤其在底层算法实现、嵌入式系统和高性能计算中表现突出。文章还介绍了C语言在知名机器学习库中的作用,以及与Python等语言结合使用的案例,展望了其未来发展的挑战与机遇。
507 1
|
C语言
《C语言及程序设计》实践参考——有多少符号
返回:贺老师课程教学链接  项目要求 【项目5:有多少符号】输入一行文字,以回车结束,统计并输出其中数字、空格、字母出现的次数,以及输入的字符总数。 [参考解答] #include "stdio.h" int main() { int alpha=0, number=0, space=0, count=0; //分别代表字母、数字、空格个数,及总字节数 char ch;
940 0
|
存储 算法 C语言
【C语言程序设计——函数】素数判定(头歌实践教学平台习题)【合集】
本内容介绍了编写一个判断素数的子函数的任务,涵盖循环控制与跳转语句、算术运算符(%)、以及素数的概念。任务要求在主函数中输入整数并输出是否为素数的信息。相关知识包括 `for` 和 `while` 循环、`break` 和 `continue` 语句、取余运算符 `%` 的使用及素数定义、分布规律和应用场景。编程要求根据提示补充代码,测试说明提供了输入输出示例,最后给出通关代码和测试结果。 任务核心:编写判断素数的子函数并在主函数中调用,涉及循环结构和条件判断。
835 23