C和指针学习笔记 (1)
第二章 基本知识
环境:分为翻译和执行2个过程。其中翻译可以理解为是一个从程序—目标代码—链接器的过程。编译过程有:
1预处理器:处理#define #include这一类代码的过程;
2源代码解析:产生错误和警告;
3优化器:有利于优化代码,提高效率。
执行的过程有
1 程序载入内存:在OS的帮助下,将代码载入到内存里,这样才可以跑得了啊
2 执行:不同地方声明的变量都在内存中不同的位置。比如局部变量等就存在堆栈中,而静态变量则存在静态区
3 终止:这里也分为正常终止(比如跑到主函数最后一句返回)和异常终止等等
词法规则
ANSI C规定了程序的函数声明是描述了函数要操作的数据类型,而函数则是定义了要执行的工作
词法里的东西没什么可多说的,注释不能嵌套,标识符不能用关键字或者数字开头,程序风格的缩进式都是老生常谈,唯一新看到的是三字母词:举个例子就是??(意思是[ ,??/的意思是/ ,这个从来没有用过,不过好像也没啥用。
举个例子 printf(“Delete file (are you really sure??):””);
第三章 数据
基本数据类型
这本书和谭浩强的不同之处就是把指针加到了基本数据类型,所以就是大类4种:整型,浮点数,指针,聚合类型。老外理解的不一样,不过以前老师也这么说过,学了这么久也觉得指针可以成为一种数据类型,他的类型就是地址,这种理解还是比较合理的。但是声明和引用方式不大一样罢了。
整型有字符型,短整型,整型,长整型。分为有符号和无符号。由于不同的主机和不同的编译器定义的不一样,所以此书的一种说法,也是ANSI C的一种规定。1,长整型至少应该和整型一样长 2, 整型至少应该和短整型一样长。
浮点数:float,double,long double
对于浮点数也有同样类似的规定,不多说了,一个意思。总之就是你至少不能比小弟还要小,最起码是一样的。
指针:说明了一个指针常量是不可控制且无意义的,这个的理解大概就是程序员定义指针的时候无法知道编译器为其分配的地址到底是在哪里
基本声明
1. C编译器并不检查数组的下标,是否在合理的范围之内,这样做是有利有弊的。弊端不用说了,有点就是可以提高编译器的效率。不过我个人觉得还有优点就是可以对数组前后的内存进行操作,有点指针的味道。
2. 隐式声明,这个是说函数不显式的声明返回值,将返回一个整形,所以说大家写函数的时候很多时候没有加函数类型,但是还能编译运行的原因。
3. typedef:说明了一个和#define 之间的一个很大的区别,这个很多书上都有,总之定义类型的时候,切忌用#define。
4.const 用法,老生常谈的了,const还是说成只读的好了,我也就能理解这么多。还是老例子 int const *p 指针指向的值不可变
int * const p 指针只读
int const *const p 都是不可变的
要是想保护某个变量不被修改,还是用下const吧
5 下面是一个作用域的问题,以前都没怎么认真深入过
1 代码块作用域,位于一对花括号之间的所有语句
2 文件作用域,任何在所有代码块之外声明的标识符
3 原型作用域,在函数原型中声明的参数名
4 函数作用域,只适用于语句标签 类似goto之类的,没啥用,goto语句都不用的
6. 连接属性
None:总是被当做单独的个体,该标识符的多个声明被当做独立不同的实体处理
Internal:在同一个源文件内,所有声明指同一个实体,但位于不同的源文件,多个声明分属不同的实体
External:不论声明多少次,位于多少个文件,都是表示同一个实体
7. 存储类型
3个地方:1 普通内存
2 堆栈
3 硬件寄存器中
变量的缺省存储类型取决于声明位置。
1 静态变量 : 代码块之外声明的变量,在整个运行期间都存在
2 自动变量 : 代码块内部声明,存储在堆栈中,执行到声明语句时才分配内存给他,离开代码块以后,OS自动收回了。
3 寄存器变量: 在寄存器里跑,在这里面跑速度会很快,但是个数有限,不能放太多的,建议把经常使用的变量,尤其指针放进去,会快很多的。
Static的使用,这个又是个老生常谈的例子,到处都有例子,引用一个老师给我的例子吧(不知道是不是他原创的)
Static:用于限定变量和函数的生命周期和作用域。
Static静态局部变量。
生命期:从函数第一次调用到整个main函数结束。
作用域:定义函数内从定义该变量开始到该语句块结束。
储存位置:静态存储区
定义时候可以赋值,定义语句的赋值只影响第一次初始化该变量。如果不进行初始化,内部类型初始化为0.用户自定义类型,依靠各自的构造函数来初始化
Static全局变量
生命期:同全局变量,整个工程全过程
作用域:本模块内从定义或者声明该变量开始到本模块结束的区域内。不可声明为extern
储存位置:静态存储区
定义时候可以赋值,定义语句的赋值只影响第一次初始化该变量。如果不进行初始化,内部类型初始化为0.用户自定义类型,依靠各自的构造函数来初始化
Static静态函数
作用域:本模块内从定义或者声明该变量开始到本模块结束的区域内。不可声明为extern
生命期:无
储存位置:无
Static对变量和函数的适用范围做出了比较额外的限制。为什么还要用static关键字呢,局部静态变量和静态全局变量都可以用全局变量来代替,函数也是,为什么要多此一举呢?
答案:加static关键字正是为了限制函数和变量的使用范围,避免不相关的代码调用该变量或者函数。保持名字的相对清洁度