一个冒泡排序引发的 ‘思考’

一个冒泡排序引发的 ‘思考’

首先看一个冒泡排序的代码,如下:

#include <stdio.h>

#if 1
void maopao(int a[]) //此处形参等同于int *a
{	
printf("%ld\n",sizeof(a)/sizeof(int));//调试打印
	for(i=0;i<n;i++) //对比趟数
	{
		for(j=i;j<n;j++) //对比次数,从小到大排列
		{
			if(a[j] > a[j+1])
			{	temp = a[j];
				a[j] = a[j+1];
				a[j+1] = temp;
			}
		}
	}
}

#endif
int main(int argc, char const *argv[])
{
	/* code */
	int i;
	int a[5]={1,2,5,4,3};
	maopao(a);

	for(i=0;i<sizeof(a)/sizeof(int);i++)
		printf("%d",a[i]);//打印排序后的数组
	return 0;
}

先对上述冒泡排序做个解读,这个排序是有问题的。可以复制到调试机看一下现象。正常情况下传递数组的时候, 要把数组元素的个数也传递过来。正确的代码如下所示。

#include <stdio.h>

#if 1
void maopao(int *a,int n)
{
	//int n = sizeof(a)/sizeof(int);
	//int n;
	int i,j,temp;

printf("%ld\n",sizeof(a)/sizeof(int));

	for(i=0;i<n;i++)
	{
		for(j=i;j<n;j++)
		{
			if(a[j] > a[j+1])
			{	temp = a[j];
				a[j] = a[j+1];
				a[j+1] = temp;
			}
		}
	}
}

#endif
int main(int argc, char const *argv[])
{
	/* code */
	int i;
	int a[5]={1,2,5,4,3};
	maopao(a,5);


	for(i=0;i<sizeof(a)/sizeof(int);i++)
		printf("%d",a[i]);
	return 0;
}

接着正确代码解读,执行后打印如下

在这里插入图片描述
由上述图片发现打印出来为2.
思考1:一位数组做形参,实际上是一个指针。所有类型的指针都是四个字节,为什么会是2?不应该是1吗?
解读血案1:一定要看清楚每个字,尤其是标粗的
在计算机内存中,每一个字节单元,都有一个编号,称为地址
在计算机中是以字节(byte)为单位存储。1 byte=8 bit(一位二进制数)
地址是一片内存中每个字节(byte)的编号,就好比房号是一栋办公楼中每个房间的编号一样,假如我所在的办公楼房间数量总共不超过1000间,那么我用一个三位数来表示就足够了,比如302、508等等。

同样的道理,假如计算机内存的字节总数不超过1000个,也可以用三位数来表达,换算成二进制数,最多也就是11 1110 0111(即十进制的999),也就说说用10bits就可以完全表示1000以下的所有字节的编号的。但假如我们的内存有多达4GB个字节,10bits的编号显然太短了,经计算,我们至少需要32bits来表示所有的字节地址编号,因此一个数据的地址就类似于:0110 1101 1100 0010 1101 1110 0101 1101,由于写起来太长不够方便,因此我们更喜欢将上述地址表示为十六进制:0x6DC2DE5D。

内存这栋大楼的房间数多得惊人!他们的编号从0x00000000开始,到0xFFFFFFFF,总计达232个房间!每一个房间(字节/byte)包含8个比特/bit,每个比特可以存放一个1或者0,一图顶万言,附上一张内存的性感照片:

在这里插入图片描述

上图展现了一个32位系统的内存示意图,第0x0804FFB0号字节里面存放了一串数据:1111 0000,而紧挨着他的第0x0804FFB1号字节里面存放了另一串数据:1010 1010。

看明白了没有?之所以指针是4字节,是因为在32位系统中。

而对于此处之所以打印出2,是因为使用的是64位操作系统,此时指针占的内存空间为8字节了。
在这里插入图片描述
上图可以看出,不管是char类型,还是int类型的指针,64位操作系统中都是8个字节。另外注意:64位系统只能安装在64位电脑上(CPU必须是64位的),同时需要安装64位常用软件以发挥64位(x64)的最佳性能。32位操作系统则可以安装在32位(32位CPU)或64位(64位CPU)电脑上。如果32位操作系统安装在64位电脑上,其硬件恰似“大马拉小车”:64位效能就会大打折扣。 64位CPU GPRs(General-Purpose Registers,通用寄存器)的数据宽度为64位,64位指令集可以运行64位数据指令,也就是说处理器一次可提取64位数据(只要两个指令,一次提取8个字节的数据),比32位(需要四个指令,一次提取4个字节的数据)提高了一倍,理论上性能会相应提升1倍。

至于为什么是8字节:在64位系统中,cpu会通过地址总线在2^64个地址中寻找其中的某一个地址值的数据,所以8个字节的指针就可以代表内存中任意位置的一个地址值,所以指针占8个字节就足够用了。可以参考微博https://www.cnblogs.com/gaoxiaoniu/p/10677754.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值