[TOC] # 编程语言 ## 一、C/C++ ### C 与 C++ 的区别(面向对象的特点) - [ ] TODO ### C++ 与 Python的区别 - [ ] TODO ### 判断struct的字节数 一般使用sizeof判断struct所占的字节数,那么计算规则是什么呢? 关键词: 1.变量的起始地址和变量自身的字节数 2.以最大变量字节数进行字节对齐(倍数关系)。 注:这里介绍的原则都是在没有#pragma pack宏的情况下 先举个例子: ```cpp struct A { char a[5]; int b; short int c; }struct A; ``` 在上例中,要计算 sizeof(a) 是多少? 有两个原则: 1)各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数 即当 A中的a占用了5个字节后,b需要占用四个字节,此时如果b直接放在a后,则b的起始地址是5,不是sizeof(int)的整数倍,所以 需要在a后面补充3个空字节,使得b的起始地址为8. 当放完b后,总空间为5+3+4 = 12. 接着放c,此时为 12 + 2 = 14. 2)为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数, 所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。 这是说A中占用最大空间的类型,就是int型了,占用了4个字节,那么规定A占用的空间必须是4的整数倍。本来计算出来占用的空间为14, 不是4的整数倍,因此需要在最后补充2个字节。最终导致A占用的空间为16个字节。 再举个例子: ```cpp struct B { char *d; short int e; long long f; char c[1]; }b; void test2() { printf("%d\n", sizeof(b)); } ``` 对于此题,需要注意的一点是:windows系统对long long是按照8字节进行对齐的,但是Linux系统对long long则是按照4字节对齐的。 因此: d占用4字节(因为d是指针) e占用2字节 f占用8字节,但是其起始地址为为6,不是4的整数倍(对于Linux系统),或不是8的整数倍(对于Windows系统),因此对e之后进行字节补齐,在这里不管对于Linux还是Windows都是补充2个字节,因此 f 的起始地址是8,占用8个字节。 对于c,它占用了1个字节,起始地址是16,也是1的整数倍。  最后,在c之后需要对整个B结构体占用的空间进行补齐,目前占用空间是16+1 = 17个字节。 对于Linux,按4字节补齐(long long 是按4字节补齐的),因此补充了3位空字节,最后占用空间是 17 + 3 = 20字节。 对于Windows系统,是按8字节补齐的,因此就补充了7个字节,最后占用的空间是24字节。 **参考资料** - [【C++】计算struct结构体占用的长度](https://blog.csdn.net/nisxiya/article/details/22456283?utm_source=copy ) ### static 作用 **什么是static?** static 是C++中很常用的修饰符,它被用来控制变量的存储方式和可见性。 **为什么要引入static?** 函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时,如何实现? 最容易想到的方法是定义一个全局的变量,但定义为一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅受此函数控制)。 **static的作用** 第一个作用是限定作用域(隐藏);第二个作用是保持变量内容持久化; - 函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值。 举个例子 ``` #include using namespace std; int main(){ for(int i=0; i<10; ++i){ int a = 0; static int b = 0; cout<<"a: "<< a++ <