【C解析之4】指针
【C解析之四】指针

C解析之四指针
前言:C指针可以这么学。
在很多初学者而言,C/C++指针是一场灾难。C作为底层编程语言的首选,得益于其灵活的指针,使程序员在极大程度上可以直接操控内存,这在比如操作系统的实现上显得必不可少。然而过于灵活的指针有着让人担忧的另一面,不当的使用指针访问未定义空间引发不可知错误,篡改系统安全空间导致系统瘫痪等隐患,犹如挥之不去梦魇。
Java,Python等语言不再直接提供指针以保证安全,提供自动的内存处理以避免可能的安全隐患。
核心:指针:指针指向一块内存空间。
1.内存,变量,指针
以下示例一块内存:(每个格子表示一个内存单元)
用数字给每个内存单元编号(上图中的0,1,2...等编号),在计算机而言,编号就是内存地址(当然实际地址多是32位的二进制表示)。这很容易理解,给每个内存编号,通过这些编号可以找到这个内存单元,才能往这个内存单元里读取或则写入数据 ,这是计算机运行最基本的法则。
0 | 1 | 2 | 3 |
4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 |
int N; //定义一个int变量
int *P; //定义一个指向存储int类型内存单元的指针,就是内存地址
计算机角度而言,指针需要特别照顾,它存储的内存地址有别于一般数据。不管是变量还是指针都需要内存空间存储,唯一的不同点是存储内容性质不同,当访问到指针时,你自然会想到要看看它代表的那个内存地址存了些什么。
2.指针的操作
& ;取址运算符,借助&可以让指针指向特定变量的内存地址。
* ;间接访问运算符,借助*可以间接地把指针指向地址里的内容取出来。
+/-;加减运算符,类比房间号加减,很容易想到指针的加减实际上让指针指向了临近的内存。但需要注意,相对于单个变量的地址而言加减运算没有意义并具有风险,因为单个变量的地址临近的内存存储的内容是未知的。只有在指针指向一个数组(数组的内存地址是连续的),+/-便具有实际的价值。
3.指针的诱人之处
3.1高效的参数传递:函数参数的传递,一般是以实参复制给形参的方式实现,如果参数很大复制 过程巨大的消耗将让人难以接受,这时选择用指针传递参数的地址(地址大小是固定的)具有无可比拟的优势。
3.2动态内存分配支持:内存动态分配的实现依赖于指针,将动态开辟的地址赋给指针,通过指针对分配的内存进行访问,同样通过指针实现内存的释放回收。
3.3对链表的支持:链表是一种重要的数据管理结构,具有十分优秀的性能,应用十分广泛。指针的支持是链表能将不连续内存地址形成链的关键,指针就没有链表。
4.指针的隐患
4.1指针未初始化;在C中并不对指针指向空间的内容进行检查,如果指针没有初始化,对该指针的使用将导致不可预测的结果。
4.2局部变量地址被回收引起异常:指针指向一个局部变量的地址,在局部变量生存期结束时系统将自动收回其内存空间,此时指针便指向一个不存在的空间。在两个指针指向同一个地址空间时,其中一个释放将会导致另一个指针置空。
4.3指针改变引起的内存泄漏:
在这段代码中,指针P先是指向申请的int空间地址,随后P被赋值为int变量m的地址,开始申请的int空间将再也无法访问,同样无法释放,内存泄漏便发生了。
4.4指针越界:次情况多发生在指针访问数组时,这类问题稍不注意就可能发生,越界访问直接导致程序异常终止。