掌握C语言必知要点(续)
8、边界对齐
本文引用地址:http://www.amcfsurvey.com/article/266192.htmCPU在单位时间内(同一时间)能一次处理的二进制数的位数叫字长。处理字长为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!!!
c语言相关文章:c语言教程
评论