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;
}