面试题(2)预处理、const、static、sizeof



1.#ifdef #else #endif指示符

#ifdef指示符常用来判断一个预处理常量是否已被定义,比便有条件的包含代码。#ifndef与#ifdef作用相同,只是判断方式相反。

#include<stdio.h>
#include
<stdlib.h>
#define DEBUG
int main()
{
    
int i=0;char c;
    
while(1)
    {
        i
++;
        c
=getchar();
        
if(c!='\n')getchar();
        
if(c=='q'||c=='Q')
        {
            #ifdef DEBUG
            printf(
"we got:%c,about to exit.\n",c);
            
#endif
            
break;
        }
        
else
        {
            printf(
"i=%d",i);
            #ifdef DEBUG
            printf(
"we got:%c.\n",c);
            
#endif
            printf(
"\n");
        }
    }
    
return 0;
}

2.宏定义,利用宏定义提高代码的可读性和可移植性。

 

#include<stdio.h>
#define STR(s) #s
#define CONS(a,b) (int)(a##e##b)
int main()
{
    printf(STR(vck));
//vck
    printf("\n");
    printf(
"%d\n",CONS(2,3));//2000
    return 0;
}
 
 

#define ARR_SIZE(a) (sizeof((a))/sizeof((a[0]))) //得到数组的元素个数

#define WORD_LO(XXX) ((byte)((word)(xxx)&255))//低字节

3.const常量

它的主要作用是 定义常量,const定义的常量编译器可以对其进行数据静态类型的安全检查;const修饰形参,当输入参数为用户自定义类型和抽象数据类型时将值传递改为 const &传递可以提高效率,例如void fun(A a),void fun(A const &a);第一个函数参数采用值传递,临时对象的构造复制析构过程都要消耗时间。;const修饰函数的返回值;const修饰类成员函数

 

  #include<iostream>
  class widget
  {
      private:
          static int count;
      public:
      widget(){count++;}
      ~widget(){count--;}
     static int num(){return count;}
 };
 int widget::count=0;
 int main()
 {
    using namespace std;
     widget x,y;
     cout<<"The number is "<<widget::num()<<endl;//2
     if(widget::num()>1)
     {
         widget u,v,w;    
         cout<<"The number is "<<widget::num()<<endl;//5
     }
     widget z;    
     cout<<"The number is "<<widget::num()<<endl;//3
 }

1.它限定变量不被改变,使用const 可以在一定上增强程序的健壮性,减少程序出错。

#include<stdio.h>
int main()
{
    
const int x=1;//常量 ,值不能改变
    int b=10,c=20;
    
const int *a1=&b;//指针指向的内容不能改变:*a1 只读
    int * const a2=&b;//指针本身为常量 : a2 只读
    const int *const a3=&b;//指针不能改变,指向的内容也不能改变:a3,*a3 只读
    x=2;//error: assignment of read-only variable ‘x’
    a1=&c;
    
*a1=1;//error: assignment of read-only location ‘*a1’
    a2=&c;//error: assignment of read-only variable ‘a2’
    *a2=1;
    a3
=&c;//error: assignment of read-only variable ‘a3’
    *a3=1;//error: assignment of read-only location ‘*a3’
    return 0;
}
 

2.const 与#define

#define在程序编译的时候实施替换,然后进行编译

const存在与程序的数据段 

4 static 变量(静态变量)

static关键词代表静态,它可以作用于变量以及函数,在局部变量加上static---》静态局部变量;函数返回类型+static--->静态函数。类成员+static--->成员属于类。

static在函数体内,一个被声明为静态的变量在函数调用过程中维持其值不变。模块内函数外,静态变量可以被模块内所有函数访问,但不能被模块外的函数访问。在模块内 静态函数只能被这一模块的函数调用。

 


5 sizeof操作符

1)sizeof是单目操作符,而不是函数, 以字节形式给出了其操作数的存储空间。

