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

导读:本篇文章讲解 C语言之(有关%d和%u的有关内容,输出方法)(有符号和无符号在内存中的存储情况)(整形无符号数和有符号数是如何进行计算的,整形无符号数和有符号数在循环中的应用举例),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

在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
输出结果为-10

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之间的一个数,并不会超出这个范围。因此循环的条件永远成立。
注:无符号数经常会导致程序进入死循环,因此在以后编写程序的过程中,无符号数字我们要谨慎使用,以免发生程序死循环现象。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/81494.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!