C语言指针经典知识汇总( 二 )

在指针的算术运算中, 指针所指向的类型有很大的作用 。
 
3、指针的值
指针的值是指针本身存储的数值, 这个值将被编译器当作一个地址, 而不是一个一般的数值 。在 32 位程序里, 所有类型的指针的值都是一个 32 位 整数, 因为 32 位程序里内存地址全都是 32 位长 。
指针所指向的内存区就是从指针的值所代表的那个内存地址开始, 长度为 sizeof(指针所指向的类型)的一片内存区 。
以后, 我们说一个指针的值是 XX, 就相当于说该指针指向了以 XX 为首地址的一片内存区域; 我们说一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址 。
指针所指向的内存区和指针所指向的类型是两个完全不同的概念 。在例一中, 指针所指向的类型已经有了, 但由于指针还未初始化, 所以它所指向的内存区是不存在的, 或者说是无意义的 。
以后, 每遇到一个指针, 都应该问问: 这个指针的类型是什么? 指针指向的类型是什么? 该指针指向了哪里? (重点注意)。
 
4、指针本身所占据的内存区
指针本身占了多大的内存? 你只要用函数 sizeof(指针的类型)测一下就知道了 。在 32 位平台里, 指针本身占据了 4 个字节的长度 。指针本身占据的内存这个概念在判断一个指针表达式(后面会解释) 是否是左值时很有用 。
 
指针的算术运算指针可以加上或减去一个整数 。指针的这种运算的意义和通常的数值的加减运算的意义是不一样的, 以单元为单位 。
这在内存上体现为:相对这个指针向后偏移多少个单位或向前偏移了多少个单位,这里的单位与指针变量的类型有关 。在32bit环境下,int类型占4个字节,float占4字节,double类型占8字节,char占1字节 。
【注意】一些处理整数的操作不能用来处理指针 。例如,可以把两个整数相乘,但是不能把两个指针相乘 。
示例程序#include <stdio.h>int main(void){inta = 10, *pa = &a;floatb = 6.6, *pb = &b;charc = 'a', *pc = &c;double d = 2.14e9, *pd = &d;//最初的值printf("pa0=%d, pb0=%d, pc0=%d, pd0=%dn", pa, pb, pc, pd);//加法运算pa += 2; pb += 2; pc += 2;pd += 2;printf("pa1=%d, pb1=%d, pc1=%d, pd1=%dn", pa, pb, pc, pd);//减法运算pa -= 1; pb -= 1; pc -= 1;pd -= 1;printf("pa2=%d, pb2=%d, pc2=%d, pd2=%dn", pa, pb, pc, pd);return 0;}运行结果为:
pa0=6422268, pb0=6422264, pc0=6422263, pd0=6422248pa1=6422276, pb1=6422272, pc1=6422265, pd1=6422264pa2=6422272, pb2=6422268, pc2=6422264, pd2=6422256解析:
举例说明pa0→pa1→pa2的过程,其他类似 。pa0+2*sizeof(int)=pa1,pa1-1*sizeof(int)=pa2 。因为pa为int类型的指针,所以加减运算是以4字节(即sizeof(int))为单位地址向前向后偏移的 。看下图:

C语言指针经典知识汇总

文章插图
 
如图:pa1所指向的地址在pa0所指向地址往后8字节处,pa2指向地址在pa1指向地址往前4字节处 。
从本示例程序中,还可以看出:连续定义的变量在内存的存储有可能是紧挨着的,有可能是分散着的 。
 
数组和指针的联系数组与指针有很密切的联系,常见的结合情况有以下三种:
  • 数组指针
  • 指针数组
  • 二维数组指针
1、数组指针
数组指针:指向数组的指针 。如:
int arr[] = {0,1,2,3,4};int *p = arr; //也可写作int *p=&arr[0]也就是说,p,arr,&arr[0]都是指向数组的开头,即第0个元素的地址 。
如果一个指针p指向一个数组arr[]的开头,那么p+i为数组第i个元素的地址,即&arr[i],那么*(p+i)为数组第i个元素的值,即arr[i] 。
同理,若指针p指向数组的第n个元素,那么p+i为第n+1个元素的地址;不管 p 指向了数组的第几个元素,p+1 总是指向下一个元素,p-1 也总是指向上一个元素 。
下面示例证实了这一点:
#include <stdio.h>int main(void){int arr[] = {0, 1, 2, 3, 4};int *p = &arr[3];//也可以写作 int *p = arr + 3;printf("%d, %d, %d, %d, %dn",*(p-3), *(p-2), *(p-1), *(p), *(p+1) );return 0;}【C语言指针经典知识汇总】运行结果为:
0, 1, 2, 3, 4 
2、指针数组
指针数组:数组中每个元素都是指针 。如:
int a=1,b=2,c=3;int *arr[3] = {&a,&b,&c};示例程序:
#include <stdio.h>int main(void){int a = 1, b = 2, c = 3;//定义一个指针数组int *arr[3] = {&a, &b, &c};//也可以不指定长度,直接写作 int *parr[]//定义一个指向指针数组的指针int **parr = arr;printf("%d, %d, %dn", *arr[0], *arr[1], *arr[2]);printf("%d, %d, %dn", **(parr+0), **(parr+1), **(parr+2));return 0;}


推荐阅读