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

程序员面试(c++)——预处理,const与sizeof总结

2016-06-29 14:42 357 查看
本文是对《程序员面试宝典》的学习总结,不足之处望多多批评指正。

每次看《程序员面试宝典》都有收获,但是不总结,有些东西无法真正掌握,这里对预处理、const和sizeof进行总结,希望能帮到更多人。大神亲喷。

预处理、const和sizeof问题是c++设计语言中的三大难点,也是各公司经常面试反复出现的问题。因此这里对其单独进行学习总结。

1、宏定义

宏定义主要考察的有:

(1)#define的基本语法知识(切记不能以分号结束,宏定义是没有符号结束的)

(2)实际使用中,最好把参数都用括号括起来,不然很容易出错。举个栗子:

#define chufa(a,b) a/b

那么multply(2+3,4+5)的结果是这样解释的:2+3/4+5;这实际上不是我们想要的,若写成

#define chufa(a,b) (a)/(b)

那么结果将是正确的。

2、const

(1)const修饰指针的情况

int b=100;

const int* a=&b;

int const* a=&b;

上面两种情况是等价的,只要const放在*的左边则代表const修饰是指针所指向的变量,如果const放在*的右边,则代表const修饰的是指针,即指针是常量,如下面情况。需要说明的是,由于没有const*这种含义解释,因此实际上上述两个式子其实是等价的。

int* const a=&b;

const int* const a=&b;

(2)const成员函数

const修饰成员函数时应该放在函数的后面,如int add(int a,int b) const;代表该成员函数不会修改类数据成员。

如果const关键字放在函数声明前,那么代表函数返回的值是const,即常量。

(3)如果在const成员函数中需要修改某些数据成员,应该怎么做?

可以在类数据成员用关键字mutable修饰,代表可修改。

(4)const和#define都可以定义常量,那么他们有什么不同呢?

const常量有数据类型,如const int a;而宏常量是没有数据类型的。编译器对const可以进行安全类型检查,而对后者值进行字符替换,没有类型安全检查。在c++中const只使用const常量,不使用宏常量。

3、sizeof

(1)先举几个例子,说明在sizeof上容易犯的错误。

char* ss1="0123";   sizeof(ss1)=4;

char ss2[]="0123";   sizeof(ss2)=5;

char ss3[100]="0123"; sizeof(ss3)=100;

int ss4[100]; sizeof(ss4)=400(100*4);

char q2[]="a\n"; sizeof(q2)=3;

char *q3="a\n";  sizeof(q3)=4;

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

总结:

a、指针的大小为4字节。(指针的大小是由cpu的寻址位数决定的,32位cpu的32指的是字长,寻址位数不一定是32位)

b、char数组的大小已经给定,那么该数组的sizeof就是给定的大小。如果char数组的大小未给定,那么sizeof的结果将是给定值的个数+1,注意这里的加一代表字符串结束隐含的"\0"。即sizeof的大小是以访问到"\0"为依据的。

c、sizeof经常考察的还有一种情况是结构体,求结构体大小的时候一般遵循下面两条原则:

(I)结构体中成员的偏移量必须是成员类型大小的整数倍。(0是如何成员大小的整数倍)

(II)结构体是最大成员类型大小的整数倍。

举两个例子(假设处理器位数是32位):

struct A{

short a1;

short a2;

short a3;

};

那么sizeof(A)的大小是多少呢?2+2+2=6;查看上面两个原则。

struct B{

long a1;

short a2;

};

sizeof(B)=4+2+2(填充以满足第二个原则)=8;

题外话:在c++中可以通过pack预处理指令来禁止对齐调整。但是不推荐。

#pragma pack(1)

struct{...

};

#pragma pack()

需要注意的是:如果结构体中有静态变量,由于sizeof是计算栈中分配的大小,所以静态变量是不会计算在sizeof里面的。

4、sizeof和strlen都是求长度的,但是我们很容易将他们混淆,这里进行比较他们的不同。

char ss[100]="0123456789";

sizeof(ss)=100;

strlen(ss)=10;

总结:strlen内部实现是用一个循环计算字符串的长度,直到“\0”为止,但是不计算“\0”。

int s1[100];

strlen(s1)将会出错,这是因为strlen只针对char*类型的

a、sizeof是运算符,strlen是函数

b、数组传递给sizeof不退化,而传递给strlen就退化成指针

我们需要明确sizeof不是函数,也不是一元运算符,他是类似宏定义的特殊关键字,sizeof()。括号内的内容在编译过程中是不会被编译的,而是被替代类型。int a=8; cout<<sizeof(a=6);那么a的值将不会被改变,只是简单替代成sizeof(int)。

至于空类以及类继承等的情况,比较特殊,争取尽快将学习结果总结出来,共同进步。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息