C学习笔记
C学习笔记
- Fang XS.
- 1452512966@qq.com
- 如果有错误,希望被指出,学习技术的路难免会磕磕绊绊,不定期更新
- 副作用与序列点
- const
- static
- volatile
- 数字的前缀与后缀
- C语言面向对象
副作用与序列点
- 副作用
- 副作用是指对数据对象或文件的修改。
- 对于表达式来说, 主要作用是求表达式的值, 其他作用为副作用。
- 例如,a=3;C会对表达式进行求值,表达式值为3,而a这个对象的值也被修改成3。
- 序列点
- 序列点有: 完整表达式(full expression), 表示语句结束的分号, 逻辑运算符 && 和 ||, 逗号运算符。
- 程序执行到序列点时, 所有副作用都在序列点之前发生。
- 例如,a=3;,程序修改了a的值就是副作用,这个副作用在这个语句的序列点;之前发生。
- C标准
- C标准规定:在两个序列点之间,一个对象所保存的值最多只能被修改一次。
- C标准规定:在两个序列点之间,副作用的执行顺序是不确定的。
- C标准规定:两个序列点之间的执行顺序是任意的。当然这个任意是在不违背操作符优先级和结合特性的前提下的,这个规定的意义是为编译器的优化留下空间。
- 总结
- 这样看来,我们写C程序大多数情况就是在用C的副作用。
- 尽量不要这样写a = i++ + ++j;这样的代码,碰到考试或者面试,先分析表达式的运算优先级,i++先取值后自增,++j先自增再取值。
const
- 关于const修饰变量
- 在C中,const所修饰的变量,具有只读属性。
- 在C中,const所修饰的变量,本身还是变量,只是被限定为只读,不可修改。
- 在C中,const所修饰的变量,被限定为只读属性,通过非常规操作还是可以改,这里不讨论。
- 关于const修饰指针
- const int *p修饰指针p所指向的值不可改,常量指针。
- int const *p修饰指针p所指向的值不可改,常量指针。
- int * const p修饰指针p不可改,指针常量。
- const int * const p修饰指针和指针p所指向的值不可改,指向常量的指针常量。
- 总结
- const修饰指针,分3种情况,修饰指针指向的值,修饰指针,修饰指针和指向的值。
- 修饰指针不可改,const放在*的右边。
- 修饰指针指向的值不可改,const放在*的左边。
- 修饰指针和指向的值都不可改,const在*的左边和右边。
- 在函数中,const一般用来修饰形参,来确保传进的值或指针,不被本函数修改。
static
- 在C中, static使用恰当能够大大提高程序的模块化特性,有利于扩展和维护。
- 在C中, static用来修饰变量 称静态变量
- 函数内局部变量
- 函数内局部变量,只具有局部作用域,局部生命周期,在栈区分配内存空间。
- 被static修饰的局部变量称静态局部变量。
- 具有局部作用域,全局生命周期。
- 静态局部变量,只被初始化一次,在全局数据区分配内存空间。
- 函数外全局变量
- 函数外全局变量,具有全局作用域,全局生命周期,在全局数据区分配内存空间。
- 被static修饰的全局变量称静态全局变量
- 具有文件作用域,全局生命周期,只在模块内访问,在全局数据区分配内存空间。
- 在C中, static用来修饰函数 称静态函数
- 静态函数只能在声明它的文件中可见,其他文件不能引用该函数。
- 不同的文件可以使用相同名字的静态函数,互不影响。
- 不被static修饰的函数,隐含被声明为extern,其他文件可以访问。
volatile
- 翻译过来是 adj.易变的,动荡不定的,反复无常的;
- volatile声明的变量,提醒编译器随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。
- 现在的编译器趋向于智能化,经过时间的沉淀,bug越来越少,越来越智能,甚至有的变量,编译器可能优化读取和存储,来提升程序的速度和性能。
- 在嵌入式中,有些指针存储的是寄存器的地址,而寄存器的值可以不仅仅被程序改变,也可以被外设,或者引脚电平变化而随之改变,这样一来,如果编译器对其进行优化,暂时使用寄存器中的值,那么编译器优化保存的值,跟实际的值是不一样的,会出现bug。
数字的前缀与后缀
- 在数据前后加前后缀通常是为了指明常量的数据类型,以便与变量的数据类型保持一致或保证数据运算的正确性.
- 前缀(大小写都一样)
- 0x表示该数值是十六进制表示的。
- 0表示该数值是八进制表示的。
- 后缀(大小写都一样)
- U表示该常数用无符号整型方式存储,相当于unsigned int.
- L表示该常数用长整型方式存储,相当于long.
- F表示该常数用浮点方式存储,相当于float.
- H表示该数值是用十六进制表示的。
- B表示该数值是用八进制表示的。
C语言面向对象
- 在学习C++面向对象过程中,突然想到C生万物,那C是否可以面向对象来编程。
- 答案是肯定的。
- 只是一些C++中,面向对象天然就有的构造方法,析构方法,虚函数,虚函数指针,虚函数列表…
C语言要手动实现,创建对象需要手动调用。 - 在C中, 对象是一块能存储数据,且具有某种类型的内存空间。
- 在C++中,对象是是类的实例,一个对象必须属于一个自己的类,因此在定义对象前,必须要定义好对象所属的类。也就是先将具体事务抽象成类,将类实例化就得到一个对象。这样看来实例化的对象本质也是一段内存空间。研究C++对象模型也是在研究对象如何在内存中排布的。
- 这里给出一个简单的类实现,说明及注意事项测试案例等都在README.md 参考简单类实现