sizeof

sizeof是关键字

  • sizeof是数据类型关键字,而非函数。
类型关键字
数据类型14个void,char,int,float,double,short,long,signed, unsigned,struct,union,enum,typedef,sizeof
控制类型6个auto,static,extern,register,const,volstile
控制关键字12个return,continue,break,goto,if,else,switch,case,default,for,do,while

扩展:预处理指令不是C语言中的语言类型

  • 语言类型分5大类:

    • 表达式语句
    • 函数调用语句
    • 控制语句(if语句、switch语句……)
    • 复合语句
    • 空语句
  • 预处理指令的结尾不能添加分号,所以预处理指令不是语句。

sizeof与strlen的区别

int main(int argc,char* argv[]){
    cout << strlen("\0") << endl; //0
    cout << sizeof("\0") << endl; //2
    getchar();
    return 0;
}
  • strlen执行的计数器的工作,它从内存的某个位置开始扫描,直到碰到第一个字符串结束符’\0’为止,然后返回计数器值。

  • sizeof是关键字,它以字节的形式给出了其操作数的存储大小,操作数可以是一个表达式或类型名,操作数的存储大小由操作数的类型决定。

  • sizeof是关键字,strlen是函数。

  • sizeof可以用类型作为参数,而strlen只能用char*作为参数,而且必须是以‘\0’结尾。sizeof还可以以函数作为参数,例如 int g(),则sizeof(g())的值等价于sizeof(int)的值。

    • sizeof:类型(自定义类型)、函数作为参数。
    • strlen:只能char*作为参数。
  • 大部分编译程序的sizeof都是在编译的时候计算,而strlen在运行期间计算。

    • sizeof:编译期间计算
    • strlen:运行期间计算
  • 数组作为参数传递给函数时传的是指针而非数组,传递的是数组的首地址。

void g(char ch[]){
    cout << sizeof(ch) <<endl; //4
}

int main(int argc,char* argv[]){
    char ch[8];
    cout << sizeof(ch) <<endl; //8
    g(ch);
    getchar();
    return 0;
}

为什么结构体sizeof返回的值一般大于期望值?

  • 结构体的sizeof是所有成员对齐后长度相加,而union共用体的sizeof是取最大的成员长度

  • 按照最大成员长度对齐,即最大成员的整数倍。

#include<iostream>

using namespace std;

struct A1 {
    int a;
    char c;
    A1();
    ~A1(){}
};

struct A2 {
    double d;
    float f;
    int a;
    char c;
    A2();
    ~A2() {}
};

int main(int argc, char* argv[]) {
    cout << sizeof(A1) << endl;  //8
    cout << sizeof(A2) << endl;  //24
    getchar();
    return 0;
}

sizeof计算栈中分配的大小

  • sizeof只计算栈中分配的大小,静态变量存放在全局数据区,不加入运算。
#include<iostream>

using namespace std;

struct A1 {
    int a;
    char c;
    static char c1;   //BSS段,不属于栈区
    A1();
    ~A1(){}
};

struct A2 {
private:
    static double d1;
    double d;
    float f;
    int a;
    char c;
    A2();
    ~A2() {}
};

int main(int argc, char* argv[]) {
    cout << sizeof(A1) << endl;   //8
    cout << sizeof(A2) << endl;   //24
    getchar();
    return 0;
}

sizeof时指针和引用的区别

  • 引用进行sizeof操作得到的是所指向的变量(对象)的大小

  • 指针进行sizeof操作得到的是指针本身(所指向的变量(对象)的地址)的大小。

#include<iostream>

using namespace std;

struct A {
    int a;
    char c;
};

int main(int argc, char* argv[]) {
    A a;
    A &b = a;
    cout << sizeof(b) << endl;  //8
    A *c = &a;
    cout << sizeof(c) << endl;  //4
    getchar();
    return 0;
}

sizeof之虚函数

  • 虚函数是由虚函数表和虚表指针来动态绑定的,在计算sizeof时,无论有多少个虚函数,其只计算sizeof(虚表指针)=4(64位为8)。
#include<iostream>

using namespace std;

struct A1 {
    int a;
    char c;
    static char c1;   //BSS段,不属于栈区
    A1();
    ~A1() {}
    virtual void f1() {}
    virtual void f2() {}
    virtual void f3() {}
};

int main(int argc, char* argv[]) {
    cout << sizeof(A1) << endl;  //12
    getchar();
    return 0;
}

sizeof之继承

  • 基类的sizeof结果只与基类有关。

  • 因存在继承关系,所以派生类的sizeof结果需要加上基类的sizeof结果

  • 当基类和派生类均有虚函数时,只计算一次sizeof(虚表指针)

#include<iostream>

using namespace std;

struct A1 {
    int a;
    char c;
    static char c1;   //BSS段,不属于栈区
    A1();
    ~A1() {}
    virtual void f1() {}
    virtual void f2() {}
    virtual void f3() {}
};

struct A2 : public A1{
    float f;
    void f1(){}
    void f2(){}
    void f3(){}
    virtual void g1(){}  
    virtual void g2(){}
};

int main(int argc, char* argv[]) {
    cout << sizeof(A1) << endl;  //12
    cout << sizeof(A2) << endl;  //16
    getchar();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值