第二章阅读笔记:
1) y=x/*p,这条指令并不表示成这样:x除以p指向的内存里的值,把结果赋值给y。 在编译器上测试一下,会提示出错,它会把/*当作是一段注释的开始,把其后面的内容都当作注释,直到出现*/为止。
可以修改为 y=x/(*p),甚至 y=x/ *p都可,最后在编译阶段去除注释内容,并不是单纯的全部清除,而是通过“空格”替换,因此诸如int/*...*/i;并不会出错,而in/*..*/t i;则会出错
2) 关于自加与自减运算,++和--。 ++、--作为前缀,必然是先自加或自减,然后再做别的运算;但是作为后缀时的自加、自减则与自己想象的不同。
i = 3; k =(i++) + (i++) + (i++); 那么printf("%d\n",k)的值是多少,本来以为会是12呢,测试才知道k = 9,这是因为对于后缀的自加和自减运算都是在本计算单位计算结束后再自加或自减,在例子中也就是当i遇到最后一个分号的时候才进行自加或自减的
3)移位运算符的优先级低于算术运算符,因此0x01<<2+3的结果不为7,而是32,先进行算术加法,再进行移位
第三章阅读笔记:
4) #define BSC //
#define BMC /*
#define EMC */
则,BSC my single-line comment
BMC my multi-line comment EMC
都会出错,因为在编译器的处理流程中,注释先于预处理指令被处理,当这两行宏被展开时,注释语句已经处理完毕,此时再出现//或者/**/自然出错,因此试图用宏开始或结束一段注释是不行的
5)#define SUM(x) (x) + (x) 与 #define SUM (x) (x) + (x)不同,SUM与(x)间的空格只在定义时有用,在使用的时候,会自动被编译器给忽略
6)关于字节对齐,字、双字、四字在自然边界上不需要在内存中对齐(对字,双字,和四字来说,自然边界分别是偶数地址,可以被4整除的地址,和可以被8整除的地址)。一个字或双字操作数跨越了4字节边界,或者一个四字操作数跨越了8字节边界,被认为是未对齐的,从而需要两次总线周期来访问内存。一个字起始地址是奇数但却没有跨越字边界被认为是对齐的,能够在一个总线周期中被访问
struct my_struct1 struct my_struct2
{ {
char c1; char c1;
short s; char c2;
char c2; short s;
int i; int i;
} }
在这里sizeof(my_struct1) = 12; sizeof(my_struct2) = 8;
宏#pragma pack()可以改变编译器的默认对齐方式,指令#pragma pack(n),编译器将按照n个字节对齐,使用指令#pragma pack(),编译器将取消自定义对齐方式,在两个宏定义之间的代码将按照n字节对齐
对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个
7)#define SQR(x) printf("The square of x is %d.\n",((x)*(x)));
则使用宏SQR(8);输出为The square of x is 64.
#define SQR(x) printf("The square of "#x" is %d.\n",((x)*(x)));
则使用宏SQR(8);输出为The square of 8 is 64.
阅读(1045) | 评论(0) | 转发(0) |