C语言深度解剖 (三)

2016-12-06 10:59:04来源:作者:镜缘浮影人点击

第七城市
前言

C语言的水深不见底,好在一些前辈们已经将很多雷区探了一遍

这里分享一下我在学习 《C语言深度解剖》过程中的一些笔记和心得

概要 typedef

typedef从字面上理解,是类型定义的意思,但其实应该是 typerename的意思,给一个已经存在的数据类型取一个别名,而非定义一个新的数据类型

void main(){typedef struct student{int age;char sex;} Stu_st,*Stu_pst; struct student stu1={23,'f'};Stu_st stu2={24,'m'}; //与 stu1 的定义形式等价struct student *stu3=&stu1;Stu_pst stu4=&stu2; //与 stu3 的定义形式等价}

虽然看起来很奇怪,但是只要将 struct student { ... }和 struct student { ... } *看作成一个整体,对整体进行命名就容易理解了

typedef 与 const void main(){typedef struct student{int age;char sex;} *Stu_pst; struct student stutmp1={23,'f'},stutmp2={24,'m'};const Stu_pst stu1=&stutmp1; //const 在前的定义 , 参考之前的const使用方法,如果将 Stu_pst 与 typedef struct student { ... } * 进行简单替换,理论上const 修饰的是 *stu1 从而限定的是 stu1 指的对象,即stu1指的对象不能改变,stu1本身应该可以改变值 Stu_pst const stu2=&stutmp2; //const 在后的定义 , 参考之前的const使用方法,如果将 Stu_pst 与 typedef struct student { ... } * 进行简单替换,理论上const 修饰的是 stu2 从而限定的是 stu2 本身,即stu2本身不能改变,stu2指的对象应该可以改变值stu1->age=12; stu1->sex='m'; //结果stu1所指的对象可以接受修改stu2->age=13;stu2->sex='f'; //stu1=&stutmp2; //error C2166: l-value specifies const object //stu1 本身不能修改,stu1所指的对象反而可以接受修改,说明了const修饰的其实是指针变量本身,与stu2的一样//stu2=&stutmp1; //error C2166: l-value specifies const object }

这个实验结果与我们之前的理解有些出入,原因是 typedef struct student { ... } *被编译器当作了一个整体,解释的过程中,Stu_pst 是一个类型名,被忽略掉,从而直接修饰了指针本身

typedef 与 #define #define INT32 intunsigned INT32 i=10;typedef int int32;//unsigned int32 k=10; //error C2061: syntax error : identifier 'k'//error C2059: syntax error : ';'//error C2513: '/*global*/ ' : no variable declared before '='typedef static int intx; //error C2159: more than one storage class specifiedint32 j=10;intx l=11;void main(){}

出错的信息代表,typedef 取的别名不支持类型扩展

#define PCHAR char*PCHAR p1,p2; // p1为指针,但是p2为字符类型typedef char* pchar;pchar p3,p4; //p3,p4都是指针void main(){int i=sizeof(p1); //4int j=sizeof(p2); //1int k=sizeof(p3); //4int l=sizeof(p4); //4}

由于预处理仅仅是简单的替换,所以p2为字符的情况很容易被忽略

加上数组与指针的情况

有以下几种声明

#define a int[10]typedef int a[10];#define a int*[10]typedef int * a[10];#define *a int[10]typedef int (*a)[10];#define *a * int[10]typedef int* (*a)[10];

和以下几种定义,它们之间相互结合,哪些可以正常使用

a[10] a[10];a[10] a;int a[10];int a;a b[10];a b;a* b[10];a* b;

以上的实例,实话说我目前还没完全理清,先记录下来,慢慢研究,准备专门开一篇来详细探究

注释

C语言里有两中注释方式: /**/和 //

/*这是*/#/*一条*/define/*合法的*/ID/*预处理*/replacement/*指*/list/*令*/// 从这里开始 /*这是/*非法*/的*/ 因为/*总是与离它最近的*/匹配void main(){int/*there is a comment here*/i=10;char* s="abcdefgh //hijklmn";//Is it a /valid comment? //warning C4010: single-line comment contains line-continuation characterin/*this is a comment*/t j; //error C2065: 'in' : undeclared identifier//error C2146: syntax error : missing ';' before identifier 't'//error C2065: 't' : undeclared identifier//error C2146: syntax error : missing ';' before identifier 'j'//error C2065: 'j' : undeclared identifier}

注释里可以包含换行符,但是编译过程中会产生警告

编译器会将注释剔除,但不是简单的剔除,而是用空格代替原来的注释

/*总是与离它最近的 */匹配

void main(){int x=5,y=0,a=4,*p;p=&a;//y=x/*p; //fatal error C1071: unexpected end of file found in comment y=x/ *p;y=x/(*p);}

只要 /与 *之间没有空格,都会被当作注释的开始,要进行合理规避

注释代码段时,应强调 为何做why而不是 怎么做how

接续符

/表示断行,编译器会将反斜杠剔除掉,跟在反斜杠后面的字符自动接续到前一行

#def/ine MAC/RO xyzvoid main(){//这是一条合法的/单行注释 //warning C4010: single-line comment contains line-continuation charactercha/r* s="comment te/st";}

反斜杠之后不能有空格,反斜杠的下一行之前也不能有空格

单引号,双引号 Item Comment 1 整型常数,32位系统下占4个byte '1' 字符常量,占1个byte "1" 字符串常量,占2个byte 逻辑运算 #include <stdio.h>void main(){int i=0;int j=0;if((++i>0)||(++j>0)){printf("%d %d/n",i,j); // 1 0}}

逻辑或,在遇到第一个表达式为真的情况下,会短路掉第二个表达式的计算,同样逻辑与遇到第一个表达式为假的时候也一样

位运算

a^=b; b^=a; a^=b;可以实现不用第三个临时变量来交换值

void main(){int i = 0x01 << 2 + 3; // 32 , 算术运算优先级高int j = 0x01 << 2 + 32; // 0 , 溢出int k = 0x01 << 2 - 3; // 0 int l = 0x01 >> 2 - 3; // 0 不能为负数int m = 0x01 << 2; // 4} ++,-- #include <stdio.h>void main(){int i = 3; int j = (++i) +(++i) +(++i); // i:6 j:16 非常奇怪的结果int k = 0;int l = (k++,k++,k++); // k:3 l:2 取第三个表达式的值int x =0;int y =(++x,x++,x+10); //x:2 y:12for(i=0,printf("First=%d",i);i<10,printf("Second=%d",i);i++,printf("Third=%d",i)) //会死循环下去,因为第二个表达式取值为printf的返回结果,永远为真{printf("Fourth=%d",i);}}
第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台