8、鸿沟对齐
CPU在单位时间内(同一时间)能一次处理的二进制数的位数叫字长。处理字长为8位数据的CPU一般就叫8位的CPU, 当时的CPU大部分是32位的CPU,假如某台机器的字长为4个字节(也便是32位),那么下面的结构领会占用多少内存空间呢?
struct StrA{
int a;
char b;
short c;
char d;
};
假如你的答案是12字节,祝贺你!答对了。这个结构在内存中的存储如下图所示:
a为int型,占4个字节(0-3),b为char型,占一个字节(4),c就要留意了,short型占2个字节,可是不能从5号位存储,偏移量有必要为2的整数倍方位,所以,从6号方位开端,占有6和7号位,d为char型,只需占用8号位即可,可是由于机器字长为4个字节,当下一个结构存储时,不能从9号位开端,需从12号位开端,也便是说9、10、11号位也被糟蹋掉。
简略来说能够这样算,在成员变量所占字节数和机器字长中挑选小的一个,并按该字节数对齐,比方c占2个字节,那么在存储它时,就按2字节对齐,存储c的方位有必要是2的整数倍,b和d占1字节,按1字节对齐,所以实际上结构体共占用了9个字节,终究一步,需求依照机器字长进行圆整,由于字长为4字节,所以结构体占用字节数有必要为4的整数倍,终究占了12字节的内存。
再看下面这个比方,占用了多少字节呢?
struct StrB{
int a;
short c;
char b;
char d;
};
答案是:8个。两个结构存储的内容完全相同,常识调整了成员b和c的次序,可是却节省了33%的空间。
9、再说static
Static能够用来润饰全局变量、部分变量和函数。下面留意来叙述:
(1)被static润饰的全局变量称为静态全局变量,它与一般全局变量的差异在于,“一般全局变量穿上static外衣后,它就变成了新娘,已心有所属,只能被界说它的源文件(新郎)中的变量或函数拜访。”而其它文件内的函数是无法拜访它的。
(2)一般的部分变量在栈空间上分配,这个部分变量地点的函数被屡次调用时,每次调用这个部分变量在栈上的方位都不必定相同。并且只有当函数被调用时一般部分变量才被创立,函数调用结束则毁掉。
被static润饰的部分变量称作静态部分变量,它虽然是部分的,可是在程序的整个生命周期中存在。和部分变量相同,只能在函数内部拜访,不能被其他函数和源文件拜访,静态部分变量假如没有被用户初始化,则会被编译器主动赋值为0,由于其不会被毁掉,所以今后再调用静态部分变量的时分都用前次修正往后的值。
(3)当函数被static润饰后,就只能被当时文件中的被拜访,即便其它文件中含有相同称号的函数,也不会发生冲突。所以它很好地处理不同原文件中函数同名的问题。
10、函数指针数组
数组名是数组的第一个元素在内存中的地址,函数名是履行这个函数使命的代码在内存中的开始地址。函数指针能够指向函数的开始地址,因而函数名可经过函数指针加以保存。那么也能够界说一个数组保存若干个函数名,这便是函数指针数组。可是这若干个需求经过函数指针数组保存的函数有必要有相同的输入、输出值。
函数指针数组用在这种状况下,当咱们要依据一个变量值来决议履行某个函数时,咱们能够运用switch-case句子来做,可是当要处理的状况较多时,比方100种状况,那就需求写100个case来挑选,可是你大可不必这样做,这时分函数指针数组就派上用场了。详细怎么运用呢,举例如下:
首先要界说100个函数:
Int Func1(int,int);
.
.
.
Int Func100(int,int);
其次界说函数指针数组,并给数组赋值。
Int (*func[100])(int,int)={ Func1,Func2,…Func100};
终究,依据变量var的值来决议履行那个函数,并将履行成果回来给result。
Result = func[var](var1,var2);
依据var从数组中挑选正确的函数指针,并调用相应函数来履行,代码量大大削减,履行功率较高。
C的指针很灵敏,对指针的约束也较少,所以程序员在运用指针时需加倍当心。Pascal言语的指针哲学:“运用锤子可能会伤到你自己,所以咱们不给你锤子”。而C言语则是:“给你锤子,实际上你能够运用好锤子,祝你好运!”。
So, good luck!!!