People Lack Willpower,Rather Than Strength!
1.全局变量和局部变量
- 所谓全局变量/局部变量是根据作用域来划分的.
-
局部变量:
- 定义:定义在函数/代码块/函数形参小括号内的变量称为局部变量;
- 作用域:从定义那一行开始直至其所在的代码块结束;
- 生命周期:从程序运行到定义他的那一行开始分配空间,直至程序离开该变量所在的作用域;
- 注意:同一作用域内不可以定义同名的局部变量;同名局部变量会覆盖全局变量.
-
全局变量:
- 定义在函数外边的变量称为全局变量
- 作用域范围:从定义哪行开始直到文件结尾
- 生命周期:程序一启动就会分配存储空间,直到程序结束
- 存储位置:静态存储区
- 可以重名,但其实他们拥有的空间是同一块.
-
static & extern 对局部变量的作用
-
static对局部变量的作用
- 延长局部变量的生命周期,从程序启动到程序退出,但是它并没有改变变量的作用域
- 定义变量的代码在整个程序运行期间仅仅会执行一次(该变量整个程序运行期间只创建一次).
-
extern用在函数内部
- 不是定义局部变量,它用在函数内部是声明一个全局变量
-
-
static & extern对全局变量的作用
-
static 修饰全局变量,表示是内部全局变量,只能文件内使用!
- 对全局变量修饰时,既是声明也是定义.⭐️
extern修饰全局变量时,表示声明该全局变量为外部变量,可以为多个文件共用. 但是虽然可以共用,A文件中定义的外部变量,B文件如果想使用,前提是得声明一下!!
-
- 声明外部变量/函数并不会开辟存储空间!!!🐓
- A文件中,如果只是声明了一个外部变量,而没有定义会报错:
extern int a;
int main(){
printf("%a\n",a);
return 0;
}
报错如下:
Undefined symbols for architecture x86_64:
"_a", referenced from:......
- static&extern对函数作用,就是声明外部/内部函数.
2.预处理指令
位置:预处理指令可以出现在程序的任何位置
好处:合理地使用预处理功能编写的程序便于阅读、修改、移植和调试,也有利于模块化程序设计。
-
1.宏:
- 格式:
#define 标识符 字符串
- 被定义为“宏”的标识符称为“宏名”。编译预处理时进行“宏代换”或“宏展开”.
- ""括起来的字符不会被当做宏名!
- 宏展开时只是简单的替换,不检查语法.
- 结束宏定义: #undef
- 格式:
-
2.条件编译
-
为什么要使用条件编译?
- 1)按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件。有利于程序的移植和调试。
- 2)条件编译当然也可以用条件语句来实现。 但是用条件语句将会对整个源程序进行编译,生成 的目标代码程序很长,而采用条件编译,则根据条件只编译其中的程序段1或程序段2,生成的目 标程序较短。
注意:条件编译后面的条件表达式中
不能识别变量
,它里面只能识别常量和宏定义!
-
3.typedef
-
typedef 原类型名 新类型名;
- 可见可以对类型名typedef,也可以是原类型本体.
-
宏定义和函数的区别
- 1> 行为: 宏定义不涉及存储空间的分配、参数类型匹配、参数传递、返回值问题
- 2> 时间: 函数调用在程序运行时执行,而宏替换只在编译预处理阶段进行。
所以带参数的宏比函数具有更高的执行效率
-
宏定义和typedef区别
- 时间:宏定义在预处理完成的;typedef在编译时完成.
- 功能:宏定义只是简单的字符串替换; typedef不是作简单的代换,而是对类型说明符重新命名。
重命名的标识符具有原类型名的所有功能!
4.const修饰符!!
- what is const?
- const是一个类型修饰符
1>使用const
修饰变量
则可以让变量的值不能改变2>常类型是指使用const
修饰的类型
,常类型定义的变量或对象的值是不能被更新的。-
3> 对于const修饰指针:
- 先看“*”的位置
如果const 在 *的左侧 表示值不能修改,但是指向可以改。 如果const 在 *的右侧 表示指向不能改,但是值可以改 如果在“*”的两侧都有const 标识指向和值都不能改。
- 编译器通常不为普通const常量分配存储空间,而是将它们保存在
符号表
中,这使得它成为一个编译期间的常量
,没有了存储与读内存的操作,使得它的效率也很高。那程序运行期间那??
- const是一个类型修饰符