玩转指针(Playing with Pointers)
Question: What is a Pointer? What are its limitations? What are its benefits? How do we use it? What all operation we can perform using it?
In this article we are going to discover answers to all these questions.
指针是一个包含其它变量地址的变量,这里的其它变量可以是结构,数组或则其它基本类型的数据。定义指针的基本语法如下:
Datatype * identifier;
Datatype表示定义的指针变量中存储的是何种类型数据的地址。
*是间接取值/解引用符号。
identifier是定义的指针变量名。
指针使得我们能直接对内存操作改变内存中存储的数据,这是C语言的特征。无论何时我们定义一个指向某种类型数据的指针,我们可以称呼这个指针为——例如整型数据——指向整型数据的指针。
在C语言中指针和数组的关系很密切。数组的下标形式可以用指针形式替代,一般指针形式比较快。因此,数组中arr[n]第i各元素可以用*(arr + i)表示。之所以能这样表示是因为数组名本身就是数组第一个元素的地址。但数组名和指针还是有很重要的区别的。指针是一个变量,
ptr=arr;
和
ptr++;
是合法的,但数组名不是变量,这样的语句:
arr=ptr;
和
arr++;
都是不合法的,这里arr和ptr的定义也是不同的,分别是int arr[n] 和 int *ptr。
指针操作
现在我们来看看指针相关的操作。可行的操作有:给指针指向的变量赋值,指针变量和指针变量的加减,指针和整数的加减,指针减指针,利用指针对数组元素进行加减和比较。所有其它指针本身的算术都是非法的,包括但不限于指针本身相加,乘除,平移或掩码操作,加减浮点数,不加转换的赋值等。然而,如果两个指针指向同一个数组的元素,可以使用二进制运算== , != , < , >=。
C语言中还定义了一个一般化的指针——void *,也就是空指针。它可以被投射成任何类型的指针,默认情况下返回类型是库函数malloc(),void *类型指针不能de-reference(取指针指向的值)自己,所以需要转化为其它类型的指针。下面的代码包含了所有我们讨论过的方面。
#include<stdio.h> int main(void) { // Declaring a void pointer void *vptr; // Creating some pointer variables int arr[5]={34,5,17,39,1}; int *ptr1,*ptr,num,i; vptr=arr; ptr=(int *)vptr; // casting void * ptr1=arr+3; // pointer and integer addition if(ptr1 > ptr) //comparison of pointers num=ptr1-ptr; // subtraction of pointers printf("% d,% d,% d\n",*ptr,*ptr1,num); ptr = ptr1-2; //pointer and integer subtraction ptr1++; //pointer increment printf("% d,% d\n",*ptr,*ptr1); return 0; }
Output:
34 39 3
5 1
下面是一些非法的操作:
// invalid operations ptr1 = arr + ptr ; ptr1 +=ptr; ptr *=3; ptr1 /=ptr; char *cptr =ptr; ptr =*(arr +4.2); ptr <<2;