【程序员面试宝典】错题好题汇总ch6
错题,知识盲点、查漏补缺
好题,开阔思路、锻炼思维
ch6 预处理、const与sizeof
1.
#include<iostream> using namespace std; #define SUB(x,y) (x-y) //如果是#define SUB(x,y) x-y,DEV-cpp编译会出错。 #define ACCESS_BEFORE(element,offset,value) *SUB(&element,offset) =value int main(){ int i; int array[10] = {1,2,3,4,5,6,7,8,9,10}; ACCESS_BEFORE(array[5],4,6); for(i = 0;i < 10;++i)cout<<array[i]<<" "; return 0; }
结果与分析:
2.
常见宏定义:
#define SECONDSOFAYEAR (60 * 60 * 24 * 365)UL //一年多少秒,不考虑闰年 #define MIN(x,y) ((x) <= (y)?(x):(y)) #define MAX(x,y) ((x) >= (y)?(x):(y))
3.
关于const:
(1)
Class A_class{ public: void f()const{ return ++m_const; } private: mutable int m_const; }
加了mutable之后,const成员函数就可以修改成员变量了。
(2)
int b = 600,c = 700; const int *a = &b;//情况一 int const *a = &b;//情况二
情况一二是完全一样的。
都是说b的值不可以通过a改变,即:*a = 400;这句话不允许。但是b = 400;这句话是允许的。
a = &c;这句话也是允许的。
打比方a是管理员,b是仓库。a不能动仓库b里的东西,也不能动仓库c里的东西,但是a可以选择管理哪个仓库,仓库自己可以改变自己。
总之,a不要去改变仓库就好了。
int * const a = &b;//情况三
这时候,a的值不可改变。a必须管理b。即:a = &c;不允许。
但是,现在a有权限改b了,*a = 400;b = 400;都是可以的。
const int * const a = &b;//情况四
b = 400;允许。*a = 400;a = &c;都不允许。
(3)
const与#define相比?
答案:
前者有几个优点:
一、const有数据类型。可以类型检查。#define会有边际效应。
二、const可以调试。
4.
#include<iostream> #include<cstdlib> 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; }
结果与分析:
string strArr1[] = {"Trend","Micro","Soft"}; string * pStrArr1 = new string[2]; pStrArr1[0] = "US"; pStrArr1[1] = "CN"; cout<<endl; cout<<"sizeof string[] :"<<sizeof strArr1<<endl; cout<<"sizeof string* :"<<sizeof pStrArr1<<endl; cout<<"sizeof string :"<<sizeof(string)<<endl;
结果与分析:
sizeof是一个类似于宏的运算符,对sizeof(),括号里的内容会被替换为类型名,比如int f(int x){return x;} sizeof(f());会被替换为sizeof(int)。
数组的大小是各维数的乘积×数组元素的大小。因此,string数组大小就是4×维数,上面的12 = 4 × 3。
sizeof只计算栈中分配的大小,不会计算静态变量。
class Base{ public: Base(){ cout<<"Base-ctor"<<endl; } ~Base(){ cout<<"Base-dtor"<<endl; } virtual void f(int){ cout<<"Base f(int)"<<endl; } };
结果与分析:
类里面有虚函数的时候,有一个隐藏的虚指针,所以sizeof大小为4.
而下面这种不带虚函数的类,大小为1。为1的原因可能是不能再小了。。
class Base{ public: Base(){ cout<<"Base-ctor"<<endl; } ~Base(){ cout<<"Base-dtor"<<endl; } };
结果与分析:
int test(char var[]){ return sizeof var; } int main(){ char var[10]; cout<<"sizeof var :"<<test(var)<<endl; return 0; }
结果与分析:
在函数内部,var[]等价于*var,大小为4.
引申:
如果想在函数内部知道数组的大小,需要这样做:进入函数后用memcpy将数组复制出来,长度由另一个形参传进去。
code:
fun(unsigned char *p1,int len){ unsigned char * buf = new unsigned char[len + 1]; memcpy(buf,p1,len); }