您的位置:首页 > 编程语言 > C语言/C++

c++面试题

2015-01-14 21:35 337 查看
2015.1.14

预处理 const 和 sizeof

1、sizeof(str)

str是个数组,sizeof数组得到的值=单个数组元素的字节大小*数组元素个数=1*25=25,不要漏了字符串结尾的0

2、sizeof(p)

p是个指针,32位系统上指针就是个32位的值,所以等于4(4字节=32位)

3、sizeof(n)

同2,32位系统上int占4个字节,所以等于4

4、数组做函数参数时,其实是按指针来传递的,所以同2,sizeof(指针)=4

5、同2,p是个指针,sizeof(p) = 4



数据类型 LP64 ILP64 LLP64 ILP32 LP32

char 8 8 8 8 8

short 16 16 16 16 16

_int32 N/A 32 N/A N/A N/A

int 32 64 32 32 16

long 64 64 32 32 32

long long N/A N/A 64 N/A N/A

pointer 64 64 64 32 32

LP64,ILP64,LLP64是64位平台上的字长模型,ILP32和LP32是32位平台上的字长模型。

64位Windows采用的是LLP64数据模型。

64位UNIX/Linux/MacOS X采用的是LP64数据模型。

对于支持SIMD指令集的CPU,比如MMX、SSE2/3/4等的,或者PowerPC指令的CPU,int显然不是最快的。因为那些CPU一个时钟周期能处理64位甚至128位整数。

#include<iostream>

#include<stdio.h>

#include<string.h>

using namespace std;

struct{

short a1;

short a2;

short a3;

}A;

struct{

long a1;

short a2;

}B;

int main()

{

char* ss1="0123456789";

char ss2[]="0123456789";

char ss3[100]="0123456789";

int ss4[100];

char q1[]="abc";

char q2[]="a/n";

char* q3="a/n";

char* str1=(char*)malloc(100);

void *str2=(void*)malloc(100);

cout<<sizeof(ss1)<<" ";

cout<<sizeof(ss2)<<" ";

cout<<sizeof(ss3)<<" ";

cout<<sizeof(ss4)<<" ";

cout<<sizeof(q1)<<" ";

cout<<sizeof(q2)<<" ";

cout<<sizeof(q3)<<" ";

cout<<sizeof(A)<<" ";

cout<<sizeof(B)<<" ";

cout<<sizeof(str1)<<" ";

cout<<sizeof(str2)<<" ";

return 0;

}

//解析:

//ss1是一个字符指针,指针的大小是一个定植,就是4。

//q2里面有一个"/n","/n"算做一位,所以它的空间大小是3。

//A 和B是两个结构体。在默认情况下,为了方便对结构体内元素的访问和管理,当结构体内的元素的长度都

//小于处理器的位数的时候,便以结构体里面最长的数据元素为对齐单位,也就是说,结构体的长度一定是

//最长的数据元素的整数倍。如果结构体内存在长度大于处理器位数的元素,那么就以处理器的位数为对齐

//单位。但是结构体内类型相同的连续元素将在连续的空间内,和数组一样。

//

//结构体A中有3个short类型变量,各自以2字节对齐,结构体对齐参数按默认的8字节对齐,则a1、a2、a3都

//取2字节对齐,sizeof(A)为6,其也是2的整数倍。B中a1为4字节对齐,a2 为2字节对齐,结构体默认对齐参数

//为8,则a1取2字节对齐;结构体大小6字节,6不为4的整数倍,增加到8时,符合所有条件,则sizeof(B)为8。

=======================================================================================================

//sizeof面试题3.cpp

//求解下面程序的结果。

//[中国某著名通信企业H面试题]

#include<iostream>

using namespace std;

class A1{

public:

int a;

static int b;

A1();

~A1();

};

class A2{

public:

int a;

char c;

A2();

~A2();

};

class A3{

public:

float a;

char c;

A3();

~A3();

};

class A4{

public:

float a;

int b;

char c;

A4();

~A4();

};

class A5{

public:

double d;

float a;

int b;

char c,e;

A5();

~A5();

};

int main()

