标识符的作用域:
局部作用域:
写在{}内,作用范围为本函数;
全局作用域:
在所有函数体之外声明的变量,它可以在定义后的整个程序的任何地方被访问,包括所有的函数;
注意:
1.标识符必须先定义在使用;
2.在同一作用域中不能定义同名标识符;
3.在不同作用域中定义的同名标识符互不影响;
4.在两个或两个具有包含关系的不同作用域中定义的同名标识符,外层标识符在内层不可见
变量的生存期:
静态变量的生存期
静态变量在程序启动时分配内存,并保持存在直至程序结束。这意味着静态变量的生命周期是全局的,无论是全局静态变量还是局部静态变量。静态变量的初始化发生在程序启动时,对于未显式初始化的静态变量,它们会被初始化为零。局部静态变量即使在其所在的函数执行完毕后,其值依保留。
动态变量的生存期
动态变量通常是指在程序运行时动态分配内存的变量。这些变量的生命周期仅限于它们被分配和释放的时间段。一旦函数执行结束或者动态内存被释放,变量所占用的内存就不再保留,其生存期随之结束。
关键字:
auto关键字:用于声明自动变量,即局部变量。不过,在现代C语言编程中,auto关键字的使用并不常见,因为局部变量的默认存储类型就是自动的,所以通常不需要显式地使用auto来声明。
register关键字:在C语言中指示编译器尝试将变量存储在CPU的寄存器中,而不是常规的内存。这样做的目的是为了加快对该变量的访问速度,因为寄存器的读写速度远快于内存。
static关键字:用于定义变量或函数:
1.局部静态变量:
1.当在一个函数内部使用static关键字声明变量时,该变量成为局部静态变量。与普通局部变量不同,局部静态变量在第一次被初始化后,其值在函数调用之间保持不变,即其生存期跨越了函数调用的界限,直到整个程序结束。
2.局部静态变量的存储空间在数据段中分配,而非在栈上。这意味着在函数调用结束后,局部静态变量不会被释放,其值在下一次函数调用时仍然可用。
2.全局静态变量:
1.当在文件或函数外部使用static关键字声明变量时,该变量成为全局静态变量。全局静态变量的生存期是整个程序的生命周期,但其作用域被限制在声明它的文件内,即在其他源文件中不可见,这有助于避免命名冲突。
2.全局静态变量的初始化发生在程序开始执行之前,未初始化的全局静态变量将被初始化为零。
3.静态函数:
static关键字也可以用于函数声明,这样声明的函数称为静态函数。静态函数的作用域被限制在声明它的文件内,即在其他源文件中不可见。这有助于模块化代码,避免函数名称冲突,并限制函数的访问范围,提高代码的安全性和可维护性。
ertern关键字:声明变量或函数在其他文件中的定义,实现跨文件的数据共享和函数调用。
预处理命令:
#include:用来包含其他文件的内容,通常用于包含标准库头文件或用户自定义的头文件。
#include<stdio.h>//引用标准库函数;
#include"func.h"//引用自定义函数“func.h”;
#define: 用于定义宏,可以是无参宏或带参宏。无参宏是简单的文本替换,而带参宏在替换时会用实际参数替换形式参数。宏定义通常用于创建符号常量或简化复杂的表达式。
所有的宏都是简单的无脑替换;
条件编译
条件编译通常涉及以下几个关键字:
#if:开始一个条件编译块,后面跟随一个表达式,只有当表达式求值为真(非零)时,对应的代码块才会被编译。
#ifdef / #ifndef:分别用来检查指定的宏是否已经被定义或未被定义,并据此决定是否编译后续的代码块。
#else:提供一个备选的代码块,当#if、#ifdef或#ifndef后面的条件为假时,会编译#else后面的代码块。
#elif:作为#else和另一个#if的结合,用于在多个条件中进行检查。
#endif:结束一个条件编译块。
条件编译的典型应用场景
防止头文件多重包含:通过在头文件的开始处使用#ifndef和#define来确保头文件不会被包含多次。