- 公开视频 -> 链接点击跳转公开课程
- 博客首页 -> 链接点击跳转博客主页
目录
局部变量
-
在C语言中,局部变量是在函数内部或代码块内部声明的变量。它们只在其被声明的函数或代码块内可见,超出范围的地方无法访问。
-
局部性:局部变量的作用域仅限于其所在的函数或代码块,超出该范围无法直接访问。
-
生命周期:局部变量在其所在的函数或代码块的执行期间存在,当函数或代码块执行结束时,局部变量的存储空间会被释放。
-
默认值:局部变量不会自动初始化,使用之前需要手动赋值。
#include <stdio.h> #include <stdlib.h> void Fun(int num) { //函数Fun内部的局部变量 int a = 0; //函数内局部变量未赋值时默认值为堆栈数据0xcccccccc int b; } int main() { //参数压栈 -> PUSH //函数调用 -> CALL //堆栈平衡 -> ESP Fun(5); //main函数当中无法使用Fun函数内部定义的局部变量 //a = 2; if (1) { //main函数内部if语句代码块内定义的局部变量 int b = 0; b = 1; } //超出局部变量定义的代码块外无法访问 //b = 2; return 0; }
-
全局变量
-
在C语言中,全局变量是在函数外部声明的变量,它们可以被程序中的所有函数访问。全局变量具有以下特点:
-
全局性:全局变量的作用域跨越整个程序,可以在程序中的任何函数中访问。
-
生命周期:全局变量在程序的整个执行期间都存在,它们的存储空间在程序启动时分配,直到程序结束时才会释放。
-
默认值:全局变量如果没有被显式初始化,会自动被初始化为0(对于数值类型)或空指针(对于指针类型)。
#include <stdio.h> #include <stdlib.h> //全局变量 int g_Num = 0x12345678; void Fun() { g_Num = 2; } int main() { //全局变量数据编译后默认存储在文件内部 printf("%x - %x \r\n", &g_Num ,g_Num); g_Num = 1; system("pause"); return 0; }
-
-
多个源文件包含一个全局变量
- 定义头文件声明全局变量extern int g_Num;
- 定义源文件定义全局变量int g_Num = 0;
静态变量
-
在C语言中,静态变量是在函数内部声明的变量,但其生命周期超出了函数的执行范围。静态变量具有以下特点:
-
存储位置:静态变量存储在静态数据区,而不是栈上。它在程序运行期间一直存在,不会在每次函数调用时重新创建和销毁。
-
初始化:静态变量默认情况下会被初始化为0(对于数值类型)或空指针(对于指针类型)。
-
作用域:静态变量的作用域仅限于声明它的函数内部,但其在函数调用之间保持其值。
#include <stdio.h> #include <stdlib.h> void Fun() { //局部变量 -> 线程栈区 int a = 0; printf("A -> %d \r\n", ++a); //静态变量 -> 初始化只执行一次 生命周期不会随着函数调用结束 static int b = 10; printf("B -> %d \r\n", ++b); } int main() { Fun(); Fun(); Fun(); return 0; }
-
-
寄存器变量
- 寄存器变量是一种通知编译器将变量存储在寄存器中的请求。它的目的是通过减少访问内存的次数来提高程序的执行效率。
- 编译器可以选择忽略这个请求,因为寄存器的数量是有限的,而且寄存器变量的地址是不可用的。
-
寄存器变量用于频繁访问的变量,通常是在循环或频繁调用的函数中使用。
-
只有整型变量(如int、char等)才能声明为寄存器变量。
-
寄存器变量不能直接获取其地址,因此无法使用指针指向寄存器变量。
-
编译器可以忽略寄存器变量的请求,特别是当寄存器数量有限时或者变量太大无法放入寄存器时。
#include <stdio.h> int main() { register int x; // 声明寄存器变量 int i, sum = 0; for (i = 1; i <= 10000; i++) { x = i; // 将i赋值给寄存器变量x sum += x; } printf("Sum: %d\n", sum); return 0; }
- 寄存器变量是一种通知编译器将变量存储在寄存器中的请求。
- 寄存器变量用于频繁访问的变量,可以提高程序的执行效率。
- 只有整型变量才能声明为寄存器变量。
- 编译器可以选择忽略寄存器变量的请求,因此不能依赖寄存器变量一定会存储在寄存器中。
- 寄存器变量的地址不可用,无法使用指针指向寄存器变量。
枚举变量
- 枚举变量是一种用户定义的数据类型,用于定义一组命名的整数常量。枚举变量提供了一种更加可读和可维护的方式来表示相关的常量值。
-
以下是枚举变量的特点和使用方法:
-
枚举变量由一组预定义的常量值组成,称为枚举器(enumerator)。
-
每个枚举器都有一个与之关联的整数值,从0开始依次递增。
-
枚举变量的默认值是枚举器中的第一个值(默认为0)。
-
枚举变量的值只能是枚举器中的某个值,不能赋予其他整数值。
#include <stdio.h> #include <stdlib.h> //枚举变量 enum ThreadState { THREAD_READY, THREAD_WAIT, THREAD_RUNNING, THREAD_SUSPEND = 10, THREAD_RESUME, THREAD_EXIT }; int main() { printf("%d \r\n", THREAD_EXIT); return 0; }
-
- 枚举变量是一种用户定义的数据类型,用于定义一组命名的整数常量。
- 枚举变量由一组预定义的常量值组成,称为枚举器。
- 枚举变量的默认值是枚举器中的第一个值,默认为0。
- 枚举变量的值只能是枚举器中的某个值,不能赋予其他整数值。
- 枚举变量可以提高代码的可读性和可维护性,特别是当需要表示一组相关的常量值时。
联合体
-
联合体是一种特殊的数据类型,允许在相同的内存位置存储不同的数据类型。联合体的所有成员共享同一块内存空间,但一次只能存储其中的一个成员。
- 联合体使用union关键字进行定义。
- 联合体的成员可以是不同的数据类型,但它们共享同一块内存空间。
- 联合体的大小等于最大成员的大小。
- 可以通过成员访问运算符.来访问联合体的成员。
-
#include <stdio.h> #include <stdlib.h> union MyUnion { char a; short b; int i; }; int main() { union MyUnion u; u.a = 0xDD; u.b = 0xAABB; u.i = 0x12345678; printf("%x \r\n", u.a); printf("%x \r\n", u.b); printf("%x \r\n", u.i); return 0; }
- 联合体是一种特殊的数据类型,允许在相同的内存位置存储不同的数据类型。
- 联合体使用union关键字进行定义。
- 联合体的成员可以是不同的数据类型,但它们共享同一块内存空间。
- 联合体的大小等于最大成员的大小。
- 可以通过成员访问运算符.来访问联合体的成员。
TYPEDEF
-
typedef是C语言中的一个关键字,它用于为现有的数据类型创建一个新的名称。通过typedef,可以为复杂的类型或自定义的结构体/联合体创建更简洁、易读的别名。
-
typedef与数据类型的定义一起使用,用于为数据类型创建别名。
#include <stdio.h> #include <stdlib.h> //typedef 数据类型 别名; //typedef unsigned int size_t; typedef int 整数型; typedef void 无返回; 无返回 调试输出() { } int main() { printf("%d \r\n", sizeof(整数型)); 整数型 血量 = 10; printf("%d \r\n", 血量); 调试输出(); return 0; }
-
typedef可以为基本数据类型(如int、char等)或复杂数据类型(如结构体、联合体等)创建别名。
#include <stdio.h> #include <stdlib.h> typedef struct _Animal { int age; int score; }Animal, * PAnimal; int main() { //struct _Animal dog = { 3, 99 }; Animal dog = { 3, 99 }; //struct _Animal* p1 = &dog; PAnimal p1 = &dog; return 0; }
-
typedef声明的别名可以像原始数据类型一样使用,可以用于声明变量、函数参数和返回值等。
#include <stdio.h> #include <stdlib.h> int Add(int a, int b) { return a + b; } int Sub(int a, int b) { return a - b; } int main() { //函数指针 //返回值 (*变量名)(参数, 参数, ...) int (*Fun)(int, int); typedef int (*CallBack)(int, int); CallBack add = Add; add(1, 2); CallBack sub = Sub; sub(2, 1); return 0; }
-