一,数据结构分类
连续结构,跳转结构。
二,对变量的理解
在 C 语言中,变量是用于存储数据的抽象符号。变量本质上是一块内存区域的标识符(即它代表内存中的某一块区域),用来存储数据,并通过一个名字来访问这些数据。为了深入理解这一点,我们需要从几个方面来探讨:
1. 变量的本质
-
内存地址:变量本质上是内存中的一块存储区域,计算机内存中的每个单元(如字节)都有一个唯一的地址。一个变量通过名字绑定到一个内存地址,这样程序就可以通过这个变量名字来访问存储在该内存地址中的数据。
-
数据类型:每个变量都有一个数据类型(如
int
,float
,char
等),这决定了该变量可以存储的数据的类型及其大小。不同的数据类型需要不同大小的内存空间。例如,int
类型通常占 4 字节,char
类型占 1 字节,float
类型占 4 字节。 -
存储:C 语言中变量的存储位置通常是在栈(局部变量)、堆(动态分配的内存)、或者静态存储区(静态变量、全局变量)中。变量名只是程序中对内存位置的“引用”,它并不直接表示数据,而是帮助我们通过名字来访问实际存储的数据。
2. 为什么需要变量名
变量名提供了一种方便、直观的方法来访问内存中的数据。在 C 语言中,程序员通过变量名而不是直接通过内存地址来操作数据,这样做有几个重要的理由:
-
提高可读性:如果程序中的每个变量都用内存地址来表示,那么代码就会变得极为复杂且难以理解。变量名给每个存储单元提供了一个有意义的标签,能够让程序员容易理解变量的作用和内容。
-
避免直接操作内存地址:直接使用内存地址来操作数据不仅麻烦且容易出错,C 语言通过变量名隐藏了这些实现细节,程序员无需关心数据存储的物理地址,降低了程序出错的可能性。
-
可维护性:使用变量名使得代码更易于维护。当程序需要改变某个变量的实现(例如改变内存布局或者数据类型)时,只需要修改相关的变量声明和使用,而不需要到处修改内存地址。
3. 变量名与存储的数据的关系
-
内存映射:变量名实际上是内存地址的别名,它指向内存中的一块区域。每个变量名都绑定到一个特定的内存位置,通过这个名字,程序可以访问该位置存储的数据。变量名本身并不包含数据,它只是内存中数据的一种“标识”。
-
数据存储与类型:变量名指向的内存区域的大小和类型取决于变量的声明。例如,
int x
声明一个int
类型的变量,通常占 4 字节内存,而char y
声明一个char
类型的变量,通常占 1 字节内存。数据的存储结构和方式与变量的类型密切相关。 -
访问数据:通过变量名,程序可以对存储在内存中的数据进行操作。例如,
x = 5;
语句将5
存储到x
变量对应的内存位置。程序实际上是通过x
来间接访问内存中的那块存储区域,读取或者修改数据。
4. 内存模型
C 语言中的内存模型决定了变量名与数据存储的关系。在一个简单的 C 程序中,变量名指向的内存位置可以分配在不同的内存区域:
-
栈内存(Stack):局部变量通常存储在栈上,栈内存是一个先进后出(LIFO)的结构。栈上的内存分配和释放由编译器自动管理,程序员不需要手动干预。
-
堆内存(Heap):通过
malloc
、calloc
、realloc
等函数动态分配的内存通常存储在堆上。堆内存由程序员手动管理(例如通过free
释放)。 -
静态内存(Static Memory):全局变量和静态变量存储在静态内存区域,它们的生命周期从程序开始到结束,而不受栈的作用范围限制。
-
寄存器(Registers):编译器可能会将一些频繁使用的变量存储在寄存器中,这些变量具有比内存更快的访问速度,但寄存器的数量有限。
三,对控制流的理解
四,函数调用的理解
着重强调一下值传递和引用传递:
值传递就是复制忍者卡卡西,虽然长得一样,包含的数据一样,但终究是拷贝。但引用传递就是鲁迅与周树人的关系,名字不同,指的是同一个人。