第7章 指针
存储一个数据的地址取决于所使用的计算机、操作系统和编译器。
可以存储地址的变量称为指针,存储在指针中的地址通常是另一个变量。
编译器必须知道它所指的变量的类型,否则不可能知道如何处理它所指的内存的内容。
void*类型的指针可以包含任意类型的数据项地址。
未初始化的指针是非常危险的,所以应总是在声明指针时对它进行初始化。
NULL在C语言中是一个特殊的常量,对于指针它表示0。NULL是一个不指向任何内存位置的值。
间接运算符*可以访问指针所指的变量值。因为它用于取消对指针的引用,也称为取消引用运算符。
使用指针时,可以使用const关键字,使该指针指向的值不能改变,也可以使指针中存储的地址不能改变。
最好将p作为指针名的第一个字母。
数组是相同类型的对象的集合,可以用一个名称引用。指针是一个变量,它的值是给定类型的另一个变量或常量的地址。使用指针可以在不同的时间访问不同的变量,只要它们类型相同即可。
数组和指针似乎完全不同,却有非常密切的关系,有时还可以互换。但数组不是指针,它们有一个重要的区别:可以改变指针包含的地址,但不能改变数组名称引用的地址。
只有使用指针,才能动态分配内存。在程序的执行期间分配内存时,内存区域中的这个空间称为堆(heap)。还有一个内存区域,称为堆栈(stack),其中空间分配给函数的参数和本地变量。在执行完该函数后,存储参数和本地变量的内存空间就会释放。堆中的内存是由程序员控制的。
在运行是分配内存的最简单的标准库函数是malloc()。malloc()函数需指定要分配的内存字节数作为参数,函数返回所分配内存的第一个字节的地址。
sizeof运算符返回一个size_t类型的无符号整数,该整数是存储它的参数需要的字节数。把数组名作为参数时,sizeof返回存储整个数组所需的字节数。
calloc()函数和malloc()函数相比有两个优点:第一,它把内存分配为给定大小的数组;第二,它初始化了所分配的内存,所有的位都是0。calloc()函数需要两个参数:数组的元素个数和数组元素占用的字节数。
在动态分配内存是,应总是在不需要该内存是释放它们。当动态分配了一些内存时,没有保留对它们的引用,就会出现内存泄漏,此时无法释放内存。释放内存用free()函数,它的形参是void*类型。
realloc()函数可以重用通过malloc()或calloc()(或realloc())分配的内存。该函数需要两个参数:一个是指针,它包含前面调用malloc()或calloc()(或realloc())返回的地址,另一个是要分配的新内存的字节数。
动态分配内存的基本规则:
1.避免分配大量的小内存块。分配堆上的内存有一些系统开销,所以分配许多小的内存块比分配几个大的内存块的系统开销大。
2.仅在需要时分配内存。只要使用完堆上的内存块,就释放它。
3.总是确保释放已分配的内存。在编写分配内存的代码时,就要确定在代码的什么地方释放内存。
4.在释放内存之前,确保不会无意中覆盖堆上分配的内存地址,否则程序就会发生内存泄漏。在循环中分配内存时,要特别小心。
指针错误会产生灾难性的结果。如果使用一个没有指定地址值的未初始化指针存储值,该指针使用的地址就是存储在该指针位置的任何内容,这可能是内存中任何一个位置。
文章评论(0条评论)
登录后参与讨论