{

cout<<sizeof(A1)<<endl;

cout<<sizeof(A2)<<endl;

cout<<sizeof(A3)<<endl;

cout<<sizeof(A4)<<endl;

cout<<sizeof(A5)<<endl;

return 0;

}

//解析:

//因为静态变量是存放在全局数据区的,而sizeof计算栈中分配的大小,是不会计算在内的,所以sizeof(A1)

//是4。

//为了照顾数据对齐,int大小为4,char大小为1,所以sizeof(A2)是8。

// 为了照顾数据对齐,float大小为4,char大小为1,所以sizeof(A3)是8。

// 为了照顾数据对齐,float大小为4,int大小为4,char大小为1,所以sizeof(A4)是12。

// 为了照顾数据对齐,double大小是8,float大小为4,int大小为4,char大小为1,所以sizeof(A5)是24。
==================================================================================

含位域结构体的sizeof:

前面已经说过,位域成员不能单独被取sizeof值,我们这里要讨论的是含有位域的结构体的sizeof,只是考虑到其特殊性而将其专门列了出来。

C99规定int、unsigned int和bool可以作为位域类型,但编译器几乎都对此作了扩展,允许其它类型类型的存在。

使用位域的主要目的是压缩存储,其大致规则为:

1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;

2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;

3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++和GCC采取压缩方式;

4) 如果位域字段之间穿插着非位域字段,则不进行压缩;

5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。

还是让我们来看看例子。

示例1:

struct BF1

{

char f1 : 3;

char f2 : 4;

char f3 : 5;

};

其内存布局为:

|__f1___|____f2___ |__|____f3______|______|

|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|

位域类型为char,第1个字节仅能容纳下f1和f2,所以f2被压缩到第1个字节中,而f3只

能从下一个字节开始。因此sizeof(BF1)的结果为2。

示例2:

struct BF2

{

char f1 : 3;

short f2 : 4;

char f3 : 5;

};

由于相邻位域类型不同,在VC6中其sizeof为6,在Dev-C++中为2。

示例3:

struct BF3

{

char f1 : 3;

char f2;

char f3 : 5;

};

非位域字段穿插在其中,不会产生压缩,在VC6和Dev-C++中得到的大小均为3。

在结构体和类中,可以使用位域来规定某个成员所能占用的空间,所以使用位域能在一定程度上节省结构体占用的空间。不过考虑下面的代码:

struct s1

{

 int i: 8;

 int j: 4;

 double b;

 int a:3;

};

struct s2

{

 int i;

 int j;

 double b;

 int a;

};

struct s3

{

 int i;

 int j;

 int a;

 double b;

};

struct s4

{

 int i: 8;

 int j: 4;

 int a:3;

 double b;

};

cout<<sizeof(s1)<<endl; // 24

cout<<sizeof(s2)<<endl; // 24

cout<<sizeof(s3)<<endl; // 24

cout<<sizeof(s4)<<endl; // 16

  可以看到,有double存在会干涉到位域(sizeof的算法参考上一节),所以使用位域的的时候,最好把float类型和double类型放在程序的开始或者最后。

===================================================================================================================

const的用法:

求统计数组里重复元素个数,以及位置:

#include <iostream>

#include <map>

#include <vector>

using namespace std;

void main(void)

{

int data[]={20,20,12,8,8,6,6,10,20,15};

map<int, vector<int>> m_data;

map<int, vector<int>>::iterator r;

for(int i=0; i<sizeof(data)/sizeof(*data); ++i)

{

vector<int> pos;

r = m_data.find(data[i]);

if(r != m_data.end())

{ r->second.push_back(i);

m_data[data[i]] = r->second;

}

else

{

pos.push_back(i);

m_data[data[i]] = pos;

}

}

for(map<int, vector<int>>::iterator e=m_data.begin(); e!=m_data.end(); ++e)

{

cout << "数字:" << e->first << " 在数组中的个数:" << e->second.size() << " 在数组中的位置:";

for(vector<int>::iterator r= (e->second).begin(); r!=(e->second).end(); ++r)

cout << *r << " ";

cout << endl;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: