本文从一个新的视角看指针,希望能给读者耳目一新的感觉。
直奔主题,我认为指针有两个主要的属性:一是指针的值,二是指针的型。
指针的值就是指针所指的变量的首地址,指针的型就是指针所指变量的类型。本文就围绕着指针的值和型展开。
指针的值是可以改变的。但如果不想让指针的值更改可以声明为常量指针。例如char * const p=“greeting”,P的值就是字符串“greeting”的首地址,永远不能在改变。
那指针的型能不能改变呢?先看一个有意思的小程序。
#include<stdio.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start,int len)
{
int i;
for(i=0;i<len;i++)
printf("%2x",start[i]);
printf("\n");
}
void show_int(int x)
{
show_bytes((byte_pointer) &x,sizeof(int));
}
int main(){
int i=0x12345678;
show_int(i);
}
这个程序可以打印出组成int类型的每一个字节。通过这个程序还可以判断你的操作系统使用的是大端格式还是小端格式。我的电脑输出为78563412所以是小端格式。该程序的主要技巧是把int类型的指针强制转变为unsigned char类型的指针,从而可以操作每一个字节。所以指针的类型也是可以改变的,而且非常的有用。
还有一种经常碰到的需要改变指针类型的情况。假如你定义了一个链表,该链表可以存储各种类型的值,这样的链表更有用,你该怎么办。我们就要用到void类型的指针,void类型的指针可以接收任意类型的指针,然后在转换为该类型。
通过指针的值我们可以找到变量,那指针的型有什么作用呢。我认为主要有两点:一是通过指针的型可以判断该指针可以执行哪些操作,例如char类型的指针可以执行++操作而函数指针却不能,因为这样做没有任何意义。二是通过指针的型可以得到指针所指变量的大小(这里有两个例外一是字符串指针,其实就没有所谓的字符串指针只有char*指针,但是它可以指向字符串。Char*指针得到的是char类型的大小,字符串的大小要靠伟大的'/0'来得到。二是函数指针,以前我一直有一个疑惑,函数指针只指出了函数的大小,但函数执行到什么时候结束呢?其实这很简单每一个函数都有return语句,当碰到return也就结束了。所以函数指针也得不到所指函数的大小)。
以上我们分析了指针的值和型。下面分析一下指针的++操作,对指针执行++操作就是指向数据的下一个元素。什么叫指向数据的下一个元素呢。举一个例子,对char类型的指针执行++操作就是移动一个字节,对int类型的指针执行++操作就是就是移动四个字节。对int(*matrix)[10]类型的指针指针执行++操作也就是移动四十个字节。(未完待续)