表达式,语句,变量与宏的一些概念
表达式
表达式C语言中分为常量表达式,算术表达式,关系表达式,逻辑表达式,赋值表达式,逗号表达式和复合表达式etc。表达式可以分为左值和右值
左值(ell-value)可以出现在赋值运算符的左边或者右边,变量就是一个左值表达式
右值(are-value)只能出现在赋值运算符的右边,数字字面值就是一个右值表达式。
语句
语句是C语言用于表达命令逻辑语法结构,主要分为表达式语句,语句块,空语句,控制语句和特殊语句
变量
从语言的角度看,变量是一个左值,可以放在赋值运算符的左边接受一个值或者是右边用来给别的变量赋值,同时,变量也是一个表达式,这个表达式的值就是变量的值。此外,变量也可以从程序的本质来理解,对于任何一个问题及其解决方案,都要用 一组数据 和 这组数据的变化 来描述,描述好了就可以用计算机解决,描述不了的计算机也解决不了。变量就是用来表示一组类似的相似数据的其中一种方法,是所有现代程序设计语言的基础。
-
数据类型: C语言中,任何数据皆有其类型,就像水果可以被划分为苹果、橘子etc
-
常量:值不能更改的量,即柜子上一个上锁的抽屉,里面存了什么就是什么,你知道,但你改不了
-
变量:值可以更改的量,即似柜子上一个没锁的抽屉,今天用来放小苹果,明天放个大苹果
-
常量的类型:定义常量时指定的这块内存存放的数据类型,即上锁的抽屉里存的到底是苹果还是橘子
-
常量的地址:存储该常量的内存区域的第一个byte的地址,即上锁抽屉的编号
-
变量的类型:定义变量时指定的这个变量里面存储的数据类型,即没锁的抽屉专门用来放苹果还是放橘子
-
变量的地址:变量用来存储数据的那块内存的首地址,即没锁抽屉的编号,因为每个地址在内存中都是唯一的,所以变量的地址可以用来唯一的标识变量
-
值传递:把一个变量里存储的数据传递给另一个变量,即在另外一个没锁的抽屉里放一个之前一模一样的苹果
-
地址传递:把一个变量的地址传递给另一个变量,即在另外一个没锁的抽屉里放个纸条,上面写着之前那个抽屉的编号
-
作用域:变量工作范围的空间限定,即超过多远就不能直接打开抽屉,如果使用变量的代码不在该变量的作用域,需要使用"值传递"或"地址传递"的方式获得相应数据再使用
-
生命周期:变量工作范围的时间限定,即超过多久抽屉就被扔掉了,变量的生命周期一旦结束,它之前占据的内存就会被重新用作它用,这个变量也就不再存在了
-
自动变量:不需要指定变量的存储类型的变量,通常我们不进行任何修饰的变量的就是自动变量,需要使用
auto
关键字,现在已很少使用 -
寄存器变量:希望将该变量存储在寄存器中而不是内存中,可以提高变量的读取速度,需要使用
register
关键字,由于编译器的智能化,基本没有用了 -
全局变量:作用域是整个程序的变量,声明在main之外,需要
global
关键字来声明,生命周期和进程一样长 -
局部变量:作用域是函数体的变量,声明在函数体
fcn(){}
内,生命周期和函数一样长 -
块内变量 :作用域在块内的变量,声明在语句块
{}
内,生命周期和语句块一样长 -
静态变量 :生命周期和进程一样长的变量,限制了变量的作用域不会超出本文件,即全局变量被限制在本文件,局部和块内还是本来的作用域范围,声明需要使用
static
关键字 -
外部变量:该变量已经在其他源文件中被定义过,被拿到此文件中使用,声明一个外部变量需要使用
extern
关键字
宏
宏是C语言中使用#define
关键字定义的一个别名,在预处理阶段会进行宏替换,以字符串的形式原模原样的替换被定义的字符串
#define add (plus) //程序中所有的add组合都会被替换成(plus)
C语言内置宏
这些宏长用于调试代码,C语言的很多宏都使用__XXX__格式,Linux的API里很多宏都使用XXX_XXX格式,所以当使用自定义宏的时候,应该使用其他格式避免重名,宏只是进行字符组合的替换,在预处理阶段就做完了,如果除了bug很难找。
__LINE__ //该行代码的所在行号
__FILE__ //源文件的文件名
__DATE__ //源文件被翻译到代码时的日期。
__TIME__ //源代码翻译到目标代码的时间
__STDC__ //如果实现是标准的,则宏__STDC__含有十进制常量1。如果它含有任何其它数,则实现是非标准的。