不要伤害指针(7)--指针类型转换

当我们初始化一个指针或给一个指针赋值时,赋值号的左边是一个指针,赋值号的右边是一个指针表达式。在我们前面所举的例子中,绝大多数情况下,指针的类型和指针表达式的类型是一样的,指针所指向的类型和指针表达式所指向的类型是一样的。

例十五:

float f = 12.3;
float *fptr = &f;
int *p;

在上面的例子中,假如我们想让指针p 指向实数f,应该怎么办?是用下面的语句吗?

p = &f;

不对。因为指针p 的类型是int *,它指向的类型是int。表达式&f 的结果是一个指针,指针的类型是float *,它指向的类型是float。两者不一致,直接赋值的方法是不行的。至少在我的MSVC++6.0 上,对指针的赋值语句要求赋值号两边的类型一致,所指向的类型也一致,其它的编译器上我没试过,大家可以试试。为了实现我们的目的,需要进行"强制类型转换":

p = (int*)&f;

如果有一个指针p,我们需要把它的类型和所指向的类型改为TYEP *TYPE, 那么语法格式是: (TYPE *)p;

这样强制类型转换的结果是一个新指针,该新指针的类型是TYPE *,它指向的类型是TYPE,它指向的地址就是原指针指向的地址。而原来的指针p 的一切属性都没有被修改。(切记)

一个函数如果使用了指针作为形参,那么在函数调用语句的实参和形参的结合过程中,必须保证类型一致,否则需要强制转换

例十六:

void fun(char*);
int a = 125,b;
fun((char*)&a);
void fun(char* s)
{
    char c;
    c=*(s+3);*(s+3)=*(s+0);*(s+0)=c;
    c=*(s+2);*(s+2)=*(s+1);*(s+1)=c;
}

注意这是一个32 位程序,故int 类型占了四个字节,char 类型占一个字节。函数fun 的作用是把一个整数的四个字节的顺序来个颠倒。注意到了吗?在函数调用语句中,实参&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 = N //N 必须代表一个合法的地址;
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。

现在我们已经知道了,可以把指针的值当作一个整数取出来,也可以把一个整数值当作地址赋给一个指针。

时间: 2024-07-30 05:55:50

不要伤害指针(7)--指针类型转换的相关文章

常量指针,指针常量,C++类型转换[转]

一.const应用 1.const关键字,他后面内容的不可修改,一般来说,其修饰的变量不可再进行赋值操作: 2.常量指针 int a = 3: int b = 4: const int* pt = &a: a = 5: *pt的值为5,pt只是一个指针,所以他指向的是a的内容,const限制的是*pt,所以,只是不能通过*pt修改其指向的内存内容. 3.指针常量:int* const a = pt;由于不可再进行赋值操作,所以指针常量在声明时必须赋值: 相关文章: 一.常指针与指针常量的区别?

【转】让你不再害怕指针——C指针详解(经典,非常详细)

前言:复杂类型说明 要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一个类型里会出现很多运算符,他们也像普通的表达式一样,有优先级,其优先级和运算优先级一样,所以我总结了一下其原则:从变量名处起,根据运算符优先级结合,一步一步分析.下面让我们先从简单的类型开始慢慢分析吧: [cpp] view plain copy int p; //这是一个普通的整型变量 int *p; //首先从P 处开始,先与*结合,所以说明P 是一个指针,

指针与指针的引用

C++之研究--指针和引用 VB中的函数或过程的參数有2种传递方式:一种是值传递:一种是引用传递.分别用keywordByVal和keywordByRef指出.假设參数是以引用传递的话,函数或过程内部就能够靠这个引用參数来改变外部变量的值.在C语言中,假设要实如今函数内部改变外部变量的值的话,就应该传递这个变量的指针.假设要通过指针訪问变量,必须使用指针运算符"*".这样在源码中就会显得比較别扭: void function(int *pval){*pval=100;//pval=10

(转)数组指针和指针数组的区别

数组指针(也称行指针)定义 int (*p)[n];()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长.也就是说执行p+1时,p要跨过n个整型数据的长度. 如要将二维数组赋给一指针,应这样赋值:int a[3][4];int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组. p=a;        //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0] p++;       //该语句执行过后,也就是p=p+

数组指针和指针数组的区别(转)

数组指针(也称行指针)定义 int (*p)[n];()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长.也就是说执行p+1时,p要跨过n个整型数据的长度. 如要将二维数组赋给一指针,应这样赋值:int a[3][4];int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组. p=a;        //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0] p++;       //该语句执行过后,也就是p=p+

指针数组,数组指针,指针函数,函数指针,二级指针详解

先看个简单的:char *p,这定义了一个指针,指针指向的数据类型是字符型,char  *(p)定义了一个指针P: char *p[4], 为指针数组,由于[]的优先级高于*,所以p先和[]结合,p[]是一个数组,暂时把p[]看成是q,也就是char *(q),定义了一个指针q,只不过q是一个数组罢了,故定义了一个数组,数组里面的数据是char *的,所以数组里面的数据为指针类型.所以char *p[4]是四个指针,这四个指针组成了一个数组,称为指针数组,既有多个指针组成的数组. char(*p

C++智能指针--auto_ptr指针

auto_ptr是C++标准库提供的类模板,头文件<memory>,auto_ptr对象通过初始化指向由new创建的动态内存,它是这块内存的拥有者,一块内存不能同时被分给两个拥有者.当auto_ptr对象生命周期结束时,其析构函数会将auto_ptr对象拥有的动态内存自动释放.即使发生异常,通过异常的栈展开过程也能将动态内存释放.auto_ptr不支持new数组. auto_ptr的出现,主要是为了解决"有异常抛出时发生内存泄漏"的问题.如下的简单代码是这类问题的一个简单示

让你不再害怕指针——C指针详解(经典,非常详细)

http://blog.csdn.net/soonfly/article/details/51131141 前言:复杂类型说明 要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一个类型里会出现很多运算符,他们也像普通的表达式一样,有优先级,其优先级和运算优先级一样,所以我总结了一下其原则:从变量名处起,根据运算符优先级结合,一步一步分析.下面让我们先从简单的类型开始慢慢分析吧: [cpp] view plain copy int 

理解常量指针与指针常量?

constant *前面的是对被指向对象的修饰,*后面的是对指针本身的修饰 常量指针(被指向的对象是常量) 定义: 又叫常指针,可以理解为常量的指针,指向的是个常量 关键点: 常量指针指向的对象不能通过这个指针来修改,可是仍然可以通过原来的声明修改: 常量指针可以被赋值为变量的地址,之所以叫常量指针,是限制了通过这个指针修改变量的值: 指针还可以指向别处,因为指针本身只是个变量,可以指向任意地址: 代码形式: int const* p; const int* p; // // Created b

详解 常量指针和指针常量

说一下 常量指针和指针常量 的区别. 常量指针 指向常量的指针,也就是说指针指向的对象是常量,指向的常量不能修改.指针不是一个常量, 可以把指针指向别一个常量. 常量指针是我们最常用的,一般声明形式如下: const int *p; int const *p; 例: int a(1), b(3); const int *p; // 或者是 int const *p; p = &a; std::cout << "address : " << p <&