指针初探
可以存储地址的变量叫指针,存储在之阵中的地址通常是另一个变量。
如果指针的类型是int,就只能指向int类型的变量,如果指针的类型是float,就只能指向float类型的变量。一般给定类型的指针写成type*,其中type是任意给定的类型。
类型名void表示没有指定类型,所以"void*"类型的指针可以包含任意类型的数据项地址,类型"void*"常常用作参数类型,或以独立于类型的方式处理数据的函数的返回值类型。任意类型的指针都可以传送为"void*"类型的值,在使用它时,再将其转换为合适的类型。例如,int类型变量的地址可以存储在"void*"类型的指针变量中。要访问存储在"void*"指针所指地址中的整数值,必须先把指针转换为int *类型。
声明指针
type* 指针名;
上面的指针是未初始化的,未初始化的指针非常危险,所以我们在声明它的时候要进行初始化操作。
type* 指针名 = NULL;
如果用已声明的变量地址初始化指针变量,可以使用寻址运算符&,例如:
int num = 99;
int* pointer = #
复制代码
使用指针访问值
使用间接运算符*可以访问指针所指的变量值,这个运算符也称为取消引用运算符,因为它用于取消对指针的引用。。假设声明一下的变量:
int number=15;
int *pointer=&number;
int result=0;
复制代码
pointer变量含有number变量的值,所以可以在表达式中使用它计算result的新值,例如:
result=*pointer+5;
复制代码
表达式*pointer等于存储在pointer中的地址的值,也就是存储在number变量中的值,所以result是15+5,等于20.
指向常量的指针
指向常量的指针总结来说,就是:
- 可以使用变量来改变数值,例如:value=20;
- 可以改变指针中的地址pvalue=&number;
- 不能通过指针修改数据,*pvalue=30L;
常量指针
使指针中存储的地址不能改变,可以使用下列方式:
int count=34;
int *const pcount=&count;
复制代码
如果重新给指针赋值编译器会产生错误信息,但是可以通过指针来修改指向变量的值 *pcount=40; 如果希望所有的信息都不能改变,可以将count定义为常量;
内存的使用
动态分配内存
动态分配内存的函数是:malloc();
在使用这个函数时,需要添加头文件
使用malloc函数需要指定要分配的内存字节数作为参数,这个函数返回分配内存的第一个字节的地址。
int *pNumber=(int*)malloc(25* sizeof(int));
复制代码
因为malloc函数返回的是void类型的指针,可以指向任意类型的数据,然而不能取消对指针的引用,因为它指向未具体说明的对象,所以需要强制类型转换。
如果因为某种原因不能分配请求的内存,malloc函数就会返回一个NULL,这个指针等于0,最好先使用if进行检查是否分配了内存。
释放动态分配的内存
要释放动态分配的内存,必须能访问引用内存块的地址。要释放动态分配的内存,而该内存的地址存储在pNumber指针中,可以使用下面的语句:
free(pNumber);
pNumber=NULL;
复制代码
用calloc()函数分配内存
相比malloc有两个优点:
- 它把内存分配为给定大小的数组
- 初始化了所分配的内存,所有位都是0.
calloc()需要两个参数:数组的元素个数和数组元素占用的字节数,这两个参数的类型都是size_t。