2012.9华为软件开发面试题

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):

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

举例说明

 

1 struct A
2 { 
3     short a; 
4     short b; 
5     short c; 
6 }; 

sizeof(A)=6

1 struct B
2 { 
3     long a; 
4     short c; 
5 }; 

sizeof(B)=8

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

 

1 struct C
2 { 
3     int a; 
4     char b; 
5     short c; 
6 };

sizeof(C)=8

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

 

 

1 struct D
2 { 
3     char a; 
4     int b; 
5     short c; 
6 };

 

sizeof(D)=12

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

 

1 struct E
2 { 
3     int a; 
4     double b; 
5     short c; 
6 };

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

 

1 struct F
2 { 
3     char a,b; 
4     int c; 
5     double d; 
6     short e; 
7     E h; 
8 };

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()宏定义)

1 #pragma pack(1) 
2 struct E
3 { 
4     int a; 
5     double b; 
6     short c; 
7 };

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

1 #pragma pack(push) //保存对齐状态 
2 #pragma pack(4)//设定为4字节对齐 
3 struct test 
4 { 
5     char m1; 
6     double m4; 
7     int m3; 
8 }; 
9 #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[n].

  递推公式:

  f[1]=0;

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

 

 

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

 

4. 不限长的数据运算问题,字符数组模拟大数

 

 

 

posted on 2012-09-08 23:02  深山中一小妖  阅读(379)  评论(0编辑  收藏  举报

导航