/*
字节对齐的细节与编译器实现相关,
1.结构体变量的首地址能够被其最宽的基本类型成员的大小所整除
2 .结构体每个成员相对与结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节
3.结构体的总大小为结构体最宽的基本类型的整数倍,如有需要编译器会在最后一个成员之间加上填充字节
根据这些规则 适当调整顺序,sizeof将获得较小的值
*/
#include
<stdio.h>
class A
{
public:int i;};
class B
{
publicchar ch;};
class C
{
public :int i;short j;};
class D
{
publicint i;short j;char ch;};
class E
{
publicint i;int ii;short j;char ch;char chcr; };
class F
{
public:int i;int ii;int iii;short j;char ch;char chr; };
struct S
{
char c1;int i;char c2;};
struct S2
{
char c1;char c2;int i;};
int main()
{
    printf(
"%d  %d  %d\n",sizeof(int),sizeof(short),sizeof(char));//4   2   1
    printf("%d  %d  %d  %d  %d  %d\n",sizeof(A),sizeof(B),sizeof(C),sizeof(D),sizeof(E),sizeof(F));//4  1  8  8  12   16
    printf("%d  %d\n",sizeof(S),sizeof(S2));//12  8
    S s={'a',1,'b'};
    S2 s1
={'a','b','1'};
    printf(
"%xH\n%xH\n%xH\n%xH\n",(unsigned)&s,(unsigned)&s.c1,(unsigned)&s.i,(unsigned)&s.c2);    
printf(
"_______________________________________________\n\n");
    printf(
"%xH\n%xH\n%xH\n%xH\n",(unsigned)&s1,(unsigned)&s1.c1,(unsigned)&s1.c2,(unsigned)&s1.i);    
}
 

2)在类中普通函数不占用内容,当有虚函数时候,用一个指针来维护虚函数表,一下示例讲得到如下结果

 

sizeof Base obj is4
sizeof Derived obj is8
sizeof A obj is8
sizeof B obj is12
sizeof A obj is8
sizeof B obj is12
4     8     8     12     8     12
 

 

/*普通函数不占用内存,如果有虚函数,则通过一个指针来维护一个虚函数表*/
#include
<iostream>
using namespace std;
class Bc
{
    
public:
    Bc(
int x):a(x){}
    
void print(){cout<<"base"<<endl;}
    
private :
    
int a;
    };
class  Dc:public Bc
{
    
private:
     
int b;
    
public:
    Dc(
int x):Bc(x-1),b(x){}
    
void print(){cout<<"derived"<<endl;}
    };
class A
{
    
private :
    
int a;
    
public :
    A(
int x):a(x){}
    
virtual void print(){cout<<"A"<<endl;}
    };
class B:public A
{
    
private:
     
int b;
    
public:
    B(
int x):A(x-1),b(x){}
    
virtual void print(){cout<<"B"<<endl;}
    };
class C
{
    
private :
    
int a;
    
public :
    C(
int x):a(x){}
    
virtual void print(){cout<<"C"<<endl;}
    
virtual void print2(){cout<<"CC"<<endl;}
    };
class D:public C
{
    
private:
     
int b;
    
public:
    D(
int x):C(x-1),b(x){}
    
virtual void print(){cout<<"D"<<endl;}
    
    
virtual void print2(){cout<<"DD"<<endl;}
    };
int main()
{
    Bc objBase(
1);
    cout
<<"sizeof Base obj is"<<sizeof(objBase)<<endl;
    Dc objDeri(
2);
    cout
<<"sizeof Derived obj is"<<sizeof(objDeri)<<endl;
    A a(
1);
    cout
<<"sizeof A obj is"<<sizeof(a)<<endl;
    B b(
2);
    cout
<<"sizeof B obj is"<<sizeof(b)<<endl;
    C c(
1);
    cout
<<"sizeof A obj is"<<sizeof(c)<<endl;
    D d(
2);
    cout
<<"sizeof B obj is"<<sizeof(d)<<endl;
    cout
<<sizeof(Bc)<<"     "<<sizeof(Dc)<<"     "<<sizeof(A)<<"     "<<sizeof(B)<<"     "<<sizeof(C)<<"     "<<sizeof(D)<<"     "<<endl;
    
return 0;
    }

3)#pragma park

 1 #include<iostream>
 2 #pragma pack(1)
 3 struct test
 4 {
 5     char c; short s1;short s2;int i;
 6 };
 7 int main()
 8 {
 9     using namespace std;
10     cout<<sizeof(test)<<endl;//9 #pragma pack(1)将对齐方式设为1,否则结果为12
11     return 0;
12 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值