您的位置:首页 > 职场人生

2012.9华为软件开发面试题

2012-09-08 23:02 148 查看
1. C语言结构体数据对齐

转自:http://blog.csdn.net/tiany524/article/details/6295551

1.1 结构体数据对齐(没有#pragma pack()宏定义)

结构体对齐可以总结为三个基本原则

①数据成员对齐规则:

结构体的数据成员中,第一个成员从offset为0的地址开始,以后每一个成员存储的起始位置为该成员大小的整数倍(在win32中int为32bit也即4字节对齐)

②结构体作为成员:

如果一个结构体1作为另一个结构体2的数据成员,则在结构体2中结构体1要从1内部成员最大的整数倍地址开始存储。

③结构体的总大小(sizeof):

为该结构体内部最大基本类型的整数倍,不足的要补齐,而不是简单的所有成员的大小总和。

举例说明

struct A
{
short a;
short b;
short c;
};


sizeof(A)=6

struct B
{
long a;
short c;
};


sizeof(B)=8

它的内存分配为: a1 a2 a3 a4 , c1 c2 x x(a1为a的第一个字节,x为补齐字节,下同)

struct C
{
int a;
char b;
short c;
};


sizeof(C)=8

它的内存分配为: a1 a2 a3 a4, b1 x c1 c2(原则1)

struct D
{
char a;
int b;
short c;
};


sizeof(D)=12

内存分配为: a1 x x x, b1 b2 b3 b4, c1 c2 x x

struct E
{
int a;
double b;
short c;
};


sizeof(E)=24

内存分布a1 a2 a3 a4 x x x x, b1 b2 b3 b4 b5 b6 b7 b7, c1 c2 x x x x x x

struct F
{
char a,b;
int c;
double d;
short e;
E h;
};


sizeof(F)=48

内存分布

a1 b1 x x, c1 c2 c3 c4 , d1 d2 d3 d4 d5 d6 d7 d8, e1 e2 x x x x x x, A的分布

1.2 加入#pragma pack()宏定义)

#pragma pack(1)
struct E
{
int a;
double b;
short c;
};


sizeof(E)=14,为实际内存
VC对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些麻烦,我们也可以屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式。
VC 中提供了 #pragma pack(n) 来设定变量以n字节对齐方式(n一般取1、2、4、8、16)。n字节对齐就是说变量存放的起始地址的偏移量有两种情况:第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式,第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。结构的总大小也有个约束条件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数; 否则必须为n的倍数。下面举例说明其用法。

#pragma pack(push) //保存对齐状态
#pragma pack(4)//设定为4字节对齐
struct test
{
char m1;
double m4;
int m3;
};
#pragma pack(pop)//恢复对齐状态


以上结构的大小为16,下面分析其存储情况,首先为m1分配空间,其偏移量为0,满足我们自己设定的对齐方式(4字节对齐),m1占用1个字节。接着开始为 m4分配空间,这时其偏移量为1,需要补足3个字节,这样使偏移量满足为n=4的倍数(因为sizeof(double)大于n),m4占用8个字节。接着为m3分配空间,这时其偏移量为12,满足为4的倍数,m3占用4个字节。这时已经为所有成员变量分配了空间,共分配了16个字节,满足为n的倍数。如果把上面的#pragma pack(4)改为#pragma pack(16),那么我们可以得到结构的大小为24。

2. 约瑟夫环问题

http://baike.baidu.com/view/717633.htm

问题描述:n个人(编号0~(n-1)),从0开始报数,报到m-1的退出,剩下的人继续从0开始报数。求胜利者的编号。

我们知道第一个人(编号一定是(m-1)%n) 出列之后,剩下的n-1个人组成了一个新的约瑟夫环(以编号为k=m%n的人开始):

k k+1 k+2 ... n-2,n-1,0,1,2,... k-2

并且从k开始报0。

  现在我们把他们的编号做一下转换:

  k --> 0

  k+1 --> 1

  k+2 --> 2

  ...

  ...

  k-3 --> n-3

  k-2 --> n-2

变换后就完完全全成为了(n-1)个人报数的子问题,假如我们知道这个子问题的解:例如x是最终的胜利者,那么根据上面这个表把这个x变回去不刚好就是n个人情况的解吗?!!

  ∵ k=m%n;

  ∴ x' = x+k = x+ m%n ; 而 x+ m%n 可能大于n

  ∴ x'= (x+m%n)%n = (x+m)%n

  得到 x‘=(x+m)%n

令f表示i个人玩游戏报m退出最后胜利者的编号,最后的结果自然是f
.

  递推公式:

  f[1]=0;

  f[i]=(f[i-1]+m)%i; (i>1)

3. 求出小于n的最大素数,并做时间复杂度优化

4. 不限长的数据运算问题,字符数组模拟大数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: