可以对指针进行哪些操作?C提供了一些基本的指针操作,下面的程序实例给出了8种不同的操作,为了显示操作的结果,该程序提供了指针的数值(即所谓指向指针的地址),若编译器不支持%p转换说明,可以用%u或者%lu代替。
#include<stdio.h>
int main(void)
{
int urn[5] = { 100,200,300,400,500 };
int * ptr1, *ptr2, *ptr3;
ptr1 = urn;
ptr2 = &urn[2];
printf("pointer value, dereferenced pointer, pointer address:\n");
printf("ptr1 = 5p, *ptr2 = %d, &ptr1 = %p\n", ptr1, ptr2, &ptr1);
//指针加法
ptr3 = ptr1 + 4;
printf("\n adding an int to a pointer :\n");
printf("ptr1 + 4 = 5p, *(ptr1 + 4) = %d\n", ptr1 + 4, *(ptr1 + 4));
ptr1++;
printf("\nvalues after ptr1++:\n");
printf("ptr1 = %p, *ptr1 = %d, &ptr1 = %p\n", ptr1, *ptr1, &ptr1);
ptr2--;
printf("\n values after --ptr2:\n");
printf("ptr1 = %p, *ptr2 = %d, &ptr2 = %p\n ", ptr2, *ptr2, &ptr2);
--ptr1;
++ptr2;
printf("\nPointers reset to original values:\n");
printf("ptr1 = %p, ptr2 = %p\n", ptr1, ptr2);
//一个指针减掉另外一个指针
printf("\nsubtracting one pointer from anothor:\n");
printf("ptr2 = %p, ptr1 = %p, ptr2 -ptr1 = %td\n", ptr2, ptr1, ptr2 - ptr1);
//一个指针减掉另外一个整数
printf("ptr3 = %p, ptr3 - 2 = %p\n", ptr3, ptr3 - 2);
return 0;
}
总结如下:
- 赋值:可以把地址赋给指针,用数组名、带指运算符(&)的变量名、另一个指针进行赋值。在程序实例中,urn数组首地址赋给了ptr1。需要强调的是,地址应该和指针类型兼容,也就是说,不能把double类型地址给int指针。
- 解引用:*运算符给出了指针的指向地址上存储的数值。所以,*ptr1的初始数值为100,该数值存储在0x7fff5fbff8f0的地址上。
- 取址:和所有的变量一样,指针变量也有自己的地址和数值。
- 指针和整数相加:可以使用+运算符把指针和整数相加。或者是整数和指针相加。所以,ptr1++相当于把ptr1数值加上4(系统中int为4字节),ptr1指向了urn[1],变量不会因为数值发生变化就变动位置。
- 指针减掉一个整数:使用-运算符从一个指针减掉一个整数。指针必须是第一个运算对象,整数是第二个运算对象。该整数将会乘以组织向类型的大小(以字节为单位),然后用初始地址减掉乘积。所以ptr3 - 2与&urn[2]等价,若相减结果超过了初始指针所指向的数组范围,计算结果是未定义的。除非正好超过数组末尾第一个位置,C保证该指针有效。
- 递减指针:递减ptr2使其指向了数组的第二个元素而不是第三个元素,前缀或者后缀指针都可以使用,注意,在重置ptr1和ptr2前,他们都会指向urn[1]。
- 指针求差:可以计算两个指针的差值,一般情况下,求差的两个指针分别指向同一个数组的不同元素,通过计算两个元素之间的距离,差值的单位与数组类型单位相同,只要两个指针都指向相同的数组(或者一个指针指向数组后面一个的地址),则C结果都是有效的。
- 比较:使用关系运算符,可以比较两个指针的数值,前提是两个指针都是指向相同类型的对象。
注意:在递增递减指针时候,编译器不会检查是否仍然指向数组元素。