今天跟大家分享的小技巧是关于分页公式计算和变量内存对齐算法的。有的朋友可能会问:这两个算法有什么共同点吗?为什么要在一篇小技巧里介绍。下面我们先来看看关于分页计算的问题:我们需要在一个画面上显示一些数据,这些数据很多,不可能在同一个画面完全显示出来,我们只好对这些数据做分页显示,例如每页显示10条数据,用户可以根据自己的需要输入想要查看的页码,然后程序会将这个页码的数据显示出来,也就是我们通常据说的数据分页功能。但是这里面有一个总页数计算的问题,我们希望数据总数(record)、每页显示数(size)和总页数(page)之间应该有这样的关系:
page = record / size
如果record % size > 0 也就是有余数,那么page应该加1。
于是我们可以这样编写一个函数来计算总页数:
int page_count(int record, int size)
{
int page = record / size;
if (record % size)
{
page++;
}
return page;
}
这样就实现我们计算总页数的函数,不过这样实现起来程序有点笨拙,我们可以把函数的内部实现过程用一个问号表达式来实现:
int page_count(int record, int size)
{
return record % size ? record / size + 1 : record / size;
}
于是程序看起来似乎简洁了不少,但还是不够简洁明了,我们来看这样一个计算方法:
int page_count(int record, int size)
{
return (record + size - 1) / size;
}
其中size - 1为size的最小余数,(record + size - 1) / size就会自然的算出总页码数了,这样的代码即简单又实用,而且CPU在做四则运算上的速度要比做逻辑条件判断快的多,如果这样的代码被使用到内循环中性能将会有很大提升。
下面我们来看第二个问题,变量占用内存对齐问题。在C语言里,为了提高CPU寻址的速度,编译器通常在为结构体中变量分配内存时需要使它们对齐(参见《变量占用内存》),例如下面结构体:
struct s_mem
{
char a;
int b;
long c;
};
我们假设系统是按4字节对齐原则,那么char a;为了与int b;对齐,再与long c;对齐,那么a、b、c占用内存的计算公式为:
(sizeof(type) + sizeof (int) - 1) / sizeof (int) * sizeof (int)
这个公式就是将上面我们讲到分页时计算总页数的公式进行了一些变化修改为sizeof()函数计算变量类型原本占用的字节数,然后再将最后的结果乘以4也就是sizeof(int)即可计算,经过上面公式计算a、b、c占用内存字节数如下:
char a 4 bytes
int b 4 bytes
long c 8 bytes
最后整个结构体所占用的内存字节数为16。
这样的算法不仅仅用在上述两个场景中,还可以使用到其它很多场景当中,例如在内存申请函数内部,就可以使用这个方法为用户申请内存,如果用户申请的内存字节数小于一个内存页的字节数(1024)则按4字节对齐为用户分配连续的内存区域;如如果用户申请的内存字节数大于一个内存页的字节数(1024)则为用户分配连续的多个内存页。这样的计算公式原型仍然为:
(x + y - 1) / y
或
(x + y - 1) / y * y
正所谓万变不离其宗,希望大家在学习这个公式之后能够灵活运用到实际工作当中去。
今天的小技巧你学会了吗?
Copyright © 2015-2023 问渠网 辽ICP备15013245号