《C语言深度解剖》小记

今日阅读一本不错的书,叫《C语言深度解剖》

做一些读书笔记:

 

关于register修饰符注意点:虽然寄存器速度非常快,但是用register修饰符也有一些限制的:register变量必须是能被CPU寄存器所接受的类型。意味着register变量必须是一个单个的值,并且其长度应小于或者等于整型的长度。而且register变量可能不存放在内存中,所以不能用取地址运算符“&”来获取register变量的地址。

 

 

关于sizeofsizeof在计算变量所占空间大小时,括号可以省略,而计算类型(int)大小时不能省略。一般情况下,不要偷懒,乖乖加上括号,继续假装它是一个函数。严重提醒,sizeof不是函数。

 

对于case语句:case后面的只能是整型或字符型的常量或常量表达式。

 

Float变量与“零值”进行比较:

Float fTestVal = 0.0;

A), if(fTestVal == 0.0);   if(fTestVal != 0.0);

B), if((fTestVal >= -EPSINON) && (fTestVal <= EPSINON));//EPSINON为定义好的精度

EPSINON为定义好的精度,如果一个数落在[0.0-EPSINON,0.0+EPSINON]这个闭区间内,我们认为在某个精度内它的值与零值相等;否则不相等。扩展一下,把0.0替换为你想比较的任何一个浮点数,那我们就可以比较任意两个浮点数的大小了,当然是在某个精度内。

 

 

有关void :  Void 的字面意思是“空类型”,void *则可以指向任何类型的数据。Void 真正发挥的作用在于:1.对函数返回的限定;2.对函数参数的限定。

 

关于const :const修饰的只读变量不能用来作为定义数组的维数,也不能放在case关键字后面。

 

a&a的区别:看程序:

main()

{

       int a[5] = {1,2,3,4,5};

       int *ptr = (int *)(&a + 1);

       printf(“%d,%d”, *(a + 1),*(ptr - 1));

}

对指针进行加1操作,得到的是下一个元素的地址,而不是原有的地址值直接加1.所以,一个类型为T的指针的移动,以sizeof(T)为移动单位。因此,对于上述程序来说,a是一个一维数组,数组中有5个元素;ptr是一个int型的指针。

       &a + 1:取数组a的首地址,该地址的值加上了sizeof(a)的值,即&a + 5*sizeof(int),也就是下一个数组的首地址,显然当前指针已经越过了数组的界限。

       int *)(&a + 1:则是把上一步计算出来的地址,强制转换为int* 类型,复制给ptr

       *a + 1: a, &a的值是一样的,但是意思不一样,a是数组首元素的首地址,也就是a[0]的首地址,&a是数组的首地址,a + 1是数组下一元素的首地址,即a[1]的首地址,&a + 1是下一个数组的首地址。所以输出2

       *(ptr-1):因为ptr 是指5,并且ptrint * 类型,所以*ptr - 1)是指向a[4]输出5.

原文地址:https://www.cnblogs.com/nickchan/p/3104543.html