c语言函数指针的指针 c语言函数指针的指针是什么( 六 )


吗?在函数调用语句中,实?amp;a的结果是一个指针,它的类型是int *,它指向的类型是int 。形参这个指针的类型是char*,它指向的类型是
char 。这样,在实参和形参的结合过程中,我们必须进行一次从int*类型到char*类型的转换 。结合这个例子 , 我们可以这样来想象编译器进行
转换的过程:编译器先构造一个临时指针 char*temp,然后执行temp=(char*)a,最后再把temp的值传递给s 。所以最后的结果是:s的类型是
char*,它指向的类型是char,它指向的地址就是a的首地址 。
我们已经知道,指针的值就是指针指向的地址 , 在32位程序中 , 指针的值其实是一个32位整数 。那可不可以把一个整数当作指针的值直接赋给
指针呢?就象下面的语句:
unsigned int a;
TYPE *ptr;//TYPE是int,char或结构类型等等类型 。
...
...
a=20345686;
ptr=20345686;//我们的目的是要使指针ptr指向地址20345686(十进制)
ptr=a;//我们的目的是要使指针ptr指向地址20345686(十进制)
编译一下吧 。结果发现后面两条语句全是错的 。那么我们的目的就不能达到了吗?不,还有办法:
unsigned int a;
TYPE *ptr;//TYPE是int,char或结构类型等等类型 。
...
...
a=某个数,这个数必须代表一个合法的地址;
ptr=(TYPE*)a;//呵呵,这就可以了 。
严格说来这里的(TYPE*)和指针类型转换中的(TYPE*)还不一样 。这里的(TYPE*)的意思是把无符号整数a的值当作一个地址来看待 。
上面强调了a的值必须代表一个合法的地址,否则的话,在你使用ptr的时候,就会出现非法操作错误 。
想想能不能反过来,把指针指向的地址即指针的值当作一个整数取出来 。完全可以 。下面的例子演示了把一个指针的值当作一个整数取出来,
然后再把这个整数当作一个地址赋给一个指针:
例十六:
int a=123,b;
int *ptr=a;
char *str;
b=(int)ptr;//把指针ptr的值当作一个整数取出来 。
str=(char*)b;//把这个整数的值当作一个地址赋给指针str 。
好了 , 现在我们已经知道了,可以把指针的值当作一个整数取出来 , 也可以把一个整数值当作地址赋给一个指针 。
第九章 。指针的安全问题
看下面的例子:
例十七:
char s='a';
int *ptr;
ptr=(int*)s;
*ptr=1298;
指针ptr是一个int*类型的指针,它指向的类型是int 。它指向的地址就是s的首地址 。在32位程序中,s占一个字节,int类型占四个字节 。最后
一条语句不但改变了s所占的一个字节,还把和s相临的高地址方向的三个字节也改变了 。这三个字节是干什么的?只有编译程序知道,而写程
序的人是不太可能知道的 。也许这三个字节里存储了非常重要的数据 , 也许这三个字节里正好是程序的一条代码,而由于你对指针的马虎应用
 , 这三个字节的值被改变了!这会造成崩溃性的错误 。让我们再来看一例:
例十八:
1 。char a;
2 。int *ptr=a;
...
...
3 。ptr++;
4 。*ptr=115;
该例子完全可以通过编译,并能执行 。但是看到没有?第3句对指针ptr进行自加1运算后,ptr指向了和整形变量a相邻的高地址方向的一块存储
区 。这块存储区里是什么?我们不知道 。有可能它是一个非常重要的数据,甚至可能是一条代码 。而第4句竟然往这片存储区里写入一个数据!
这是严重的错误 。所以在使用指针时,程序员心里必须非常清楚:我的指针究竟指向了哪里 。

推荐阅读